serilog-settings-configuration icon indicating copy to clipboard operation
serilog-settings-configuration copied to clipboard

How to configure from JSON, but then get a reference to the switch?

Open dazinator opened this issue 4 years ago • 8 comments

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?

dazinator avatar Feb 28 '20 14:02 dazinator

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.

nblumhardt avatar Mar 01 '20 23:03 nblumhardt

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 avatar Jun 13 '20 23:06 mrxrsd

@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.

dazinator avatar Jun 14 '20 00:06 dazinator

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

tsimbalar avatar Jun 14 '20 06:06 tsimbalar

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");

skomis-mm avatar Jun 14 '20 09:06 skomis-mm

By touching the core Seriloglibrary, we could also somehow expose the underlying LevelOverrideMap available in a Loggerbut 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 ConfigurationSettings Provider.

So for instance :


var logger = new LoggerConfiguration()
    .ReadFrom.Configuration(configuration, out var loadedConfiguration)
    .CreateLogger();

var switch = loadedConfiguration.GetLevelSwith("controlSwitch");

i.e. ReadFrom.Configurationtakes 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 avatar Jun 14 '20 12:06 tsimbalar

@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 .

skomis-mm avatar Jun 14 '20 13:06 skomis-mm

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.

gowon avatar Jul 24 '20 05:07 gowon