【问题标题】:Is it possible to disabled the reflection based destructurer in Serilog.Exceptions?是否可以在 Serilog.Exceptions 中禁用基于反射的解构器?
【发布时间】:2020-03-22 02:14:41
【问题描述】:

Serilog.Exceptions 非常适合记录异常。它有大量支持的异常类型。

例如当前设置:

Log.Logger = new LoggerConfiguration()
    .Enrich.WithExceptionDetails()
    .CreateLogger();

目前,如果没有找到异常类型的解构器,它会退回到“基于反射的解构器”。

出于性能考虑,但更重要的是可预测性,我们希望禁用反射回退。

我尝试使用DestructuringOptions 进行配置,例如禁用一些默认析构函数或将 DestructuringDepth 设置为 0

很遗憾,这些选项不起作用:

  • ReflectionBasedDestructurer 不在默认析构函数列表中
  • 不允许将 DestructuringDepth 设置为 0(例外)

知道如何为此配置 Serilog.Exceptions 吗?

【问题讨论】:

    标签: c# exception logging serilog serilog-exceptions


    【解决方案1】:

    我认为最好的选择是实现自己的ExceptionDecostructor,如下所示:

     public class FallbackExceptionDestructurer : ExceptionDestructurer
     {
            public override Type[] TargetTypes => new[]
            {
                typeof(Exception),
            };
    
            public override void Destructure(
                Exception exception,
                IExceptionPropertiesBag propertiesBag,
                Func<Exception, IReadOnlyDictionary<string, object>> destructureException)
            {
                base.Destructure(exception, propertiesBag, destructureException);
            }
     }
    

    这样您将保留所有可用的解构器,并且基于反射的反射将被忽略,因为FallbackExceptionDestructurer 将覆盖由于此代码导致的所有未知异常:

    public override Type[] TargetTypes => new[]
    {
      typeof(Exception),
    };
    

    这就是你注册解构器的方式

    .Enrich.WithExceptionDetails(new DestructuringOptionsBuilder()
        .WithDefaultDestructurers()
        .WithDestructurers(new[] { new FallbackExceptionDestructurer () }))
    

    如果您检查 ExceptionDestructurer.Decostruct(...) 的源代码,它不会使用任何反射 - 仅使用 Exception 类型的众所周知的属性。

    【讨论】:

      【解决方案2】:

      这已添加到 Serilog.Exceptions 5.4.0,请参阅 changelog。有一个新方法WithoutReflectionBasedDestructurer

      用法

      助手类

      public static class LoggerEnrichmentConfigurationExtensions
      {
          public static LoggerConfiguration WithExceptionDetailsWithoutReflection(
              this LoggerEnrichmentConfiguration loggerEnrichmentConfiguration)
          {
              if (loggerEnrichmentConfiguration is null)
              {
                  throw new ArgumentNullException(nameof(loggerEnrichmentConfiguration));
              }
              var options = new DestructuringOptionsBuilder()
                  .WithDefaultDestructurers()
                  .WithoutReflectionBasedDestructurer() //new in 5.4.0!
                  .WithIgnoreStackTraceAndTargetSiteExceptionFilter();
              var logEventEnricher = new ExceptionEnricher(options);
              return loggerEnrichmentConfiguration.With(logEventEnricher);
          }
      }
      

      配置

      Log.Logger = new LoggerConfiguration()
                      .ReadFrom.Configuration(configuration)
                      .Enrich.WithExceptionDetailsWithoutReflection()
                      .CreateLogger();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-26
        相关资源
        最近更新 更多