为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
www说 2022-12-24 10:12:57
我有一个扩展方法来配置我的记录器: 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] 事件处理器服务正在启动。[19-04-19 00:59:09 INF] 事件处理器服务正在启动。我有在服务中使用的扩展方法,但有时我需要覆盖 appsettings.json(或环境变量)中的某些设置,我该怎么做?因为当前的解决方案不起作用并添加了第二个记录器
查看完整描述

1 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

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


    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);

                }

            });

    }


查看完整回答
反对 回复 2022-12-24
  • 1 回答
  • 0 关注
  • 210 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号