gpt4 book ai didi

serilog - 在 Serilog 中动态更改日志文件路径?

转载 作者:行者123 更新时间:2023-12-04 09:57:43 30 4
gpt4 key购买 nike

我具有动态更改日志文件路径的功能。但是,当我更改 Consul 中可配置的路径时,它会在两个地方(即旧路径和新路径)写入部分日志。更改日志文件路径应该可以在没有任何服务重启的情况下工作。我们如何存档?

我们在日志文件中写入如下:

.WriteTo.File(logFolderFullPath + "\\" + applicationName + "_.txt",
LogEventLevel.Error, shared: true,
fileSizeLimitBytes: fileSizeLimitBytes, rollOnFileSizeLimit: true, rollingInterval: RollingInterval.Day,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level}] [{MachineName}] [{SourceContext}] {RequestId} {CorrelationId} {Message}{NewLine}{Exception}{properties}")

logFolderFullPath 是来自 appsetting.json 的可配置路径。当我们更改路径时,它会在新路径创建一个日志文件,但同时也会继续写入旧路径文件。

所以我们希望它应该停止写入旧路径。

最佳答案

你可以尝试使用Serilog.Settings.Reloader当您的配置更改时,它可以在运行时交换您的记录器实例。


另一种在运行时更改记录器属性的常用方法是使用 Serilog.Sinks.Map ,一个根据日志事件的属性分派(dispatch)事件的接收器。

下面的示例使用名为 FileName 的日志事件属性来决定它将写入的日志文件的名称,因此只要此属性发生变化,日志文件就会相应地发生变化:

Log.Logger = new LoggerConfiguration()
.WriteTo.Map("FileName", "IDontKnow", (fileName, wt) => wt.File($"{fileName}.txt"))
.CreateLogger();

Log.ForContext("FileName", "Alice").Information("Hey!"); // writes to Alice.txt
Log.ForContext("FileName", "Bob").Information("Hello!"); // writes to Bob.txt
Log.Information("Hi Again!"); // writes to IDontKnow.txt (default if property is missing)

Log.CloseAndFlush();

在您的情况下,您希望根据对配置的更改动态更改此属性名称。一个简单的方法是创建自定义 enricher可以根据您的配置设置更改上述属性的值。

您的定制enricher看起来像这样:

internal class LogFilePathEnricher : ILogEventEnricher
{
private string _cachedLogFilePath;
private LogEventProperty _cachedLogFilePathProperty;

public const string LogFilePathPropertyName = "LogFilePath";

public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
{
var logFilePath = // Read path from your appsettings.json
// Check for null, etc...

LogEventProperty logFilePathProperty;

if (logFilePath.Equals(_cachedLogFilePath))
{
// Path hasn't changed, so let's use the cached property
logFilePathProperty = _cachedLogFilePathProperty;
}
else
{
// We've got a new path for the log. Let's create a new property
// and cache it for future log events to use
_cachedLogFilePath = logFilePath;

_cachedLogFilePathProperty = logFilePathProperty =
propertyFactory.CreateProperty(LogFilePathPropertyName, logFilePath);
}

logEvent.AddPropertyIfAbsent(logFilePathProperty);
}
}

注意:如果您使用 Options pattern,上面的示例丰富器可能会更有效率,而不是每次写入日志消息时都检查配置。

有了可以根据配置为您动态设置 LogFilePath 属性的增强器,您只需将日志记录管道配置为基于该属性进行映射即可。

Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.Enrich.With<LogFileNameEnricher>()
.WriteTo.Map(LogFileNameEnricher.LogFilePathPropertyName,
(logFilePath, wt) => wt.File($"{logFilePath}"), sinkMapCountLimit: 1)
.CreateLogger();

// ...

Log.CloseAndFlush();

关于serilog - 在 Serilog 中动态更改日志文件路径?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61889762/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com