单元测试蚯间日志配置



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

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

但是我没有运气找到任何从LoggingConfiguration中获得价值的方法......

有人知道这是否可能吗?

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

如果您浏览 Serilog 的源代码,您会发现它将所有已配置的接收器分组到内部类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字段才能获得您正在寻找的"真实"水槽。

最新更新