如何使用 Serilog 以有效的 json 格式记录复杂对象?

Posted

技术标签:

【中文标题】如何使用 Serilog 以有效的 json 格式记录复杂对象?【英文标题】:How to log complex object using Serilog in valid json format? 【发布时间】:2017-02-06 13:11:40 【问题描述】:

我有这个结构:

public class LogRequestParameters

    public string RequestID  get; set; 

    public string Type  get; set; 

    public string Level  get; set; 

    public string DateTime  get; set; 

    public string MachineName  get; set; 

    public Request Request  get; set; 


public class Request

    public string URLVerb  get; set; 

我正在为日志写下一行:

Serilog.Log.Information("@LogRequestParameters", logRequestParameters);

我得到以下输出:

LogRequestParameters  RequestID: "bf14ff78-d553-4749-b2ac-0e5c333e4fce", Type: "Request", Level: "Debug", DateTime: "9/28/2016 3:12:27 PM", MachineName: "DXBKUSHAL", Request: Request  URLVerb: "GET /Violation/UnpaidViolationsSummary"  

这不是一个有效的 json。 “LogRequestParameters”(类名)即将开始。 “请求”(物业名称)来了两次。 如何记录有效的 json?

【问题讨论】:

我推荐 Newtonsoft 的 Json.NET。 使用 Json.NET,您可以使用 var json = JsonConvert.Serialize(logRequestParameters); 序列化对象的任何实例 @ThePerplexedOne:你不能用序列化框架替换日志框架,如果我没记错的话,Serilog 无论如何都依赖于 Json.NET。 Serilog 是一个支持结构化错误日志的日志框架。该结构的持久化方式取决于所使用的特定 Sink。你能展示一下你是如何初始化 Serilog 的吗?这将有助于了解您正在使用哪个接收器。 @MartinLiversage 不,Serilog 不使用 JSON.NET(它 100% 无依赖,除了基本的 .NET Framework/Core 包:-)) 【参考方案1】:

假设您使用的是文件、滚动文件或控制台接收器,您需要指定一个JsonFormatter

Log.Logger = new LoggerConfiguration()
    .WriteTo.RollingFile(new JsonFormatter(), "myapp-Date.json")
    .CreateLogger();

Serilog 支持几种不同的 JSON 格式;请参阅 this post 了解一些替代方案的讨论。

【讨论】:

我使用的是 Serilog 1.5.14,无法编写上述代码。 在 1.5 中,使用 WriteTo.Sink(new RollingFileSink("myapp-Date.json", new JsonFormatter(), 1024L * 1024 * 1024, 31, null, false)。如果可以的话,升级到 2.x 是值得的 :-) 不支持传递格式化程序的接收器怎么样,例如序列?【参考方案2】:

确保您的消息模板在末尾包含 :lj 格式说明符:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Console(outputTemplate:
        "[Timestamp:HH:mm:ss Level:u3] Message:ljNewLineException")
    .CreateLogger();

来自documentation:

Message - 日志事件的消息,呈现为纯文本。 :l 格式说明符切换字符串的引用,并且 :j 使用 JSON 样式呈现任何嵌入式结构化数据。

在带有 JSON 示例的前端文档页面上没有提及它,我也花了很多时间来解决这个问题。

【讨论】:

以上是关于如何使用 Serilog 以有效的 json 格式记录复杂对象?的主要内容,如果未能解决你的问题,请参考以下文章

使用表达式自定义Serilog输出格式

Serilog:记录到不同的文件

使用 appsettings.json 配置 Serilog RollingFile

使用appsettings.json配置Serilog RollingFile

Serilog 记录 web-api 方法,在中间件中添加上下文属性

如何修复无效的随机字符串以使其 JSON 有效