Unit test serilog configuration

烈酒焚心 提交于 2021-02-16 18:07:57

问题


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.

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

Anyone knows if this is possible?


回答1:


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.

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.

Here is a simple example:

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);
    }
}

This should output:

Serilog.Sinks.SystemConsole.ConsoleSink
Serilog.Sinks.File.FileSink

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.



来源:https://stackoverflow.com/questions/52554649/unit-test-serilog-configuration

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!