是否可以在Serilog.Exceptions中禁用基于反射的解构器?

时间:2019-11-26 15:51:42

标签: c# exception logging serilog serilog-exceptions

软件包Serilog.Exceptions非常适合记录异常。它有大量受支持的异常类型列表。

例如当前设置:

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

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

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

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

不幸的是,这些选项不起作用:

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

是否知道如何配置Serilog.Exceptions?

2 个答案:

答案 0 :(得分:2)

我认为您最好的选择是实现自己的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类型的众所周知的属性。

答案 1 :(得分:2)

此内容已添加到Serilog。异常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();