Конфигурация Serilog модульного тестирования - PullRequest
0 голосов
/ 28 сентября 2018

У меня есть кусок кода для настройки serilog, основанный на некоторой пользовательской конфигурации в сочетании с хостинговой средой.Например, приложение пишет в один приемник в процессе разработки и другой приемник в процессе производства.

Я пытаюсь выяснить, как писать тесты для этого фрагмента кода.По сути, я хочу написать тест, который проверяет, добавляется ли приемник только в том случае, если для имени среды задано заданное значение и что конфигурация приемника, например путь к файлу журнала, учитывает предоставленную мной пользовательскую конфигурацию.

Но мне не повезло найти какой-либо способ получения значений из из LoggingConfiguration ...

Кто-нибудь знает, возможно ли это?

1 Ответ

0 голосов
/ 09 октября 2018

К сожалению, Serilog не раскрывает список настроенных раковин, поэтому на данный момент единственным вариантом будет использование Reflection.

Если вы возьметесь за Исходный код 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

NB: Сохранить впомните, что в некоторых случаях Serilog оборачивает раковины, поэтому вам, возможно, придется с этим справиться, прежде чем вы сможете найти раковину, которую ищете.Например, если вы ограничите минимальный уровень приемника, ваш приемник будет обернут в RestrictedSink, поэтому вам нужно взять его поле _sink, чтобы получить «реальный»"раковина, которую вы ищете.

...