繁体   English   中英

根据 .NET Core 2.1 中的更改重新加载 Serilog JSON 配置

[英]Reload Serilog JSON Configuration on changes in .NET Core 2.1

我目前正在开发一个 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。

谢谢!!

您可以使用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");
        }

您可以使用LoggingLevelSwitch更改日志级别。 你可以在这里阅读

您可以使用IOptionsSnapshot<>接口重新加载配置。 你可以在这里阅读更多相关信息

当前的 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库,它为此提供了实用功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM