簡體   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