-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Deeper LoggingLevelSwitch support #7
Comments
Will there ever be more than one My theory is that for the majority of use cases, folks are looking for a Seq instance to communicate the logging levels, so they don't necessarily need to worry about the names, as they'd be assuming one switch. If that's truly the case, could the config be simplified to:
If this was provided, would it be possible to create a logging level switch and -- if using seq -- passing the log level switch into the seq wire-up? I wonder if that could be a good first step. Sure, it relies on conventions a bit, but if it covers a majority of use cases simply, it might be acceptable, especially as a first step. These are my thoughts as an end-user, but I recognize that implementation-wise, this might be slightly tricky, as I'm assuming a a tighter coupling between Serilog and Seq than may exist. |
Thanks for the feedback! I am also a bit unsure about the switch names, but doing it implicitly would still require some way of opting-in to using the switch with a sink. For example, the configuration below does use a switch, but doesn't let Seq control it: var sw = new LoggingLevelSwitch();
Log.Logger = new LoggerConfiguration()
.MinimumLevel.ControlledBy(sw)
.WriteTo.File(...)
.WriteTo.Seq(...)
.CreateLogger(); In this case, the switch controls the root logger and what effectively reaches the file, but this works independently of the level set in Seq. Having the explicit opt-in means the semantics are the same in code or in configuration - the presence of a switch wouldn't automatically mean that Seq (or another sink accepting a switch) will control it. |
Ahhh, I see -- what I was missing was the fact that there could be a generic switch that Seq didn't control, and that you'd specifically have to wire up a provider to use it (and that we might not want all providers extended to use it). |
In that case, I like your original suggestion, honestly. It's clean-ish, can be documented, and knowing how the switching works now, I could detect if something was wrong with that config. So no suggestions on my end from a client API perspective. |
Is this still on the plan? I'm not sure if this is granular enough, but I was looking for a way to have different log levels at the same server, so I could send a message saying "set customer X or component Y to Verbose for 30 minutes" and not have the entire cluster sending millions of messages to Seq unnecessarily. |
It would also be nice to set log level per source. |
@nvivo I don't believe this one will be granular enough for what you're after; you might be able to build what you're looking for in code, though, using @paulomorgado agreed; might need a separate ticket to track that one 👍 Cheers, |
I must say I would love to see that change come sooner rather than later :) It is THE reason why we haven't moved to remotely-controlled level. It is ok to have a bit of config in the code and a bit of config in the app settings, but I don't believe we can currently mix "seq configuration in the |
Just for the record, I did some tests using both LoggingLevelSwitch and LoggingFilterSwitch as recommended by @nblumhardt and although it's not ready out of the box, it seems doable. I didn't implement it in production yet, but nothing seems to prevent me from starting with a default and changing that later remotely. Which barriers did you find @tsimbalar? |
Thinking This would make the syntax: <!-- declare the switch -->
<add key="serilog:level-switch:Switch1" value="Debug" />
<!-- use it to control the root logger -->
<add key="serilog:minimum-level:controlled-by" value="Switch1" />
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<add key="serilog:write-to:Seq.serverUrl" value="http://localhost:5341" />
<!-- give the sink access to the switch -->
<add key="serilog:write-to:Seq.controlLevelSwitch" value="Switch1" /> Seems like there's heaps of support for this one - don't suppose anyone has the opportunity to try an implementation/PR? |
@nblumhardt oh, I thought it was already implemented somewhere, but just waiting for feedback about the the final syntax in the config file I would like to give it a try and implement it. The way I see it, because This would go into https://github.com/serilog/serilog/blob/6118a6f5958fc42b4d74e80236bc7151983ffdbf/src/Serilog/Settings/KeyValuePairs/KeyValuePairSettings.cs and matching tests in https://github.com/serilog/serilog/blob/e42245c0db0931e1fffdd72a0729361c60e877bc/test/Serilog.Tests/Settings/KeyValuePairSettingsTests.cs , is this correct ? |
@tsimbalar awesome! :-) Yes, that's correct. |
I'm currently working on it (here - work in progress :p). I am having second thoughts about the syntax for the app settings for the 1 - Variable DeclarationI'm wondering if the "variable declaration" syntax should not be more generic and allow to instantiate any type from its constructor, and then end up with something like <add key="serilog:variable:Switch1:LoggingSwitchLevel" value="Debug" /> instead of <add key="serilog:level-switch:Switch1" value="Debug" /> this would effectively say "create an instance of This would actually allow to also define variables of types other than 2 - Variable ReferenceI'm wondering if referencing a variable should be made a bit more explicit. What I mean is that the syntax should make it unambiguous whether the param we are passing is a value (like a For instance using a special symbol (like <add key="serilog:minimum-level:controlled-by" value="$Switch1" />
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<!-- give the sink access to the switch -->
<add key="serilog:write-to:Seq.controlLevelSwitch" value="$Switch1" /> this introduces a bit of complexity in the syntax for a newcomer but :
Possibly, the special symbol could also be used when declaring the variable as in : <add key="serilog:level-switch:$Switch1" value="Debug" /> OptionsI don't have particularly strong opinions on both topics, but I believe it would be good to choose a syntax that will not prevent us from extending in the future. To sum up, here are the possible syntax : Option 1 - original<!-- declare the switch -->
<add key="serilog:level-switch:Switch1" value="Debug" />
<!-- use it to control the root logger -->
<add key="serilog:minimum-level:controlled-by" value="Switch1" />
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<add key="serilog:write-to:Seq.serverUrl" value="http://localhost:5341" />
<!-- give the sink access to the switch -->
<add key="serilog:write-to:Seq.controlLevelSwitch" value="Switch1" /> Option 2 - explicit variable declaration and referencesfor instance using a <!-- declare the switch -->
<add key="serilog:level-switch:$Switch1" value="Debug" />
<!-- use it to control the root logger -->
<add key="serilog:minimum-level:controlled-by" value="$Switch1" />
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<add key="serilog:write-to:Seq.serverUrl" value="http://localhost:5341" />
<!-- give the sink access to the switch -->
<add key="serilog:write-to:Seq.controlLevelSwitch" value="$Switch1" /> (other possibilities : Option 3 - generic variable declaration<!-- declare the switch -->
<add key="serilog:variable:Switch1:LoggingLevelSwitch" value="Debug" />
<!-- use it to control the root logger -->
<add key="serilog:minimum-level:controlled-by" value="$Switch1" />
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<add key="serilog:write-to:Seq.serverUrl" value="http://localhost:5341" />
<!-- give the sink access to the switch -->
<add key="serilog:write-to:Seq.controlLevelSwitch" value="$Switch1" /> possible variations : I quite like Option 2 :) For now, I'm still implementing the original proposal by @nblumhardt |
Interesting! I think to do variables successfully, we'd need to go pretty deep so that we don't risk adding a general feature that only ever supports the one use case. I.e. we'd need to make sure values with It would also help to list other scenarios where variables would save the user enough effort that learning the variable system would pay off. My immediate reaction is - ah, that's elegant, we should definitely do variables - but, there's a lot of effort involved, so being realistic, I think we'd need to work on a pretty strong case/proposal to go forward with it. Thoughts? |
Agreed :) In doubt YAGNI I'll implement it according to the initial proposal, an maybe I'll post an issue to discuss variables in the more general serilog/serilog repo, to see if it triggers any interest or reveals any actual real-world use case. |
I've pushed the code. I would like to update the related documentation, but it turns out that doc is duplicated in :
It seems that one is a copy of the other, so should both be updated ? :) Also, the Seq sink's I'll start working on it |
It turns out <!-- declare the switch -->
<add key="serilog:level-switch:systemSwitch" value="Warning" />
<add key="serilog:minimum-level:override:System" value="systemSwitch" />
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<add key="serilog:write-to:Seq.serverUrl" value="http://localhost:5341" />
<!-- give the sink access to the switch -->
<add key="serilog:write-to:Seq.controlLevelSwitch" value="systemSwitch" /> I have added it and the correspounding tests in my PR serilog/serilog#1020 |
Closing this issue because it was implemented in serilog/serilog#1020 (and available in Serilog v2.6). The final syntax is : <!-- declare the switch -->
<add key="serilog:level-switch:$Switch1" value="Debug" />
<!-- use it to control the root logger -->
<add key="serilog:minimum-level:controlled-by" value="$Switch1" />
<add key="serilog:using:Seq" value="Serilog.Sinks.Seq" />
<add key="serilog:write-to:Seq.serverUrl" value="http://localhost:5341" />
<!-- give the sink access to the switch -->
<add key="serilog:write-to:Seq.controlLevelSwitch" value="$Switch1" /> |
If the root logger's minimum level is controlled by a
LoggingLevelSwitch
, sinks (the Seq sink in particular) can control this level in response to network messages from a remote server.It would be great to enable this capability when working with settings (both here and in the JSON variant).
The "declaration" of a switch would need to give it both a name and initial level; subsequent "uses" of the switch would just refer to its name.
E.g.:
This does feel somewhat ad-hoc - opinions welcome. I've held off suggesting this for a while because the usage is quite narrow for the amount of surface area, but I seem to have a question about it every week or two now so opening up the discussion :-)
The text was updated successfully, but these errors were encountered: