如何将 Serilog 丰富器与日志上下文结合使用

nul*_*ter 7 c# serilog

Serilog 丰富者(尤其LogEvent是)是否期望了解被推入的属性LogContext

我有一个被推送到 Serilog 上下文的属性:

using (LogContext.PushProperty(LoggingConstants.MyProperty, _myValue))
{
   // ...
}
Run Code Online (Sandbox Code Playgroud)

我还注册了一个自定义丰富器,如果属性不存在,它会添加一个属性,并将其填充到指定的长度:

public class PaddedPropertyEnricher : ILogEventEnricher
{
    private readonly string _propertyName;
    private readonly int _maxLength;

    public PaddedPropertyEnricher(string propertyName, int maxLength)
    {
      _propertyName = propertyName;
      _maxLength = maxLength;
    }

    public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
    {
      var property = propertyFactory.CreateProperty(_propertyName, new string(' ', _maxLength));
      logEvent.AddPropertyIfAbsent(property);
    }
}
Run Code Online (Sandbox Code Playgroud)

和:

Log.Logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .Enrich.With(new PaddedPropertyEnricher(LoggingConstants.MyProperty, 3))
                 // etc.
Run Code Online (Sandbox Code Playgroud)

此丰富器的目的是使不包含自定义属性的日志条目不会导致日志条目中的列未对齐。

例如,它的目的是改变这个:

2021-06-10 12:23:33.676 +12:00 [INF] [] First message without MyProperty
2021-06-10 12:23:33.677 +12:00 [DBG] [123] Second message with MyProperty
Run Code Online (Sandbox Code Playgroud)

进入这个:

2021-06-10 12:23:33.676 +12:00 [INF] [   ] First message without MyProperty
2021-06-10 12:23:33.677 +12:00 [DBG] [123] Second message with MyProperty
Run Code Online (Sandbox Code Playgroud)

然而,这个浓缩器不起作用。当针对我要推送到上下文的属性注册丰富器时,从中检索的值LogEvent始终是null- 除非MyProperty在日志消息本身中明确显示。

这是一个已知的限制,还是我滥用了丰富器?

这可能与始终使用 serilog 记录上下文数据中遇到的问题有关。

nul*_*ter 8

该问题是由于我的自定义丰富器之前已注册造成的Enrich.FromLogContext();例如:

// Bad configuration
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .Enrich.With(new PaddedPropertyEnricher(LoggingConstants.MyProperty, 3))
    .WriteTo.Console(minimumLogLevels.Console, LogFormat)

     // Other sink configuration here

    .Enrich.FromLogContext()
    .CreateLogger();
Run Code Online (Sandbox Code Playgroud)

Enrich.FromLogContext()通过确保发生在依赖它的任何丰富器之前解决了该问题;IE:

// Good configuration
Log.Logger = new LoggerConfiguration()
    .MinimumLevel.Debug()
    .WriteTo.Console(minimumLogLevels.Console, LogFormat)

     // Other sink configuration here

    .Enrich.FromLogContext()
    .Enrich.With(new PaddedPropertyEnricher(LoggingConstants.MyProperty, 3))
    .CreateLogger();
Run Code Online (Sandbox Code Playgroud)

感谢奥利维尔·罗杰(Olivier Roger)促使我查看我的完整Log.Logger链条。