c# - 如何使用 appsettings.json 覆盖 serilog 设置

标签 c# serilog

我有一个扩展方法来配置我的记录器:

 public static class Extensions
 {
     public static IWebHostBuilder UseLogging(this IWebHostBuilder webHostBuilder) =>
         webHostBuilder.UseSerilog((context, loggerConfiguration) =>
         {
             var logLevel = context.Configuration.GetValue<string>("Serilog:MinimumLevel");
             if (!Enum.TryParse<LogEventLevel>(logLevel, true, out var level))
             {
                 level = LogEventLevel.Information;
             }

             loggerConfiguration.Enrich
                 .FromLogContext()
                 .MinimumLevel.Is(level);

             loggerConfiguration
                 .ReadFrom.Configuration(context.Configuration)
                 .WriteTo.Console(
                     theme: AnsiConsoleTheme.Code,
                     outputTemplate: "[{Timestamp:yy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}");
         });
 }

我添加了这一行 .ReadFrom.Configuration(context.Configuration) 并期望来自 appsettings.json 的所有设置都将覆盖当前配置。我的意思是,如果我在 appsettings.json 中指定其他 outputTemplate,那么它将覆盖现有的。

    "Serilog": {
        "WriteTo": [
            {
                "Name": "Console",
                "Args": {
                    "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}"
                }
            }
        ]
    }

但它不起作用。现在日志消息是重复的,一个是代码格式的,另一个是配置格式的。如何在运行时覆盖 appsettings.json 中的某些设置?

[03:59:09 INF] event processor service is starting.

[19-04-19 00:59:09 INF] event processor service is starting.

我有在服务中使用的扩展方法,但有时我需要覆盖 appsettings.json(或环境变量)中的某些设置,我该怎么做?因为当前的解决方案不起作用并添加了第二个记录器

最佳答案

您基本上必须检查配置是否已经指定了控制台记录器。存储接收器的字段是私有(private)的。所以你必须使用类似的东西来对配置使用react。当您想要覆盖记录器上的某些属性时,您还需要使用反射来访问这些字段。下面的代码适用于我的简单测试应用程序。

    public static class Extensions
    {
        public static IWebHostBuilder UseLogging(this IWebHostBuilder webHostBuilder) =>
            webHostBuilder.UseSerilog((context, loggerConfiguration) =>
            {
                var logLevel = context.Configuration.GetValue<string>("Serilog:MinimumLevel");
                if (!Enum.TryParse<LogEventLevel>(logLevel, true, out var level))
                {
                    level = LogEventLevel.Information;
                }

                loggerConfiguration.Enrich
                    .FromLogContext()
                    .MinimumLevel.Is(level);

                loggerConfiguration
                    .ReadFrom.Configuration(context.Configuration);

                // Get the field that holds the sinks.
                var sinks = loggerConfiguration.GetType()
                    .GetField("_logEventSinks", BindingFlags.Instance | BindingFlags.NonPublic)
                    .GetValue(loggerConfiguration) as List<ILogEventSink>;

                // Get the sink type for reusage.
                var sinkType = typeof(AnsiConsoleTheme).Assembly.GetType("Serilog.Sinks.SystemConsole.ConsoleSink");

                // Find the first sink of the right type.
                var sink = sinks?.FirstOrDefault(s => sinkType == s.GetType());

                // Check if a sink was found.
                if (sink == null)
                {
                    // No sink found add a new one.
                    loggerConfiguration
                        .WriteTo.Console(
                            theme: AnsiConsoleTheme.Code,
                            outputTemplate:
                            "[{Timestamp:yy-MM-dd HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}");
                }
                else
                {
                    // Otherwise change the theme.
                    sinkType.GetField("_theme", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(sink, AnsiConsoleTheme.Code);
                }
            });
    }

关于c# - 如何使用 appsettings.json 覆盖 serilog 设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55777617/

相关文章:

Serilog - 在 AppSettings 中配置多个接收器

c# - 使用 appSettings 配置自定义 Serilog 接收器

使用 Linq 进行 C# 泛型转换

C# hex byte 0x09 (ascii -> tab) to "\t"string

c# - View 是否可以在不先将其保存到文件的情况下显示 WebImage?

c# - 发布 WPF .Net Core 3 应用程序和 Serilog.Sinks.File

c# - 比较两个对象的属性

c# - 我如何用 .net 解析这个 json?

c# - 在没有 DI 的情况下获取 Serilog 记录器的实例

asp.net-web-api2 - 在 WebApi2 中使用 Serilog 的正确方法