【问题标题】:Changing .NET Minimum Log Level programmatically以编程方式更改 .NET 最低日志级别
【发布时间】:2023-03-16 17:57:01
【问题描述】:

使用 Microsoft.Extensions.Logging,让我们做日志初始化 (F#):

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

我们以后如何根据需要更改最低水平?

我正在寻找一些简单的东西:

myLogger.ChangeMinimumLevelTo(newLevel)

【问题讨论】:

  • You can't: The Logging API doesn't include a scenario to change log levels while an app is running。特定的提供商可能会允许这样做。您现在只使用控制台提供程序,但如果您使用 Serilog,您将能够use dynamic level switches
  • 顺便说一句,您编写的代码看起来像是在尝试模拟 Serilog 和单例 Logger 实例。在 .NET Core 中,ILogger 特定于一个类别。 ILogger<T> 是一个ILogger,其类别是T 类型的名称。您应该只共享 LoggerFactory 并根据需要使用它来创建记录器

标签: c# .net logging f#


【解决方案1】:

有点脏,但它可以工作(Mono.Reflection 用于 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)
    )

【讨论】:

  • “有点脏”?
  • @BrianBerns 是的,我打了很多字:)
猜你喜欢
  • 1970-01-01
  • 2014-06-19
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-06
  • 2011-04-19
相关资源
最近更新 更多