以编程方式更改log4net日志记录级别

时间:2009-04-03 22:18:12

标签: c# logging log4net

这与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一段时间了,我只是没有看到它。有什么简单的我不见了吗?

8 个答案:

答案 0 :(得分:76)

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

中更改

这对我有用:

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

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

答案 1 :(得分:22)

最后找到了一个有效的解决方案,here

重要的是:

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

非常感谢Eddie提出好的尖锐问题,这让我想起了正确的话。我再也不会想到这一点。

(旁白:存储库,层次结构,记录器,RootLogger,LevelMap - 我不知道甚至可以将日志库变得复杂。它有大约20层间接,我确信它足够灵活对于任何事情,但几乎不可能做一些简单的事情,比如“不要记录超过阈值X的任何消息”。哇!)

答案 2 :(得分:8)

有一种简单的方法:

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

可以找到更多信息here

答案 3 :(得分:1)

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

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

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

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

答案 4 :(得分:0)

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

 LogManager.GlobalThreshold = LogLevel.Debug;

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

答案 5 :(得分:0)

如果这对某人有用,这就是我在Web应用程序中实现通过API调用公开的切换级别终结点的方式,因此我可以即时更改日志记录级别。

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

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

以及实际的实现方式

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;
}

答案 6 :(得分:0)

在我的情况下,我为不同的附加程序设置了不同的默认级别,但要在应用程序处于详细模式下覆盖它们。

我使用了以下内容:

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);

答案 7 :(得分:0)

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

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

xtick.major.width