Можно ли элегантно настроить Serilog с помощью операторов if? - PullRequest
0 голосов
/ 25 октября 2018

Мой код конфигурации Serilog выглядит следующим образом:

Log.Logger = new LoggerConfiguration()
    .Enrich.WithExceptionDetails()
    .Enrich.FromLogContext()
    .MinimumLevel.Warning()
//  .MinimumLevel.Override("Microsoft", LogEventLevel.Verbose)
//  .MinimumLevel.Override("System", LogEventLevel.Verbose)
//  .MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Verbose)
    .WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate )
//  .WriteTo.File()
    .CreateLogger();

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

Boolean enableConsoleLogging = ...
Boolean enableFileLogging = ...

LoggerConfiguration builder = new LoggerConfiguration()
    .Enrich.WithExceptionDetails()
    .Enrich.FromLogContext()
    .MinimumLevel.Warning();

if( enableConsoleLogging )
{
    builder = builder
        .WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate )
}

if( enableFileLogging )
{
    builder = builder
        .WriteTo.File( ... )
}
Log.Logger = builder.CreateLogger();

... что не совсем элегантно.

Я знаю, что могу добавить свою собственную If метод расширения (но я не заинтересован в расширении существующего дизайна API, даже если он выглядит красивее):

Log.Logger = new LoggerConfiguration()
    .Enrich.WithExceptionDetails()
    .Enrich.FromLogContext()
    .MinimumLevel.Warning()
    .If( enableConsoleLogging, b => b.WriteTo.Console( outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}", theme: AnsiConsoleTheme.Literate ) )
    .If( enableFileLogging, b => b.WriteTo.File( ... ) )
    .CreateLogger();


public static LoggerConfiguration If( this LoggerConfiguration cfg, Boolean test, Func<LoggerConfiguration,LoggerConfiguration> action )
{
    if( test ) return action( cfg );
    else       return cfg;
}

Какие существуют альтернативы для переключения различных параметров Serilog во время выполнения?Существуют ли какие-либо подходы, которые можно использовать с другими «свободными» API-интерфейсами?

1 Ответ

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

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

Что-то вроде

Log.Logger = new LoggerConfiguration()
    .Enrich.WithExceptionDetails()
    .Enrich.FromLogContext()
    .MinimumLevel.Warning()
    .WriteToConsoleIfEnabled()  // <---
    .WriteToFileIfEnabled()     // <---
    .CreateLogger();

На другой ноте, вы рассматривали возможность использования Serilog.Settings.AppSettings или Serilog.Settings.Configuration?Конфигурация в коде становится намного чище, и вы можете добавлять / удалять приемники в файле конфигурации по своему желанию ...

Log.Logger = new LoggerConfiguration()
  .ReadFrom.AppSettings()
  .CreateLogger()

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="serilog:minimum-level" value="Verbose" />

    <add key="serilog:using:Console" value="Serilog.Sinks.Console" />
    <add key="serilog:write-to:Console" />

    <add key="serilog:using:RollingFile" value="Serilog.Sinks.RollingFile" />
    <add key="serilog:write-to:RollingFile.pathFormat" value="C:\myapp-{Date}.txt" />
    <add key="serilog:write-to:RollingFile.retainedFileCountLimit" value="10" />

    <!-- //etc... -->
  </appSettings>
</configuration>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...