如果你想从代码中访问你的关卡开关,这可能意味着你有办法以某种方式控制它们,所以你可能一开始就不需要它们在配置文件中......
我确实认为将那部分完全保留在代码中并具有配置部分在代码中,部分在配置文件中更有意义,所以看起来像这样:
// in C# code
var appLevelSwitch = new LoggingLevelSwitch(LogEventLevel.Debug);
var netLevelSwitch= new LoggingLevelSwitch(LogEventLevel.Information);
var systemLevelSwitch= new LoggingLevelSwitch(LogEventLevel.Error);
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
Log.Logger = new LoggerConfiguration()
// load config from config file ...
.ReadFrom.Configuration(configuration)
// ... and complete it in C# code
.MinimumLevel.ControlledBy(appLevelSwitch )
.MinimumLevel.Override("Microsoft", netLevelSwitch)
.MinimumLevel.Override("System", systemLevelSwitch)
.CreateLogger();
在你的配置文件中
{
"Serilog": {
"Using": ["Serilog.Sinks.Console"],
"WriteTo": [
{ "Name": "Console" },
{ "Name": "File", "Args": { "path": "%TEMP%\\Logs\\serilog-configuration-sample.txt" } }
],
"Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"],
"Destructure": [
{ "Name": "With", "Args": { "policy": "Sample.CustomPolicy, Sample" } },
{ "Name": "ToMaximumDepth", "Args": { "maximumDestructuringDepth": 4 } },
{ "Name": "ToMaximumStringLength", "Args": { "maximumStringLength": 100 } },
{ "Name": "ToMaximumCollectionCount", "Args": { "maximumCollectionCount": 10 } }
],
"Properties": {
"Application": "Sample"
}
}
}
不过,为了完整起见,为了访问定义的控制开关,您可以执行以下操作(请注意,这是一种黑客攻击!)。
编写一个接受LoggingLevelSwitches作为参数并将它们存储为static成员的配置方法(即可以出现在.WriteTo.xxx之后的扩展方法)。该配置方法将引入一个 dummy ILogEventSink,它什么都不做(为了性能,我们甚至可以指定 restrictedToMinimumLevel: LogEventLevel.Fatal,这样它几乎不会被调用)。然后从配置文件中调用该扩展方法(Serilog.Settings.Configuration 知道如何找到扩展方法并将参数传递给它们)和 voilà,您现在可以访问 @ 987654328@ 从您的代码切换!
这是它的样子:
public static class LevelSwitches
{
private static LoggingLevelSwitch _switch1;
private static LoggingLevelSwitch _switch2;
private static LoggingLevelSwitch _switch3;
public static LoggingLevelSwitch Switch1 => _switch1 ?? throw new InvalidOperationException("Switch1 not initialized !");
public static LoggingLevelSwitch Switch2 => _switch2 ?? throw new InvalidOperationException("Switch2 not initialized !");
public static LoggingLevelSwitch Switch3 => _switch3 ?? throw new InvalidOperationException("Switch3 not initialized !");
public static LoggerConfiguration CaptureSwitches(
this LoggerSinkConfiguration sinkConfig,
LoggingLevelSwitch switch1,
LoggingLevelSwitch switch2,
LoggingLevelSwitch switch3)
{
_switch1 = switch1;
_switch2 = switch2;
_switch3 = switch3;
return sinkConfig.Sink(
restrictedToMinimumLevel: LogEventLevel.Fatal,
logEventSink: new NullSink());
}
}
public sealed class NullSink : ILogEventSink
{
public void Emit(LogEvent logEvent)
{
// nothing here, that's a useles sink !
}
}
然后在你的 json 配置文件中:
"LevelSwitches": {
"$appLogLevel": "Debug",
"$netLogLevel": "Information",
"$sysLogLevel": "Error"
},
"MinimumLevel": {
"ControlledBy": "$appLogLevel",
"Override": {
"Microsoft": "$netLogLevel",
"System": "$sysLogLevel"
}
},
"WriteTo":[
{
"Name": CaptureSwitches"",
"Args": {
"switch1": "$appLogLevel",
"switch2": "$netLogLevel",
"switch3": "$sysLogLevel",
}
}
]
(您可能需要一个 "Using" 指令,其中包含包含 LevelSwitches 类的程序集名称)
从配置文件配置你的记录器
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
从那时起,您应该能够通过LevelSwitches.Switch1、LevelSwitches.Switch2 和LevelSwitches.Switch3 访问开关。