Serilog JSON config LoggingLevelSwitch access

Xor*_*ist 7 serilog asp.net-core-2.1 .net-core-2.1

Configuring Serilog using a JSON config, it is possible to configure log level switches as such:

"LevelSwitches": {
  "$appLogLevel": "Debug",
  "$netLogLevel": "Information",
  "$sysLogLevel": "Error"
},
"MinimumLevel": {
  "ControlledBy": "$appLogLevel",
  "Override": {
    "Microsoft": "$netLogLevel",
    "System": "$sysLogLevel"
  }
}
Run Code Online (Sandbox Code Playgroud)

the purpose of the switches (when instantiated in code) is to be accessed at a later time in order to change the minimum log levels during run-time. However when configured via the JSON config, I can't find a way to access those switch instances. Does anyone know how to access them?

tsi*_*lar 1

如果您想从代码访问级别开关,这可能意味着您有办法以某种方式控制它们,因此您可能首先不需要在配置文件中使用它们......

\n\n

我确实相信将该部分完全保留在代码中并部分在代码中和部分在配置文件中进行配置更有意义,因此看起来像这样:

\n\n
// in C# code\nvar appLevelSwitch = new LoggingLevelSwitch(LogEventLevel.Debug);\nvar netLevelSwitch= new LoggingLevelSwitch(LogEventLevel.Information);\nvar systemLevelSwitch= new LoggingLevelSwitch(LogEventLevel.Error);\n\nvar configuration = new ConfigurationBuilder()\n            .AddJsonFile("appsettings.json")\n            .Build();\n\nLog.Logger = new LoggerConfiguration()\n            // load config from config file ...\n            .ReadFrom.Configuration(configuration)\n            // ... and complete it in C# code\n            .MinimumLevel.ControlledBy(appLevelSwitch )\n            .MinimumLevel.Override("Microsoft", netLevelSwitch)\n            .MinimumLevel.Override("System", systemLevelSwitch)\n            .CreateLogger();\n
Run Code Online (Sandbox Code Playgroud)\n\n

并在你的配置文件中

\n\n
{\n  "Serilog": {\n    "Using":  ["Serilog.Sinks.Console"],\n    "WriteTo": [\n      { "Name": "Console" },\n      { "Name": "File", "Args": { "path": "%TEMP%\\\\Logs\\\\serilog-configuration-sample.txt" } }\n    ],\n    "Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"],\n    "Destructure": [\n      { "Name": "With", "Args": { "policy": "Sample.CustomPolicy, Sample" } },\n      { "Name": "ToMaximumDepth", "Args": { "maximumDestructuringDepth": 4 } },\n      { "Name": "ToMaximumStringLength", "Args": { "maximumStringLength": 100 } },\n      { "Name": "ToMaximumCollectionCount", "Args": { "maximumCollectionCount": 10 } }\n    ],\n    "Properties": {\n        "Application": "Sample"\n    }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

不过,为了完整起见,为了访问定义的控制开关,您可以执行以下操作(请注意,这是一种黑客行为!)。

\n\n

编写一个配置方法(即可以出现在 后面的扩展方法.WriteTo.xxx),该方法接受LoggingLevelSwitches 作为参数并将它们存储为static成员。该配置方法将引入一个不执行任何操作的虚拟对象 ILogEventSink(出于性能考虑,我们甚至可以指定restrictedToMinimumLevel: LogEventLevel.Fatal它几乎永远不会被调用)。然后从配置文件调用该扩展方法(Serilog.Settings.Configuration知道如何查找扩展方法并向其传递参数),voil\xc3\xa0,您现在可以static从代码访问开关!

\n\n

它看起来是这样的:

\n\n
public static class LevelSwitches\n{\n    private static LoggingLevelSwitch _switch1;\n    private static LoggingLevelSwitch _switch2;\n    private static LoggingLevelSwitch _switch3;\n\n    public static LoggingLevelSwitch Switch1 => _switch1 ?? throw  new InvalidOperationException("Switch1 not initialized !");\n    public static LoggingLevelSwitch Switch2 => _switch2 ?? throw  new InvalidOperationException("Switch2 not initialized !");\n    public static LoggingLevelSwitch Switch3 => _switch3 ?? throw  new InvalidOperationException("Switch3 not initialized !");\n\n    public static LoggerConfiguration CaptureSwitches(\n        this LoggerSinkConfiguration sinkConfig,\n        LoggingLevelSwitch switch1,\n        LoggingLevelSwitch switch2,\n        LoggingLevelSwitch switch3)\n    {\n        _switch1 = switch1;\n        _switch2 = switch2;\n        _switch3 = switch3;\n\n        return sinkConfig.Sink(\n            restrictedToMinimumLevel: LogEventLevel.Fatal,\n            logEventSink: new NullSink());\n    }\n}\n\npublic sealed class NullSink : ILogEventSink\n{\n    public void Emit(LogEvent logEvent)\n    {\n        // nothing here, that\'s a useles sink !\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后在你的 json 配置文件中:

\n\n
"LevelSwitches": {\n  "$appLogLevel": "Debug",\n  "$netLogLevel": "Information",\n  "$sysLogLevel": "Error"\n},\n"MinimumLevel": {\n  "ControlledBy": "$appLogLevel",\n  "Override": {\n    "Microsoft": "$netLogLevel",\n    "System": "$sysLogLevel"\n  }\n},\n"WriteTo":[\n  {\n    "Name": CaptureSwitches"", \n    "Args": {\n      "switch1": "$appLogLevel",\n      "switch2": "$netLogLevel",\n      "switch3": "$sysLogLevel",\n    }\n  }\n]\n
Run Code Online (Sandbox Code Playgroud)\n\n

(您可能需要一个"Using"带有包含该类的程序集名称的指令LevelSwitches

\n\n

从配置文件配置您的记录器

\n\n
    var configuration = new ConfigurationBuilder()\n        .AddJsonFile("appsettings.json")\n        .Build();\n\n    var logger = new LoggerConfiguration()\n        .ReadFrom.Configuration(configuration)\n        .CreateLogger();\n
Run Code Online (Sandbox Code Playgroud)\n\n

从那时起,您应该能够通过LevelSwitches.Switch1LevelSwitches.Switch2和访问开关LevelSwitches.Switch3

\n