【问题标题】:Change log4net logging level programmatically以编程方式更改 log4net 日志记录级别
【发布时间】:2010-10-17 11:41:47
【问题描述】:

这类似于650694,但那里没有接受任何答案,我根本无法得到任何这些建议,我怀疑我的情况可能略有不同。

我正在调用 log4net.Config.XmlConfigurator.Configure()。但是在程序中的那个点之后,我想将日志记录阈值更改为仅在运行时知道的值。

从另一个问题,我试过了:

((log4net.Repository.Hierarchy.Logger)mylogger.Logger).Level = log4net.Core.Level.Error;

和:

var appender = new log4net.Appender.ColoredConsoleAppender();
appender.Layout = new log4net.Layout.PatternLayout(@"%date %-5level %message%newline");
appender.Threshold = log4net.Core.Level.Error;
appender.ActivateOptions();
log4net.Config.BasicConfigurator.Configure(appender);

但似乎都没有任何效果:我仍然在控制台上看到 DEBUG 和 INFO 日志记录语句。

我的预感是我正在添加一个新的 appender,它对 XML 配置中声明的 appender 没有影响(告诉它打印 DEBUG 级别的消息),但我还没有任何证据。

我已经研究了一段时间的 log4net API,但我只是没有看到它。我缺少什么简单的东西吗?

【问题讨论】:

  • 将记录器的级别设置为“错误”应防止记录该记录器的任何调试或信息输出。您正在查看正在更改其日志记录级别的 Logger 的 DEBUG 和 INFO?
  • 这是一个好点:#1 可能只为一个记录器设置阈值。但#2 看起来应该是全球性的。
  • 是的 #1 仅设置您正在更改的单个 Logger 实例的阈值,以及层次结构中其下方没有明确设置级别的任何 Logger。
  • 我尝试使用 #1 遍历所有 log4net.LogManager.GetCurrentLoggers(),但这也无济于事。而且我仍然认为 #2 看起来应该是全球性的。
  • 您能否提供您的 log4net 配置,只需将其编辑到问题的末尾?

标签: c# logging log4net


【解决方案1】:

这里提供的这些解决方案都不适合我。它在运行时

没有改变

这对我有用:

((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root.Level = Level.Debug;
((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).RaiseConfigurationChanged(EventArgs.Empty);

您必须在更改其配置后调用 RaiseConfigurationChanged。

【讨论】:

  • 啊,我正在寻找的答案。我上次投票是在 4 年前 :)
  • 谢谢。这对我有用。更改 Hierarchy.Logger 级别不会:)
【解决方案2】:

终于找到了一个可行的解决方案,here

主要的部分是:

  • 需要在所有记录器上设置阈值,包括“无法按名称检索”根记录器
  • 需要从 Hierarchy 的 LevelMap 中获取关卡

非常感谢 Eddie 提出了非常有针对性的问题,这让我在 Google 上搜索到了正确的词语。我永远不会独自解决这个问题。

(旁白:Repository、Hierarchy、Logger、RootLogger、LevelMap——我什至不知道有可能让一个日志库变得如此复杂。它有大约 20 层间接,我敢肯定它足够灵活对于任何事情,但几乎不可能做一些简单的事情,比如“不要记录任何高于阈值 X 的消息”。哎呀!)

【讨论】:

  • 哇,这比我想象的要复杂!很好的链接。我对问题 650694 的回答在多个应用程序中对我有用,至少在 log4Net 1.2.10 中是这样。我不知道为什么它对你不起作用,但你发现的是彻底
  • 看来此时链接已失效。有没有人知道现在在哪里可以找到它,或者保存它以便可以在这里重新发布?
【解决方案3】:

有一个简单的方法:

LogManager.GetRepository().Threshold = Level.Info;

更多信息可以在here找到。

【讨论】:

  • 一旦配置了日志记录,这并没有改变日志记录级别。
  • 您还必须通过 RaiseConfigurationChanged 告诉它配置已更改。
【解决方案4】:

如果这适用于某人,以下是我在我的 Web 应用程序中实现通过 API 调用公开的切换级别端点的方式,因此我可以动态更改日志记录级别。

public HttpResponseMessage Post([FromBody] string logLevel)
{
    var newLevel = ToggleLogging(logLevel);

    // Create your own response here.
    return newLevel;
}

以及实际的实现t

private Level ToggleLogging(string logLevel)
{

    Level level = null;

    if (logLevel != null)
    {
        level = LogManager.GetRepository().LevelMap[logLevel];
    }


    if (level == null)
    {
        level = Level.Warn;
    }

    ILoggerRepository[] repositories = LogManager.GetAllRepositories();

    //Configure all loggers to be at the same level.
    foreach (ILoggerRepository repository in repositories)
    {
        repository.Threshold = level;
        Hierarchy hier = (Hierarchy)repository;
        ILogger[] loggers = hier.GetCurrentLoggers();
        foreach (ILogger logger in loggers)
        {
            ((Logger)logger).Level = level;
        }
    }

    //Configure the root logger.
    Hierarchy h = (Hierarchy)LogManager.GetRepository();
    Logger rootLogger = h.Root;
    rootLogger.Level = level;

    return level;
}

【讨论】:

    【解决方案5】:

    JeanT 的回答似乎不适用于最新版本的 log4net。

    我对其进行了调整以使其正常工作,这将更改为调试级别,但根据需要进行更改。

    foreach(var r in LogManager.GetAllRepositories()) { ((log4net.Repository.Hierarchy.Hierarchy)r).Root.Level = Level.Debug; ((log4net.Repository.Hierarchy.Hierarchy)r).RaiseConfigurationChanged(EventArgs.Empty); }

    【讨论】:

      【解决方案6】:

      尝试了所有这些答案,但都没有奏效。在调试器中,我可以看到所有记录器级别、根级别、阈值都按指示设置。尽管如此,我在登录的滚动文件中没有看到任何日志级别的变化。

      然后我发现在配置文件中appender元素也指定了一个阈值。因此,例如,当我想在 appender 设置为 Warn 时将级别更改为 Debug 时,该 appender 没有接收其他消息,因为它们低于阈值。所以我从 appender 配置中删除了阈值,只保留了级别配置。

        <root>
          <level value="Warn" />
          <appender-ref ref="RollingFile" />
        </root>
      

      然后我最终使用 Ken 的解决方案在运行时更改关卡。

      【讨论】:

        【解决方案7】:

        我一直在寻找相同的方法,发现最新的 NLog 版本 3.2.0.0 提供了以下选项来更改运行时的日志记录级别。

         LogManager.GlobalThreshold = LogLevel.Debug;
        

        我认为另一种方法可能是使用LogManager.Configuration 使用变量覆盖配置设置。

        【讨论】:

        • LogManager.GlobalThreshold 的默认值为 LogLevel.Trace
        【解决方案8】:

        在我的例子中,我为不同的 appender 设置了不同的默认级别来设置配置,但如果应用程序处于详细模式,我想覆盖它们。

        我使用了以下内容:

        var log4NetHierarchy = (log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository();
        foreach (var appender in log4NetHierarchy.GetAppenders())
        {
            if (appender is AppenderSkeleton appenderSkeleton)
            {
                appenderSkeleton.Threshold = Level.All;
            }
        }
        log4NetHierarchy.RaiseConfigurationChanged(EventArgs.Empty);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-19
          • 2022-01-26
          • 2012-09-20
          • 1970-01-01
          相关资源
          最近更新 更多