重新加载 Serilog JSON .NET Core 2.1 中更改的配置
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;
// ...
}
}
你知道如何在运行时重新加载 Serilog 配置吗,如果我以某种方式更改了 appsettings.json。 => appsettings.json.
的实时重新加载
谢谢!!
您可以使用 LoggingLevelSwitch
更改日志级别。你可以阅读它 here
您可以使用IOptionsSnapshot<>
界面重新加载配置。您可以阅读更多相关信息 here
您可以使用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");
}
澄清一下,单例“SwitchableLogger.Instance”仅用于演示,也可以创建一个新实例“new SwitchableLogger()”。
当前的 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 库,它为此提供实用函数。
我目前正在开发 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;
// ...
}
}
你知道如何在运行时重新加载 Serilog 配置吗,如果我以某种方式更改了 appsettings.json。 => appsettings.json.
的实时重新加载谢谢!!
您可以使用 LoggingLevelSwitch
更改日志级别。你可以阅读它 here
您可以使用IOptionsSnapshot<>
界面重新加载配置。您可以阅读更多相关信息 here
您可以使用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");
}
澄清一下,单例“SwitchableLogger.Instance”仅用于演示,也可以创建一个新实例“new SwitchableLogger()”。
当前的 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 库,它为此提供实用函数。