serilog-settings-configuration
serilog-settings-configuration copied to clipboard
How to configure from JSON, but then get a reference to the switch?
I'd like to use the json configuration to configure the seq sink. However I need access to the switch in code, because I want to allow this to be changed at runtime in code. How should I go about that?
Hi Darrell; this isn't possible right now, I think a solution would need to be baked into one of the Serilog.Settings.x packages, but we haven't got a workable API/proposal figured out (input and ideas welcome). I'll transfer this to the .Configuration repo, which is the more active one, currently.
I was trying to do this just right now. I've tought it will be possible like we pass formatters to json using static variables.
It will be a great feature!
{
"Serilog": {
"LevelSwitches": {
"$controlSwitch": "Verbose",
"exposeAt": "Sample.Switchlevel, Sample"
},
"WriteTo": [
{
"Name": "Seq",
"Args": {
"serverUrl": "http://localhost:5341",
"apiKey": "yeEZyL3SMcxEKUijBjN",
"controlLevelSwitch": "$controlSwitch"
}
}
]
}
}
@mrxrsd your proposal couples the json a bit too tightly to code structure for my level of comfort. Id prefer just naming the switch in the json, and then serilog exposing some dictionary at runtime to retrieve named switches. That way, refactoring code wouldn't break anything.
FYI, you should be able to use the "hack" proposed in this issue until there's an official way to do it :
https://github.com/serilog/serilog-settings-appsettings/issues/24#issuecomment-379396610
Would be great to add support for this . Without upstream support we could solve it with adding additional parameter or new overloads to ReadFrom.Configuration
with switch collector type:
var switchCollector = new LoggerSwitchCollector();
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration, switchCollector)
.CreateLogger();
var controlSwitch = switchCollector.GetLevelSwitch("controlSwitch");
By touching the core Serilog
library, we could also somehow expose the underlying LevelOverrideMap
available in a Logger
but this seems like leaking internals a bit too much...
@skomis-mm I like your suggestion, and wonder, if we could/should even make it a more generic way to "introspect" on the results of configuring through the Configuration
Settings Provider.
So for instance :
var logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration, out var loadedConfiguration)
.CreateLogger();
var switch = loadedConfiguration.GetLevelSwith("controlSwitch");
i.e. ReadFrom.Configuration
takes a second optional argument that returns some sort of object that contains information about the configuration that we loaded.
For now, it would just allow to look up switches, but we could extend it later to have, possibly, diagnostics about the process of loading the configuration or other useful information.
@tsimbalar some generic type was in my mind too. 👍
out
modifier seems good addition. No need to import additional namespace for the type in case of inline initialization .
I wanted to share my solution for this problem when I hit it a few months ago:
- Create a dummy sink that takes the switch and a label
- The LoggerSinkConfiguration extension method adds the dynamically generated switches and labels as key-value-pairs to a singleton collection that can be refererenced outside of the logger.
- (optional) Add an extension to attach the singleton collection to the generic host DI
I wrapped it into a package here: https://github.com/gowon/Serilog.Sinks.DynamicSwitch. It feels a bit hacky, and I wish I could make it less verbose on the json side, but it gets the job done until there's some first-class interface for reaching those switches.