以编程方式更改.NET最小日志级别

3
使用Microsoft.Extensions.Logging,让我们初始化日志(F#):
let myLogger = 
    LoggerFactory
        .Create(fun builder -> 
            builder
                .AddSimpleConsole()
                .SetMinimumLevel(myLevel) 
                |> ignore)
        .CreateLogger()

我们如何随时更改最小级别?

我想要的东西就像这样简单:

myLogger.ChangeMinimumLevelTo(newLevel)

你不能:Logging API不包括在应用程序运行时更改日志级别的场景。特定提供程序可能允许此操作。您现在只使用了一个控制台提供程序,但如果您使用Serilog,您将能够使用动态级别切换。 - Panagiotis Kanavos
顺便提一下,你编写的代码看起来像是试图模拟Serilog和单例Logger实例。在.NET Core中,ILogger是特定于类别的。ILogger<T>是一个ILogger,其类别是类型T的名称。您应该只共享LoggerFactory并在需要时使用它来创建记录器。 - Panagiotis Kanavos
2个回答

4
有点肮脏,但它能用(使用Mono.Reflection获取后备字段)。
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)
    )

1
有点不干净 - Brian Berns
1
@BrianBerns 是的,我在little这个单词上打错了很多次 :) - Franco Tiveron

3

如果有其他需要此解决方案的人,但使用的是C#,这是@Franco Tiveron的解决方案翻译:

void changeMinimumLevel(ILogger logger, LogLevel level)
        {
            var _logger = logger
                    .GetType()
                    .GetField("_logger", BindingFlags.NonPublic | BindingFlags.Instance)
                    .GetValue(logger);
            var loggersArray =
                (Array)_logger
                    .GetType()
                    .GetProperty("MessageLoggers")
                    .GetValue(_logger);


            var enu = loggersArray.GetEnumerator();
            var i = 0;
            while (enu.MoveNext())
            {
                var x = enu.Current;
                var piMinLevel = x.GetType().GetProperty("MinLevel");
                var fiMinLevel = piMinLevel.GetBackingField();
                fiMinLevel.SetValue(x, level);
                loggersArray.SetValue(x, i);
                i++;
            }
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接