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

26

我有这个结构:

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" (类名) 出现在开头。 "Request" (属性名) 出现了两次。如何记录有效的 JSON?


我推荐使用Newtonsoft的Json.NET - ThePerplexedOne
2
使用Json.NET,您可以通过使用var json = JsonConvert.Serialize(logRequestParameters);序列化任何对象实例。 - ThePerplexedOne
1
@ThePerplexedOne:你不能用序列化框架替换日志框架,如果我没记错的话,Serilog 无论如何都依赖于 Json.NET。 - Martin Liversage
2
Serilog是一个支持结构化错误日志记录的日志框架。该结构如何持久化取决于所使用的特定Sink。您能展示一下您如何初始化Serilog吗?这将有助于了解您正在使用哪个sink。 - PatrickSteele
3
不,Serilog并不使用JSON.NET(它完全没有任何依赖项,除了基础的.NET Framework/Core包:-) - Nicholas Blumhardt
显示剩余4条评论
2个回答

14
假设您正在使用文件、滚动文件或控制台记录器,您需要指定一个 JsonFormatter
Log.Logger = new LoggerConfiguration()
    .WriteTo.RollingFile(new JsonFormatter(), "myapp-{Date}.json")
    .CreateLogger();

Serilog 支持多种不同的 JSON 格式;有关一些替代方案的讨论,请参见此文章

1
我正在使用Serilog 1.5.14,但是无法编写上述代码。 - user1780538
在1.5版本中,使用WriteTo.Sink(new RollingFileSink("myapp-{Date}.json", new JsonFormatter(), 1024L * 1024 * 1024, 31, null, false)。如果可以的话,升级到2.x是值得的 :-) - Nicholas Blumhardt
那些不支持传递格式化程序的下沉功能(例如Seq)怎么办? - Nico

8

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

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

根据文档

Message - 日志事件的消息,以纯文本形式呈现。 :l 格式说明符可关闭字符串引号,:j 可将任何嵌入的结构化数据使用 JSON 样式渲染。

在带有 JSON 示例的前端文档页面中没有提及此功能,所以我花了很多时间来解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接