我有一个扩展方法来配置我的记录器:
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/