Search code examples
c#.netloggingf#microsoft.extensions.logging

Changing .NET Minimum Log Level programmatically


Using Microsoft.Extensions.Logging, let be the log initialization (F#):

let myLogger = 
    LoggerFactory
        .Create(fun builder -> 
            builder
                .AddSimpleConsole()
                .SetMinimumLevel(myLevel) 
                |> ignore)
        .CreateLogger()

How do we change that minimum level later, on demand?

I am looking to something as simple as:

myLogger.ChangeMinimumLevelTo(newLevel)

Solution

  • A little dirty, but it works (Mono.Reflection used for GetBackingField)

    let changeMinimumLevel (logger: ILogger) (level: LogLevel) = 
        let logger = logger :?> Microsoft.Extensions.Logging.Logger<obj>
        let _logger = 
            logger
                .GetType()
                .GetField("_logger", BindingFlags.NonPublic ||| BindingFlags.Instance)
                .GetValue(logger)
        let loggersArray = 
            _logger
                .GetType()
                .GetProperty("MessageLoggers")
                .GetValue(_logger) :?> Array
    
        let loggers = seq { 
            let enu = loggersArray.GetEnumerator()
            while enu.MoveNext() do enu.Current 
        }
    
        loggers |> Seq.iteri (fun i info ->            
            let piMinLevel = info.GetType().GetProperty("MinLevel")
            let fiMinLevel = piMinLevel.GetBackingField()
            fiMinLevel.SetValue(info, Nullable(level))
            loggersArray.SetValue(info, i)
        )