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

查看:45
本文介绍了单元测试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

N.B .:请记住,在某些情况下,Serilog会包装接收器,因此在找到所需的接收器之前,您可能需要处理该接收器.例如,如果您限制接收器的最低级别,则接收器将被包装为

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天全站免登陆