web-dev-qa-db-ja.com

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を掘り下げてきましたが、見ていません。私が見逃している簡単なものはありますか?

57
Ken

ここにあるこれらのソリューションはどれも私にとってはうまくいきませんでした。 runtimeで変化していませんでした

ここに私のために働いたものがあります:

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

構成を変更した後、RaiseConfigurationChangedを呼び出す必要があります。

82
JeanT

最後に、有効なソリューション here が見つかりました。

大きな部分は次のとおりです。

  • 「名前で取得できない」ルートロガーを含む、すべてのロガーにしきい値を設定する必要があります
  • 階層のLevelMapからレベルを取得する必要があります

適切な言葉をグーグルで検索できるようになった、先の尖った質問をしてくれたEddieに感謝します。これを一人で理解することはなかったでしょう。

(脇:リポジトリ、階層、ロガー、RootLogger、LevelMap-ロギングライブラリをこのように複雑にすることさえ考えられませんでした。約20層のインダイレクションがあります。しかし、「しきい値Xを超えるメッセージをログに記録しない」などの簡単なことはほぼ不可能になります。

22
Ken

簡単な方法があります:

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

詳細については、 こちら をご覧ください。

8
Alex

これらすべての答えを試してみましたが、どれも機能しませんでした。デバッガーでは、すべてのロガーレベル、ルートレベル、しきい値が指示どおりに設定されていることがわかりました。それにもかかわらず、ログを記録しているローリングファイルにログレベルの変化は見られませんでした。

次に、構成ファイルでappender要素もしきい値を指定していることがわかりました。したがって、たとえば、アペンダーが警告に設定されているときにレベルをデバッグに変更したい場合、そのアペンダーはしきい値を下回っていたため、追加のメッセージをピックアップしませんでした。そのため、アペンダー構成からしきい値を削除し、レベル構成のみを保持しました。

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

その後、Kenのソリューションを使用して、実行時にレベルを変更しました。

1
Mark Meyerovich

これが誰かのために機能する場合、API呼び出しを介して公開されるトグルレベルのエンドポイントをWebアプリケーションに実装する方法を次に示します。そのため、ロギングレベルを即座に変更できます。

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

私は同じアプローチを探していましたが、最新のNLogバージョン3.2.0.0では、実行時にロギングレベルを変更するオプションが以下にあることがわかりました。

 LogManager.GlobalThreshold = LogLevel.Debug;

別のアプローチはLogManager.Configuration変数を使用して構成設定を上書きします。

0
seUser

私の場合、構成を設定するアペンダーごとに異なるデフォルトレベルがありましたが、アプリケーションが冗長モードの場合はそれらをオーバーライドしたかったのです。

私は次を使用しました:

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);
0
Jonathan Sayce