4

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

例如当前设置:

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

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

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

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

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

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

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

4

2 回答 2

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 类型的众所周知的属性。

于 2020-01-25T19:18:32.183 回答
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();
于 2020-02-04T14:08:05.013 回答