【问题标题】:Reload Serilog JSON Configuration on changes in .NET Core 2.1在 .NET Core 2.1 中重新加载 Serilog JSON 配置
【发布时间】:2019-04-26 05:42:27
【问题描述】:

我目前正在开发一个 ASP.NET Core 2.1 应用程序,我使用 Serilog 进行日志记录。我想在运行时为我的 Serilog 实现重新加载应用程序设置文件。

我的目标是在运行时更改日志级别,例如我写入 minimumLevel Debug 而不是 Information 并保存文件。我想触发设置的实时重新加载。我的appsettings.json 看起来像这样:

{
  "serilog": {
    "using": [ "Serilog.Sinks.File", "Serilog.Sinks.Console" ],
    "minimumLevel": "Information",
    "writeTo": [
      {
        "name": "File",
        "args": {
          "fileSizeLimitBytes": 256000000,
          "retainedFileCountLimit": 62,
          "rollingInterval": "Day",
          "rollOnFileSizeLimit": true,
      },
      {
        "name": "Console",
      }
    ]
  }
}

在我的 Program.cs 中,我使用标志 reloadOnChange: true 加载设置。

public class Program
{
    public static readonly ServiceSettings Settings = new ServiceSettings();
        public static void Main(string[] args)
    {
        //...
    }
    public static IWebHostBuilder CreateWebHostBuilder(string[] args)
    {
        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile(Path.GetFullPath(CoreServiceBase.Instance.ConfigFilePath), optional: false, reloadOnChange: true)
            .AddCommandLine(args)
            .Build();

        config.Bind(Settings);

        return WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()
            .UseSerilog((hostingContext, loggerConfiguration) =>
                    loggerConfiguration.ReadFrom.Configuration(hostingContext.Configuration))
            .UseConfiguration(config);
    }
}

我的启动看起来像这样:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        // ...
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
    {
        // Custom application logging
        ApplicationLogging.LoggerFactory = loggerFactory;

        // ...
    }
}

如果我以某种方式更改了 appsettings.json,您是否知道如何在运行时重新加载 Serilog 配置。 => appsettings.json 的实时重新加载。

谢谢!!

【问题讨论】:

  • 我相信你在启动过程中阅读了配置文件。您可以引入某种中间件,它会在每个请求上读取您的配置文件,但这会增加延迟。值得吗?

标签: c# json logging .net-core serilog


【解决方案1】:

您可以使用LoggingLevelSwitch 更改日志级别。你可以阅读它here

您可以使用IOptionsSnapshot&lt;&gt; 接口重新加载配置。你可以阅读更多关于here

【讨论】:

    【解决方案2】:

    您可以使用Serilog.Settings.Reloader

    我没有 ASP 示例,但在控制台程序上你可以这样做:

            // Service collection
            IServiceCollection serviceCollection = new ServiceCollection()
                .AddLogging(loggingBuilder =>
                    loggingBuilder
                        .AddSerilog(SwitchableLogger.Instance, true)
                        .AddSerilogConfigurationLoader(configuration, SwitchableLogger.Instance)
                    );
    
            // Services
            using (var services = serviceCollection.BuildServiceProvider())
            {
                // Create logger
                Microsoft.Extensions.Logging.ILogger logger = services.GetService<Microsoft.Extensions.Logging.ILogger<Program>>();
    
                // Write
                logger.LogInformation("Hello World");
    
                // Modify config
                config.Set("Serilog:WriteTo:0:Args:OutputTemplate", "[{SourceContext}] {Message:lj}{NewLine}{Exception}");
                configuration.Reload();
    
                // Write with the previous logger instance, but with different settings
                logger.LogInformation("Hello world again");
            }
    

    【讨论】:

      【解决方案3】:

      当前的 Serilog 实现 (2.9.0) 无法完全重新加载设置。要在不引入其他依赖项的情况下解决此问题,请避免创建静态记录器并遵循此处提供的示例:https://github.com/akovac35/Logging/blob/v1.0.4/src/com.github.akovac35.Logging.Serilog/SerilogHelper.cs

      public static void CreateLogger()
      {
          CreateLogger(configure =>
          {
              configure.AddJsonFile("serilog.json", optional: false, reloadOnChange: true);
          });
      }
      
      public static void CreateLogger(Action<IConfigurationBuilder> configure)
      {
          if (configure == null) throw new ArgumentNullException(nameof(configure));
      
          UpdateLogger(configure);
      }
      
      public static void UpdateLogger(Action<IConfigurationBuilder> configure)
      {
          if (configure == null) throw new ArgumentNullException(nameof(configure));
      
          // The following pattern fires the reload token only once per settings change           
          var configurationBuilder = new ConfigurationBuilder();
          try
          {
              configure(configurationBuilder);
              IConfiguration configuration = configurationBuilder.Build();
      
              // Release previous callback - will be released only if this line is reached, allowing for another reload
              _changeCallback?.Dispose();
              _changeCallback = null;
              // .NET will not trigger a reload for invalid config file format, so reaching this line signals Json is OK
              _changeCallback = configuration.GetReloadToken().RegisterChangeCallback(state =>
              {
                  UpdateLogger(configure);
              }, null);
      
              // Reading configuration will fail for invalid properties, that is why reload registration must happen
              // before this line or subsequent file updates may not be detected
              global::Serilog.ILogger newLogger = new LoggerConfiguration()
              .ReadFrom.Configuration(configuration)
              .Enrich.FromLogContext()
              .CreateLogger();
      
              Log.Logger = newLogger;
      
              GetLogger().Here(l => l.LogInformation("Updated logger: {@configuration}", configuration));
          }
          catch (Exception ex)
          {
              GetLogger().Here(l => l.LogError(ex, ex.Message));
          }
      }
      

      或者您可以简单地使用提供实用功能的 Logging.Serilog 库。

      【讨论】:

        猜你喜欢
        • 2018-11-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-27
        • 2019-02-20
        • 1970-01-01
        • 2018-11-26
        • 1970-01-01
        相关资源
        最近更新 更多