繁体   English   中英

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

[英]Change log4net logging level programmatically

这与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 一段时间了,但我只是没有看到它。 我错过了一些简单的东西吗?

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

这是对我有用的:

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

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

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

大件是:

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

非常感谢 Eddie 提出了很好的尖锐问题,这让我在 google 上找到了正确的词。 我永远不会独自解决这个问题。

(旁白:Repository、Hierarchy、Logger、RootLogger、LevelMap——我什至不知道有可能让一个日志库变得如此复杂。它有大约 20 层间接层,我确信这使它足够灵活,可以处理任何事情,但是几乎不可能做一些简单的事情,比如“不要记录超过阈值 X 的任何消息”。啊!)

有一个简单的方法来做到这一点:

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

可以在此处找到更多信息。

如果这对某人有用,以下是我在我的 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;
}

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

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

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

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

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

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

 LogManager.GlobalThreshold = LogLevel.Debug;

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

在我的情况下,我为不同的 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);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM