单元测试serilog配置 [英] Unit test serilog configuration

查看:29
本文介绍了单元测试serilog配置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a piece of code for setting up serilog based on some custom configuration combined with hosting environment. E.g. the application writes to one sink in development and another sink in production.

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

I'm trying to figure out how to write tests for this piece of code. Basically, I want to write a test that checks that a sink only is added if the environment name is set to a given value, and that the sink configuration, like log file path, respects the custom configuration that I provide.

但是我没有找到任何方法从 LoggingConfiguration取出的值...

But I haven't had any luck finding any way of getting values out of the LoggingConfiguration...

有人知道这是否可能吗?

Anyone knows if this is possible?

推荐答案

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

Unfortunately Serilog does not expose the list of Sinks that have been configured, so your only option at the moment would be to use Reflection.

如果你浏览 Serilog 的源代码,你会看到它将所有配置的接收器分组到一个实例中内部类 SafeAggregateSink 负责将日志发送到不同的接收器设置,并在名为 _sinks 的私有字段中保存一个包含所有配置接收器的数组.

If you poke around Serilog's source code, you'll see that it groups all configured sinks into an instance of an internal class SafeAggregateSink which is responsible emitting the logs to the different sinks setup, and holds an array with all the configured sinks in a private field called _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 字段才能获得真正的"接收器正在寻找.

N.B.: Keep in mind that Serilog wraps sinks in some cases, so you might need to handle that, before you can find the sink you're looking for. For example, if you restrict the minimum level of a sink, your sink will be wrapped into a RestrictedSink, so you'll have to get a hold of its _sink field to get the "real" sink you're looking for.

这篇关于单元测试serilog配置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆