Log.ForContext<T> pattern might derive SilentLoggers
See original GitHub issueI had a discussion with an unhappy user the other day in IRC so i thought let’s make an issue 😉
It is a common pattern to use code like
private static readonly ILogger Logger = Log.ForContext<CurrentClass>();
Now due to various circumstances it is possible that Log.Logger
isn’t initialized yet at the time the static constructor runs which creates a ForContext
logger based on the SilentLogger
which will break all logging for that class.
The example i was given, was that with growing complexity of the application, a Sink was built that needed services from DI which delayed the initialization of the logger, at which point many classes might have been already touched, creating unuseable loggers. They had to figure this out the hard way when the application wasn’t logging everything that should have been anymore. Also having correct behavior dependent on the correct order of static constructors being run is very bad.
Another example was being able to reconfigure the logging pipeline at runtime.
The rest was a bit of angry rambling about having the audacity to do things differently (immutable loggers vs. mutable loggers / LogManager like in nlog / log4net) than in long established logging frameworks which caused trust issues.
I think this can be fixed by introducing a Log.GetGlobalLogger()
and a Log.ForGlobalContext
method. They would work similiar to the current ForContext
mechanism in creating a new Logger(…)
but with the ILogEventSink sink
parameter not being this
but a custom Sink that always calls through Log.Logger
.
Alternatively one could argue to change the static ILogger
returning methods on Log
to do this by default. Of course this would be a breaking change, but i hope no one is using the factory methods on Log
to then switch out Log.Logger
and expect the previously derived loggers to still use the previous Log.Logger
instance. If anyone would truely need that odd behavior, they could change the code to Log.Logger.ForContext
, etc.
Looking at the code, checking the level seems to be the biggest hurdle.
Issue Analytics
- State:
- Created 5 years ago
- Comments:9 (7 by maintainers)
Ah yes a very interesting idea, this moves the point were you do the switch one back and is opt-in able, i like it. You can start with
Log.Logger = new DynamicLogger(Logger.None)
and then later update it 👍 Much easier than what i had in mind.@Suchiman I’m on a bit of an issue-tracker-cleanout; I think this is interesting but I won’t have time to jump onto it personally. I’ll close the issue here, and if you (or someone following along) want to sketch out
DynamicLogger
at some point, just give the word and I’ll send what info I can 👍