3

http経由でサーバーにログを送信するlog4jアペンダーを書いています。コードを素晴らしくシンプルに保つために、apache-commonsのHttpClientを使用したかったのです。

現在の問題は、HttpClientandCo.がlog4j自体を使用していることです。通常は良いことですが、log4jアペンダー実装内からそれらを呼び出すと、循環参照または無限ループが導入され、最終的にOutOfMemoryExceptionが発生します。

もちろん、サードパーティのライブラリがなくても好きなものを書くことができますが、この種の問題に対する既知の解決策があるかどうか疑問に思いました。

4

2 に答える 2

5

これは素晴らしい質問です!log4jがここであなたを助けようとしないのは残念です。しかし、私たちは悪意を持ってlog4jを使用してlog4jを修正することができます!重要な概念は診断コンテキストです:

private static final String IN_APPEND_KEY = MyAppender.class.getName() + ".inAppend";
public void append(LoggingEvent e) {
    if (e.getMDC(IN_APPEND_KEY) != null) return;
    MDC.put(IN_APPEND_KEY, this);
    try {
        <your code here>
    } finally {
        MDC.remove(IN_APPEND_KEY);
    }
}

基本的に、アペンダーの実行フローとともに「移動」するフラグを設定する必要があります。これは、少なくとも理論的には、診断コンテキストが行うこととまったく同じです。これはスレッドローカルであり、スレッド間で継承されます。注意深く書かれたコードは、メッセージキューなどの他の境界を越えてコンテキストを保持します。アペンダーはログメッセージをHTTPリクエストキューに入れ、キューは診断コンテキストを保存してリクエストが実行されたときにそれを復元し、HTTPライブラリはエラーをログに記録しますが、アペンダーはループを検出します。それはあなたが求めることができるほとんど最高のものです。

于 2011-07-29T00:25:18.313 に答える
0

Apache HttpClientのロガーがAppenderを使用するのはなぜですか?別のアペンダー、コンソールなどを提供します。

于 2011-06-12T11:21:47.553 に答える