自定义Serilog JSON日志输出:移除冗余字段并重命名特殊字段
在ASP.NET中配置Serilog实现自定义字段与重命名特殊字段
解决SensorInput重复出现在消息字段的问题
当前你使用{@SensorInput}作为消息模板的一部分,Serilog会自动将对象的字符串表示渲染到@m(消息)字段中,同时生成结构化的SensorInput字段。要仅保留SensorInput字段、避免其内容在消息中重复,只需将结构化数据作为额外属性传递,而非嵌入消息模板:
调整日志调用代码
var sensorInput = new { Latitude = 25, Longitude = 134 }; // 方式1:通过ForContext添加结构化属性 _logger.ForContext("SensorInput", sensorInput, destructureObjects: true) .LogInformation("传感器数据已接收"); // 方式2:通过匿名对象传递属性(消息模板中不包含{@SensorInput}) _logger.LogInformation("传感器数据已接收", new { SensorInput = sensorInput });
调整后,消息字段会显示固定文本,SensorInput字段保留完整结构化数据,不会在消息中重复出现。
重命名@t、@m等特殊字段
Serilog支持通过自定义格式化器实现特殊字段的重命名,以下提供两种方案:
方案1:使用JsonFormatter自定义字段映射
直接使用JsonFormatter并配置属性名称映射,替代默认的RenderedCompactJsonFormatter:
builder.Host.UseSerilog((context, loggerConfiguration) => { var propertyNameMap = new Dictionary<string, string> { { "@t", "timestamp" }, { "@m", "message" }, { "@l", "level" } // 可选:同时重命名日志级别字段 }; loggerConfiguration .Enrich.FromLogContext() .WriteTo.Console(new JsonFormatter( jsonWriterOptions: new JsonWriterOptions { Indented = false }, // 保持紧凑格式 propertyNameMap: propertyNameMap ), standardErrorFromLevel: LogEventLevel.Information); });
方案2:自定义Compact格式格式化器
如果希望保留RenderedCompactJsonFormatter的紧凑格式,可继承并重写属性名称逻辑:
public class CustomCompactJsonFormatter : RenderedCompactJsonFormatter { protected override void WriteEventPropertyName(TextWriter output, string name) { var mappedName = name switch { "@t" => "timestamp", "@m" => "message", "@l" => "level", _ => name }; output.Write('"'); output.Write(mappedName); output.Write('"'); } }
然后在配置中使用自定义格式化器:
builder.Host.UseSerilog((context, loggerConfiguration) => { loggerConfiguration .Enrich.FromLogContext() .WriteTo.Console(new CustomCompactJsonFormatter(), standardErrorFromLevel: LogEventLevel.Information); });
最终效果示例
调整后的日志输出会类似:
{"timestamp":"2024-05-20T12:34:56.789Z","message":"传感器数据已接收","level":"Information","SensorInput":{"Latitude":25,"Longitude":134}}
内容的提问来源于stack exchange,提问作者beseus
相关产品推荐
相关产品推荐

