代码之家  ›  专栏  ›  技术社区  ›  Dai

可以用if语句优雅地配置Serilog吗?

  •  3
  • Dai  · 技术社区  · 6 年前

    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使用了“fluent”风格的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

    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选项有哪些替代方法?有什么方法可以与其他“Fluent”api一起使用吗?

    1 回复  |  直到 6 年前
        1
  •  3
  •   C. Augusto Proiete    6 年前

    我认为,要使它变得优雅并且仍然在代码中进行,您必须扩展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>
    
        2
  •  5
  •   C. Augusto Proiete    4 年前

    Serilog 2.9.0 引入条件接收。使用 .WriteTo.Conditional 指定定义是否写入接收器的条件。

    例如

    bool enableConsoleLogging = ...
    bool enableFileLogging = ...
    
    var builder = new LoggerConfiguration()
        .Enrich.WithExceptionDetails()
        .Enrich.FromLogContext()
        .MinimumLevel.Warning()
        .WriteTo.Conditional(evt => enableConsoleLogging, wt => wt.Console())
        .WriteTo.Conditional(evt => enableFileLogging, wt => wt.File(...));
    
    Log.Logger = builder.CreateLogger();
    // ...