【问题标题】:Unit test serilog configuration单元测试 serilog 配置
【发布时间】:2018-09-28 11:44:54
【问题描述】:

我有一段代码用于根据一些自定义配置与托管环境相结合来设置 serilog。例如。应用程序写入开发中的一个接收器和生产中的另一个接收器。

我正试图弄清楚如何为这段代码编写测试。基本上,我想编写一个测试,检查仅在环境名称设置为给定值时才添加接收器,并且接收器配置(如日志文件路径)尊重我提供的自定义配置。

但我没有任何运气找到任何方法输出 LoggingConfiguration...

有人知道这是否可能吗?

【问题讨论】:

    标签: .net .net-core serilog


    【解决方案1】:

    不幸的是,Serilog 没有公开已配置的接收器列表,因此您目前唯一的选择是使用反射。

    如果您查看Serilog's source code,您会看到it groups all configured sinks 成为内部类SafeAggregateSink 的实例,该类负责将日志发送到不同的接收器设置,并保存一个包含所有已配置接收器的数组在名为 _sinks 的私有字段中。

    这是一个简单的例子:

    var log = new LoggerConfiguration()
        .WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Verbose)
        .WriteTo.File(path: "log.txt", restrictedToMinimumLevel: LogEventLevel.Verbose)
        .CreateLogger();
    
    var aggregateSinkFieldInfo = log.GetType()
        .GetField("_sink", BindingFlags.Instance | BindingFlags.NonPublic);
    
    var aggregateSink = (ILogEventSink)aggregateSinkFieldInfo?.GetValue(log);
    
    var sinkEnumerableFieldInfo = aggregateSink?.GetType()
        .GetField("_sinks", BindingFlags.Instance | BindingFlags.NonPublic);
    
    var sinks = (ILogEventSink[])sinkEnumerableFieldInfo?
        .GetValue(aggregateSink);
    
    if (sinks != null)
    {
        foreach (var sink in sinks)
        {
            Console.WriteLine(sink.GetType().FullName);
        }
    }
    

    这应该输出:

    Serilog.Sinks.SystemConsole.ConsoleSink
    Serilog.Sinks.File.FileSink
    

    注意:请记住,Serilog 在某些情况下会包裹水槽,因此您可能需要处理这个问题,然后才能找到所需的水槽。例如,如果您限制接收器的最低级别,您的接收器将被包裹到RestrictedSink,因此您必须获取其_sink 字段才能获得您正在寻找的“真实”接收器为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-08
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-13
      • 2019-01-20
      相关资源
      最近更新 更多