如何将磁盘上的 Serilog 文件接收器写入的数据推送到另一个 Serilog 接收器?
How can I push data written by a Serilog File Sink on the disk to another Serilog sink?
我们正在尝试对 logstash/elastic 的基础架构进行负载测试。由于实际日志是由使用硬件的软件生成的,我们无法大规模模拟它。
我想知道我们是否可以使用文件接收器存储日志,然后编写一个程序来读取日志文件并通过实际接收器发送数据。因为,我们正在尝试不同的设置,所以如果我们可以交换不同的接收器进行测试,那就太好了。说一下http sink和elastic sink。
我想一次读取 json 文件一行,然后在 Logger
上调用 Write 方法。但是我不确定如何从 json 获取属性数组。另外,很高兴听到 Serilog 世界中是否有更好的替代品来满足我的需求。
示例解析
var events= File.ReadAllLines(@"C:210520.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}}
更新
虽然这适用于简单的事件,
- 它无法处理上下文属性(虽然使用 ForContext 可以解决),
- 它还强制所有属性为字符串类型并且
- 更不用说解构 (@属性) 处理不当
如果你能把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);
我们正在尝试对 logstash/elastic 的基础架构进行负载测试。由于实际日志是由使用硬件的软件生成的,我们无法大规模模拟它。
我想知道我们是否可以使用文件接收器存储日志,然后编写一个程序来读取日志文件并通过实际接收器发送数据。因为,我们正在尝试不同的设置,所以如果我们可以交换不同的接收器进行测试,那就太好了。说一下http sink和elastic sink。
我想一次读取 json 文件一行,然后在 Logger
上调用 Write 方法。但是我不确定如何从 json 获取属性数组。另外,很高兴听到 Serilog 世界中是否有更好的替代品来满足我的需求。
示例解析
var events= File.ReadAllLines(@"C:210520.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}}
更新 虽然这适用于简单的事件,
- 它无法处理上下文属性(虽然使用 ForContext 可以解决),
- 它还强制所有属性为字符串类型并且
- 更不用说解构 (@属性) 处理不当
如果你能把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);