Veg*_*gar 5 .net serilog .net-core
我有一段代码用于根据一些自定义配置与托管环境相结合来设置 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);
}
}
Run Code Online (Sandbox Code Playgroud)
这应该输出:
Serilog.Sinks.SystemConsole.ConsoleSink
Serilog.Sinks.File.FileSink
Run Code Online (Sandbox Code Playgroud)
注意:请记住,在某些情况下,Serilog 会包装接收器,因此您可能需要先处理这个问题,然后才能找到所需的接收器。例如,如果您限制接收器的最低级别,您的接收器将被包裹到一个 中RestrictedSink,因此您必须掌握它的_sink字段才能获得您正在寻找的“真实”接收器。
| 归档时间: |
|
| 查看次数: |
1773 次 |
| 最近记录: |