gpt4 book ai didi

serilog - 稍后在运行时创建 serilog 文件接收器 - 如何?

转载 作者:行者123 更新时间:2023-12-03 17:33:42 28 4
gpt4 key购买 nike

我在服务器端使用 Serilog 为我所有的 .NETCore 服务使用控制台、文件和 Graylog 接收器。我也喜欢在我的 Windows 胖客户端(WPF 应用程序)中使用它。

后者我有问题既然看不到,我怎么能在用户成功登录后添加另一个文件接收器 .我需要一个应用程序日志存储在全局 AppData (Environment.SpecialFolder.CommonApplicationData)文件夹和另一个 用户日志 在用户中 子文件夹 例如像这样:

var appName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
AppDataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), appName);
Directory.CreateDirectory(AppDataDir);
AppLogDir = Path.Combine(AppDataDir, $@"Logs");
Directory.CreateDirectory(AppLogDir);

Log.Logger = new LoggerConfiguration()
.ReadFrom.AppSettings()
.Enrich.WithExceptionDetails()
.Enrich.FromLogContext()
.Enrich.WithProcessName()
.Enrich.WithThreadId()
.Enrich.WithAssemblyName()
.WriteTo.Console(outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext}] " +
"ThreadId: [{ThreadId}] {Message:lj}{NewLine}{Exception}")
.WriteTo.File(Path.Combine(AppLogDir, $"{appName}-.log"), rollOnFileSizeLimit: true,
fileSizeLimitBytes: 1048576, retainedFileCountLimit: 30,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext}] " +
"[ThreadId: {ThreadId}] {Message:lj}{NewLine}{Exception}")
.CreateLogger();

然后在我的 LoginViewModel 之后成功 登录和 配置初始应用程序记录器很久之后 ,我知道用户名并且可以为该用户创建一个文件夹并将日志文件放在那里:
var userLogDir = Path.Combine(AppDataDir, userName); // <-- userName comes from login token
Directory.CreateDirectory(userLogDir);

现在是棘手的一点:如何将文件接收器添加到我的 现有 记录器配置???我需要类似的东西:
var loggerConfig = Log.GetLoggerConfiguration();  //<--- This is missing, at least I could not find it!
loggerConfig.WriteTo.File(Path.Combine(userLogDir, $"{appName}-{userName}-.log"), rollOnFileSizeLimit: true,
fileSizeLimitBytes: 10485760, retainedFileCountLimit: 30,
outputTemplate: "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] [{SourceContext}] " +
"[ThreadId: {ThreadId}] {Message:lj}{NewLine}{Exception}")

知道如何使用 Serilog 实现这一点吗?

最佳答案

我知道这很旧,但我想我会回答这个问题,因为我只需要在我的一个项目中做类似的事情(在运行时更改记录器)。
事实证明有几种方法可以做到这一点,主要的事情(至少在前两种中)是将记录器配置与记录器本身分离。如果您想稍后简单地添加接收器而不是从头开始,这允许您存储配置以供以后使用。
替换现有记录器
第一种方法用新的记录器完全替换记录器

var logfilepath = GetLogFilePath(Assembly.GetEntryAssembly());
var loggerConfig = new LoggerConfiguration()
.WriteTo.RollingFile(logfilepath);

Log.Logger= loggerConfig.CreateLogger();

Log.Debug("It works!");


//Somewhere later in the program
Log.Debug("Setting up database with {ConnectionString}", connectionString);


loggerConfig = loggerConfig.WriteTo.MSSqlServer(
connectionString: "Server=localhost;Database=LogDb;Integrated Security=SSPI;",
sinkOptions: new MSSqlServerSinkOptions { TableName = "LogEvents" });

Log.Logger = loggerConfig.CreateLogger(); //Replace the old logger with the new one
创建新记录器并将所有事件也发送到旧记录器
下一个示例向我们展示了创建一个新记录器,然后将所有事件也传递给旧记录器,从而有效地允许我们添加。如果你走这条路,记住 Logger 的生命周期很重要。
Log.Debug("Setting up database with {ConnectionString}", connectionString);

var loggerConfig = new LoggerConfiguration()
.WriteTo.Sink((ILogEventSink)Log.Logger) //Here we're passing in the old logger
.WriteTo.MSSqlServer(
connectionString: "Server=localhost;Database=LogDb;Integrated Security=SSPI;",
sinkOptions: new MSSqlServerSinkOptions { TableName = "LogEvents" });

Log.Logger = loggerConfig.CreateLogger();
跟上配置
以这种方式设置记录器时,我们可以轻松地将配置添加到 DI 容器,如下所示:
IServiceCollection services.AddSingleton(loggerConfig); 团结 container.RegisterInstance(loggerConfig);这使我们能够在应用程序生命周期的后期访问我们的配置,并且在很大程度上使我们不必再次重新配置所有接收器、浓缩器等。
奖金
作为额外的好处,我遇到的另一件事是我们也可以在运行时从 dll 加载接收器(Serilog >=3.0)。如 this issue 中所述我们可以使用 ConfigurationAssemblySource 在运行时从程序集加载配置。
public static LoggerConfiguration Configuration(
this LoggerSettingsConfiguration settingConfiguration,
IConfiguration configuration,
ConfigurationAssemblySource configurationAssemblySource)
{ ... }

关于serilog - 稍后在运行时创建 serilog 文件接收器 - 如何?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51979815/

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