serilog - 如何将磁盘上的 Serilog 文件接收器写入的数据推送到另一个 Serilog 接收器?
问题描述
我们正在尝试对我们的 logstash/elastic 基础设施进行负载测试。由于实际日志是由使用硬件的软件生成的,因此我们无法大规模模拟它。
我想知道我们是否可以使用文件接收器存储日志,然后编写一个程序来读取日志文件并通过实际接收器发送数据。因为,我们正在尝试不同的设置,如果我们可以交换不同的接收器进行测试,那就太好了。说 http sink 和 elastic sink。
我想一次读取json 文件一行,然后在Logger
. 但是我不确定如何从 json 中获取属性数组。此外,很高兴听到 Serilog 世界中是否有更好的选择来满足我的需求。
示例解析
var events= File.ReadAllLines(@"C:\20210520.json")
.Select(line => JsonConvert.DeserializeObject<dynamic>(line));
foreach (var o in objects)
{
DateTime timeStamp = o.Timestamp;
LogEventLevel level = o.Level;
string messageTemplate = o.MessageTemplate;
string exception = o.Exception;
var properties = (o.Properties as JObject);
List<object> parameters = new List<object>();
foreach (var property in properties)
{
if(messageTemplate.Contains(property.Key))
parameters.Add(property.Value.ToString());
}
logInstance.Write(level, messageTemplate, parameters.ToArray());
count++;
}
写入文件的示例 Json 事件
{"Timestamp":"2021-05-20T13:15:49.5565372+10:00","Level":"Information","MessageTemplate":"Text dialog with {Title} and {Message} displayed, user selected {Selected}","Properties":{"Title":"Unload Device from Test","Message":"Please unload the tested device from test jig","Selected":"Methods.Option","SinkRepository":null,"SourceRepository":null,"TX":"TX2937-002 ","Host":"Host1","Session":"Host1-2021.05.20 13.12.44","Seq":87321,"ThreadId":3}}
更新 虽然这适用于简单的事件,
- 它无法处理 Context 属性(虽然使用 ForContext 有一个变通方法),
- 它还强制所有属性为字符串类型,并且
- 更不用说解构(@property)没有正确处理
解决方案
如果您可以将 JSON 格式更改为Serilog.Formatting.Compact的 CLEF 格式,那么您可以为此使用Serilog.Formatting.Compact.Reader。
在源应用程序中:
// dotnet add package Serilog.Formatting.Compact
Log.Logger = new LoggerConfiguration()
.WriteTo.File(new CompactJsonFormatter(), "./logs/myapp.clef")
.CreateLogger();
在负载测试器中:
// dotnet add package Serilog.Formatting.Compact.Reader
using (var target = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Console()
.CreateLogger())
{
using (var file = File.OpenText("./logs/myapp.clef"))
{
var reader = new LogEventReader(file);
while (reader.TryRead(out var evt))
target.Write(evt);
}
}
请注意,如果您使用重复的时间戳,许多接收器的负载测试结果将不准确。您应该考虑重新映射您读入的事件以使用当前时间戳。
例如,一旦你加载了evt
:
var current = new LogEvent(DateTimeOffset.Now,
evt.Level,
evt.Exception,
evt.MessageTemplate,
evt.Properties);
target.Write(current);
推荐阅读
- php - 如何在保留兄弟键值对的同时基于键值与数组相交
- python - 检查一个数组中的元素是否存在于另一个数组中?
- python - 如何从第二项迭代python dict
- java - 通过实现 onSeekBarChangeListener 在 TextView 中的多个搜索栏值
- angular - 错误 ReferenceError:particleJS 未定义 ~ Angular Universal + Webpack
- c# - ExpectedObjects 比较具体对象而不仅仅是接口
- python-3.x - RuntimeError:后端 CPU 的预期对象,但为参数 #2 'weight' 获得了后端 CUDA
- python-3.x - 尝试下载自制软件
- facebook - Firebase Facebook 身份验证:格式错误或过期的身份验证凭据
- php - 无法从会话设置电子邮件变量,因此 mail() 函数正常工作