Serilog - 覆盖配置值

How*_*ard 4 c# serilog

我正在构建 Windows 10 应用程序 (UWP) 并使用 Serilog 实现日志记录。

\n\n

下面显示的是一个 appsettings.json 文件,我用它配置 Serilog 以写入滚动文件接收器(以及其他接收器)。

\n\n
{\n  "Serilog": {\n    "Using": [ "Serilog.Sinks.Console" ],\n    "MinimumLevel": "Debug",\n    "WriteTo": [\n      { "Name": "Console" },\n      {\n        "Name": "RollingFile",\n        "Args": {\n          "pathFormat": "#{LogFilePath}log-{Date}.txt",\n          "fileSizeLimitBytes": "3000",\n          "retainedFileCountLimit": "2"\n        }\n      }      \n    ],\n    "Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],\n    "Properties": {\n      "Application": "Sample"\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后我调用以下代码:

\n\n
 var configuration = new ConfigurationBuilder()                        \n        .AddJsonFile(sampleFile.Path)\n        .Build();\n\n    Log.Logger = new LoggerConfiguration()\n        .ReadFrom.Configuration(configuration)\n        .CreateLogger();\n
Run Code Online (Sandbox Code Playgroud)\n\n

但是,我需要能够在运行时更改 pathFormat 属性,以便将日志写入 application\xe2\x80\x99s \xe2\x80\x9cLocalState\xe2\x80\x9d 文件夹。

\n\n

问:Serilog 是否支持读取配置,然后在运行时覆盖特定参数?

\n\n

我当前的解决方法是在 JSON 中使用名为 \xe2\x80\x9c#{LogFilePath}\xe2\x80\x9d 的令牌,并在运行时在文件中替换它。

\n\n

我\xe2\x80\x99ve发现以下内容,但在我的情况下可以\xe2\x80\x99t使用环境变量: 指定Serilog滚动文件路径的目录

\n

abl*_*aze 5

根据 Serilog,您将需要使用文件日志记录 \xe2\x80\x93 ,因为看起来,RollingFile 可能很快就会消失。

\n\n
\n

重要提示:此接收器中的滚动功能已得到改进并合并到 Serilog.Sinks.File 包中。RollingFile\n 将在可预见的将来得到维护,但建议新应用程序\n 使用 File。

\n
\n\n

固定格式

\n\n

Here is a straightforward way of using a File Sink:

\n\n

appsettings.json

\n\n
{\n  "Serilog": {\n    "MinimumLevel": "Verbose",\n    "WriteTo": [\n      {\n        "Name": "Console"        \n      },\n      {\n        "Name": "File",\n        "Args": {\n          "path": "Logs\\\\log.txt",\n          "fileSizeLimitBytes": 3000,\n          "buffered": false,\n          "rollOnFileSizeLimit": true,\n          "retainedFileCountLimit": 3,\n          "rollingInterval": "Hour"\n        }\n      }\n    ]\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

Program.cs

\n\n
var configuration = new ConfigurationBuilder()\n    .SetBasePath(Directory.GetCurrentDirectory())\n    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();\nvar loggerConfig = new LoggerConfiguration().ReadFrom.Configuration(configuration);\nvar logger = loggerConfig.CreateLogger();\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

Custom Format

\n\n

Last year there seemed to be some enthusiasm to specify some default configuration then have it overridden by the config files, in the Serilog team & the community. They created an experimental repository, and a Nuget Package - not sure where that stands today.

\n\n

But I think there is a work around \xe2\x80\x93 below is one of the ways how you could implement this in a little bit cleaner way, than your "token" approach.

\n\n

appsettings.json

\n\n
{\n  "FileLogger": {\n    //"path": "Logs\\\\log.txt",\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

This way, if you specify the value in the config file, it would take precedence. Else, your custom format would be used. Having defaults specified in the application and then using configurations to override them (instead the other way around) is a better design in my opinion.

\n\n

Program.cs

\n\n
var configuration = new ConfigurationBuilder()\n    .SetBasePath(Directory.GetCurrentDirectory())\n    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();\n\nvar customLogFileFormat = configuration["FileLogger:path"] ?? $"Logs\\\\log_{DateTime.Now.ToString("MMddyyyy_hhmmsstt")}log.txt";\n\nvar loggerConfig = new LoggerConfiguration()\n                .MinimumLevel.Debug()\n                .WriteTo.Console()\n                .WriteTo.File(\n                    path: customLogFileFormat,\n                    fileSizeLimitBytes: 3000,\n                    buffered: true,\n                    rollOnFileSizeLimit: true,\n                    rollingInterval: RollingInterval.Day,\n                    retainedFileCountLimit: 5);\n
Run Code Online (Sandbox Code Playgroud)\n\n

If you are interested about more details about my test app, following sequence of PoweShell commands might help:

\n\n
mkdir SerilogApp\ncd SerilogApp\ndotnet new console -f netcoreapp2.2 -n SerilogApp -o SerilogApp\ndotnet new sln -n SerilogApp.sln\ndotnet sln add .\\SerilogApp\\SerilogApp.csproj\ndotnet add .\\SerilogApp\\SerilogApp.csproj package Microsoft.Extensions.Configuration -f netcoreapp2.2\ndotnet add .\\SerilogApp\\SerilogApp.csproj package Microsoft.Extensions.Configuration.FileExtensions -f netcoreapp2.2\ndotnet add .\\SerilogApp\\SerilogApp.csproj package Microsoft.Extensions.Configuration.Json -f netcoreapp2.2\ndotnet add .\\SerilogApp\\SerilogApp.csproj package Serilog -f netcoreapp2.2\ndotnet add .\\SerilogApp\\SerilogApp.csproj package Serilog.Settings.Configuration -f netcoreapp2.2\ndotnet add .\\SerilogApp\\SerilogApp.csproj package Serilog.Sinks.Console -f netcoreapp2.2\n dotnet add .\\SerilogApp\\SerilogApp.csproj package Serilog.Sinks.File -f netcoreapp2.2 -v 4.0.0\ncd .\\SerilogApp\necho $null >> appsettings.json\n
Run Code Online (Sandbox Code Playgroud)\n

  • 但是,有没有办法让 Serilog 基于“appsettings.json”自动初始化,但在“Startup.cs”中覆盖代码中的某些设置? (3认同)