单元测试Serilog配置

9
我有一段代码,用于根据一些自定义配置和托管环境设置Serilog。例如,应用程序在开发中写入一个汇聚器,在生产中写入另一个汇聚器。
我正在尝试弄清楚如何为这段代码编写测试。基本上,我想编写一个测试,检查仅当环境名称设置为特定值时才添加汇聚器,并且像日志文件路径这样的汇聚器配置遵守我提供的自定义配置。
但是我没有找到任何从LoggingConfiguration中获取值的方法...
有人知道是否可能吗?
1个回答

7

很遗憾,Serilog没有公开已配置的Sinks列表,因此您目前唯一的选择是使用反射。

如果您查看Serilog的源代码,您会发现它将所有已配置的sinks分组到一个内部类SafeAggregateSink实例中,该实例负责将日志发送到设置的不同sinks,并在名为_sinks的私有字段中保存所有已配置的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字段以获取您要查找的“真实”接收器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接