简体   繁体   English

Serilog - 覆盖配置值

[英]Serilog - Override config values

I am building a Windows 10 app (UWP) and implementing logging using Serilog.我正在构建一个 Windows 10 应用程序 (UWP) 并使用 Serilog 实现日志记录。

Shown below is an appsettings.json file with which I configure Serilog to write to a Rolling File sink (amongst other sinks).下面显示的是一个 appsettings.json 文件,我使用它配置 Serilog 以写入滚动文件接收器(以及其他接收器)。

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

I then call the following code:然后我调用以下代码:

 var configuration = new ConfigurationBuilder()                        
        .AddJsonFile(sampleFile.Path)
        .Build();

    Log.Logger = new LoggerConfiguration()
        .ReadFrom.Configuration(configuration)
        .CreateLogger();

However, I need to be able to change the pathFormat attribute at runtime, so that the log is written to the application's “LocalState” folder.但是,我需要能够在运行时更改 pathFormat 属性,以便将日志写入应用程序的“LocalState”文件夹。

Q. Does Serilog support reading from configuration and then overriding particularly arguments at runtime?问:Serilog 是否支持从配置中读取然后在运行时覆盖特定的参数?

My current workaround is to use a token in the JSON called “#{LogFilePath}” and replace this in the file at runtime.我目前的解决方法是在 JSON 中使用一个名为“#{LogFilePath}”的令牌,并在运行时在文件中替换它。

I've found the following, but can't use environment variables in my case: Specify directory for Serilog rolling file path我发现了以下内容,但在我的情况下不能使用环境变量: 为 Serilog 滚动文件路径指定目录

According to Serilog , you would need to use file logging – as it seems, RollingFile might be going away soon. 根据 Serilog 的说法,您需要使用文件日志记录——看起来,RollingFile 可能很快就会消失。

Important note: the rolling functionality in this sink has been improved and merged into the Serilog.Sinks.File package.重要说明:此接收器中的滚动功能已得到改进并合并到 Serilog.Sinks.File 包中。 RollingFile will be maintained for the foreseeable future, however File is recommended for new applications. RollingFile 将在可预见的未来维护,但建议将 File 用于新应用程序。

Fixed Format固定格式

Here is a straightforward way of using a File Sink:这是使用文件接收器的直接方法:

appsettings.json appsettings.json

{
  "Serilog": {
    "MinimumLevel": "Verbose",
    "WriteTo": [
      {
        "Name": "Console"        
      },
      {
        "Name": "File",
        "Args": {
          "path": "Logs\\log.txt",
          "fileSizeLimitBytes": 3000,
          "buffered": false,
          "rollOnFileSizeLimit": true,
          "retainedFileCountLimit": 3,
          "rollingInterval": "Hour"
        }
      }
    ]
  }
}

Program.cs程序.cs

var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();
var loggerConfig = new LoggerConfiguration().ReadFrom.Configuration(configuration);
var logger = loggerConfig.CreateLogger();

Custom Format自定义格式

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.去年,在 Serilog 团队和社区中,似乎有些人热衷于指定一些默认配置,然后让配置文件覆盖它。 They created an experimental repository , and a Nuget Package - not sure where that stands today.他们创建了一个实验性存储库和一个Nuget 包- 不确定今天的情况。

But I think there is a work around – below is one of the ways how you could implement this in a little bit cleaner way, than your "token" approach.但我认为有一种解决方法——下面是一种比“令牌”方法更简洁的实现方式。

appsettings.json appsettings.json

{
  "FileLogger": {
    //"path": "Logs\\log.txt",
  }
}

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.在应用程序中指定默认值,然后使用配置来覆盖它们(而不是相反)在我看来是更好的设计。

Program.cs程序.cs

var configuration = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true).Build();

var customLogFileFormat = configuration["FileLogger:path"] ?? $"Logs\\log_{DateTime.Now.ToString("MMddyyyy_hhmmsstt")}log.txt";

var loggerConfig = new LoggerConfiguration()
                .MinimumLevel.Debug()
                .WriteTo.Console()
                .WriteTo.File(
                    path: customLogFileFormat,
                    fileSizeLimitBytes: 3000,
                    buffered: true,
                    rollOnFileSizeLimit: true,
                    rollingInterval: RollingInterval.Day,
                    retainedFileCountLimit: 5);

If you are interested about more details about my test app, following sequence of PoweShell commands might help:如果您对我的测试应用程序的更多详细信息感兴趣,以下 PoweShell 命令序列可能会有所帮助:

mkdir SerilogApp
cd SerilogApp
dotnet new console -f netcoreapp2.2 -n SerilogApp -o SerilogApp
dotnet new sln -n SerilogApp.sln
dotnet sln add .\SerilogApp\SerilogApp.csproj
dotnet add .\SerilogApp\SerilogApp.csproj package Microsoft.Extensions.Configuration -f netcoreapp2.2
dotnet add .\SerilogApp\SerilogApp.csproj package Microsoft.Extensions.Configuration.FileExtensions -f netcoreapp2.2
dotnet add .\SerilogApp\SerilogApp.csproj package Microsoft.Extensions.Configuration.Json -f netcoreapp2.2
dotnet add .\SerilogApp\SerilogApp.csproj package Serilog -f netcoreapp2.2
dotnet add .\SerilogApp\SerilogApp.csproj package Serilog.Settings.Configuration -f netcoreapp2.2
dotnet add .\SerilogApp\SerilogApp.csproj package Serilog.Sinks.Console -f netcoreapp2.2
 dotnet add .\SerilogApp\SerilogApp.csproj package Serilog.Sinks.File -f netcoreapp2.2 -v 4.0.0
cd .\SerilogApp
echo $null >> appsettings.json

You can change the configuration after it's read from json and before you use it to create the logger.您可以在从 json 读取配置之后以及在使用它创建记录器之前更改配置。 Assuming the following json:假设以下json:

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
    "MinimumLevel": {
      "Default": "Debug"
    },
    "WriteTo": [
      {
        "Name": "Console",
        "Args": {
          "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj}{NewLine}{Exception}"
        }
      },
      {
        "Name": "File",
        "Args": {
          "path": "placeholder",
          "buffered": false,
          "outputTemplate": "[{Timestamp:HH:mm:ss.fff} {Level:u3}] {Message}{NewLine}{Exception}",
          "rollingInterval": "Day"
        }
      }
    ],
    "Enrich": [ "FromLogContext" ]
  }
}

Use this code to update the "placeholder" in the json file to "abc.log" prior to the call to CreateLogger.在调用 CreateLogger 之前,使用此代码将 json 文件中的“占位符”更新为“abc.log”。

 var configuration = new ConfigurationBuilder()
         .AddJsonFile(AppSettingsPath, 
             optional: false, reloadOnChange: true)
         .Build();

 configuration["Serilog:WriteTo:1:Args:path"] = "abc.log";

 Log.Logger = new LoggerConfiguration()
     .ReadFrom.Configuration(configuration)
     .WriteTo.SerilogSink(MessageBroker.Broker)
     .CreateLogger();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM