Serilog如何将日志级别转换为syslog标准值并输出双格式级别
Serilog 适配 Azure IoT Edge 日志格式实现方案
不需要实现全量自定义文本格式化器即可满足同一日志行双格式渲染日志级别的需求,最轻量的实现方式是通过自定义Enricher补充Syslog级别属性,配合标准输出模板直接拼接格式。
级别映射规则
首先对齐Azure IoT Edge要求的Syslog严重度编码和Serilog日志级别的对应关系:
Fatal-> 2(Syslog Critical级别)Error-> 3(Syslog Error级别)Warning-> 4(Syslog Warning级别)Information-> 6(Syslog Informational级别)Debug/Verbose->7(Syslog Debug级别)
方案1:Enricher + 原生输出模板(推荐)
该方案代码量最小,性能和原生Serilog控制台输出基本一致,两个级别的渲染逻辑完全独立,后续调整格式更灵活。
- 实现一个轻量的日志Enricher,为每条日志事件补充Syslog编码属性:
using Serilog.Core; using Serilog.Events; public class SyslogSeverityEnricher : ILogEventEnricher { public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { int severityCode = logEvent.Level switch { LogEventLevel.Fatal => 2, LogEventLevel.Error => 3, LogEventLevel.Warning => 4, LogEventLevel.Information => 6, LogEventLevel.Debug => 7, LogEventLevel.Verbose => 7, _ => 7 }; logEvent.AddPropertyIfAbsent( propertyFactory.CreateProperty("SyslogSeverity", severityCode) ); } } - 配置Logger时挂载Enricher,直接在输出模板中同时引用自定义Syslog编码属性和内置的3位短级别格式符即可:
using Serilog; using Serilog.Sinks.SystemConsole.Themes; Log.Logger = new LoggerConfiguration() .Enrich.With<SyslogSeverityEnricher>() .WriteTo.Console( theme: ConsoleTheme.None, // 必须关闭颜色输出,避免ANSI转义字符污染日志 outputTemplate: "<{SyslogSeverity}> {Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] - {Message:lj}{NewLine}{Exception}" ) .CreateLogger();
该配置输出的日志行和官方要求的示例完全一致,Information级别日志输出效果:
<6> 2022-06-15 13:05:44.790 +00:00 [INF] - Received direct method call - ping
方案2:自定义ITextFormatter(适合后续有复杂格式扩展需求的场景)
如果后续需要对日志输出做更多自定义控制,可以实现自定义文本格式化器,在格式化逻辑中分别生成两种格式的级别值拼接即可,不存在“同一日志无法渲染两种级别格式”的限制:
using Serilog.Formatting; using Serilog.Events; using System.IO; public class IoTEdgeCompatibleFormatter : ITextFormatter { public void Format(LogEvent logEvent, TextWriter output) { // 计算Syslog级别编码 int syslogCode = logEvent.Level switch { LogEventLevel.Fatal => 2, LogEventLevel.Error => 3, LogEventLevel.Warning => 4, LogEventLevel.Information => 6, LogEventLevel.Debug => 7, LogEventLevel.Verbose => 7, _ => 7 }; // 计算3位短级别文本 string shortLevel = logEvent.Level switch { LogEventLevel.Fatal => "FTL", LogEventLevel.Error => "ERR", LogEventLevel.Warning => "WRN", LogEventLevel.Information => "INF", LogEventLevel.Debug => "DBG", LogEventLevel.Verbose => "VRB", _ => "???" }; // 按规则拼接日志行 output.Write($"<{syslogCode}> {logEvent.Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{shortLevel}] - "); logEvent.RenderMessage(output); output.WriteLine(); // 输出异常信息 if (logEvent.Exception != null) { output.WriteLine(logEvent.Exception.ToString()); } } }
配置时直接传入格式化器实例即可:
Log.Logger = new LoggerConfiguration() .WriteTo.Console(new IoTEdgeCompatibleFormatter()) .CreateLogger();
注意事项
- 控制台输出必须关闭颜色主题,否则ANSI颜色控制字符会被写入stdout,导致Azure IoT Edge日志检索时出现乱码、格式解析失败
- 时间戳必须保留UTC偏移量(即模板中的
zzz部分),和官方示例格式对齐,避免日志时间排序异常
内容的提问来源于stack exchange,提问作者Steve0212
相关产品推荐
相关产品推荐

