4

一部のLog4jコンフィギュレーターには、スレッドを開始して構成に使用されるファイル (ファイルまたはファイル)を監視し、ファイルが変更された場合に再構成をトリガーconfigureAndWatch()するメソッドがあります。XMLproperties

Log4j ただし、デフォルトの初期化手順に依存している場合は、 を呼び出す機会がありませんconfigureAndWatch()。構成に使用されたファイルさえ知りません (ファイルでさえない可能性があります)。

デフォルトの初期化手順configureAndWatch()を使用しながら、その場でログ構成を変更できるスタイルの動作を取得する良い方法はありますか? 別のサーバーの URL はおそらく60 秒ごとに取得したいものではないため、構成 URL は最終的に監視可能なファイルに解決されると想定しています。

(別のスレッドのため、 Java EEconfigureAndWatch()環境ではメソッドが安全ではない ことがわかりました。一部のアプリサーバーには、構成ファイルを監視するための独自のメカニズムがあることがわかりましたが、現在取り組んでいるプログラムは実行されていませんJava EEで。)log4j

4

3 に答える 3

9

私は以前に答えのすべてを破棄し、あなたが何を望んでいるのかをよりよく理解するために最初からやり直しました。

次の段落では、log4j が log4j 構成ファイル名を決定するために使用する実際のシーケンスについて説明します。このコードは、これらの規則に従おうとします。

http://logging.apache.org/log4j/1.2/manual.html#defaultInit

使用する log4j 構成ファイルを決定し、見つかったファイルを使用して PropertyConfigurator をセットアップします。これは、ファイルがファイル システム上にある場合にのみ機能します。ファイルが jar 内またはリモート HTTP URL にある場合は機能しません。

    String prop = System.getProperty("log4j.configuration");
    if (prop == null) prop = "log4j.properties";
    URL log4jConfig = Loader.getResource(prop);
    if (log4jConfig.getProtocol().equalsIgnoreCase("file")) {
        PropertyConfigurator.configureAndWatch(log4jConfig.getFile().substring(1), 10000);
    }
    else {
        // cannot monitor if file changed because URL is not a file
    }
于 2012-08-30T15:26:25.327 に答える
2

ただし、Log4j のデフォルトの初期化手順に依存している場合、configureAndWatch() を呼び出す機会はありません。構成に使用されたファイルさえ知りません (ファイルでさえない可能性があります)。

[1][2]で既に回答したいくつかの関連する質問を投稿したので、この回答は他の人の説明に基づいています。繰り返しますが、私は AspectJ を使用しています。

サンプル アプリケーション クラス:

import org.apache.log4j.Logger;

public class Log4jDemo {
    private static Logger logger = Logger.getLogger("scrum-master.de");

    public static void main(String[] args) throws InterruptedException {
        while (true) {
            logger.info("Log message");
            Thread.sleep(2000);
        }
    }
}

デフォルトの URL をキャプチャし、次の URL に引き渡すアスペクトconfigureAndWatch:

import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.LogManager;
import org.apache.log4j.PropertyConfigurator;
import org.aspectj.lang.SoftException;

public aspect Log4jAspect {
    after(URL defaultURL) returning :
        within(LogManager) &&
        cflow(staticinitialization(LogManager)) &&
        call(* OptionConverter.selectAndConfigure(URL, ..)) &&
        args(defaultURL, ..)
    {
        try {
            PropertyConfigurator.configureAndWatch(new File(defaultURL.toURI()).getAbsolutePath(), 2000);
        } catch (URISyntaxException e) {
            throw new SoftException(e);
        }
    }
}

log4j.properties-Dlog4j.configDebug=trueで、出力チャネルをSystem.log(Eclipse コンソールの黒色) からSystem.err(赤色、ここでは表示されない) に前後に変更して、Eclipse でテストしたところ、うまく機能しました。ログ出力には、ファイルの変更が検出された後の再構成に関するデバッグ情報も表示されます。

log4j: Trying to find [log4j.xml] using context classloader sun.misc.Launcher$AppClassLoader@f4a24a.
log4j: Trying to find [log4j.xml] using sun.misc.Launcher$AppClassLoader@f4a24a class loader.
log4j: Trying to find [log4j.xml] using ClassLoader.getSystemResource().
log4j: Trying to find [log4j.properties] using context classloader sun.misc.Launcher$AppClassLoader@f4a24a.
log4j: Using URL [file:/C:/Dokumente%20und%20Einstellungen/Robin/Eigene%20Dateien/java-src/dummy2/bin/log4j.properties] for automatic log4j configuration.
log4j: Reading configuration from URL file:/C:/Dokumente%20und%20Einstellungen/Robin/Eigene%20Dateien/java-src/dummy2/bin/log4j.properties
log4j: Parsing for [root] with value=[debug, stdout].
log4j: Level token is [debug].
log4j: Category root set to DEBUG
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: Setting property [conversionPattern] to [%d{ABSOLUTE} %5p %c{1}:%L - %m%n].
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.err].
log4j: Parsed "stdout" options.
log4j: Finished configuring.
log4j: Parsing for [root] with value=[debug, stdout].
log4j: Level token is [debug].
log4j: Category root set to DEBUG
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: Setting property [conversionPattern] to [%d{ABSOLUTE} %5p %c{1}:%L - %m%n].
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.err].
log4j: Parsed "stdout" options.
log4j: Finished configuring.
17:48:20,944  INFO de:10 - Log message
17:48:22,944  INFO de:10 - Log message
17:48:24,944  INFO de:10 - Log message
17:48:26,944  INFO de:10 - Log message
log4j: Parsing for [root] with value=[debug, stdout].
log4j: Level token is [debug].
log4j: Category root set to DEBUG
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: Setting property [conversionPattern] to [%d{ABSOLUTE} %5p %c{1}:%L - %m%n].
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.out].
log4j: Parsed "stdout" options.
log4j: Finished configuring.
17:48:28,944  INFO de:10 - Log message
17:48:30,944  INFO de:10 - Log message
17:48:32,944  INFO de:10 - Log message
17:48:34,944  INFO de:10 - Log message
log4j: Parsing for [root] with value=[debug, stdout].
log4j: Level token is [debug].
log4j: Category root set to DEBUG
log4j: Parsing appender named "stdout".
log4j: Parsing layout options for "stdout".
log4j: Setting property [conversionPattern] to [%d{ABSOLUTE} %5p %c{1}:%L - %m%n].
log4j: End of parsing for "stdout".
log4j: Setting property [target] to [System.err].
log4j: Parsed "stdout" options.
log4j: Finished configuring.
17:48:36,944  INFO de:10 - Log message
17:48:38,944  INFO de:10 - Log message
于 2012-08-31T15:49:46.670 に答える
0

デフォルトのロガーとアペンダーを使用する前にこれを行いました。プロパティ ファイルの変更を監視するための別のハンドラを作成する必要があります。変更が発生したら、ロガーをリセットしてアペンダー設定を再度追加します。

/**
 * Setup log4j appender.
 */
public static void setupLog4jAppender(Class appender) {
    getLogger();

    String rootLogger=(String)props.get("log4j.rootLogger");
    rootLogger+=",appname";
    getProps().setProperty("log4j.rootLogger", rootLogger);

    getProps().put("log4j.appender.appname", appender.getName());  // Our custom appender
    getProps().put("log4j.appender.appname.layout", "org.apache.log4j.PatternLayout"); 
    //See: http://logging.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html
    getProps().put("log4j.appender.appname.layout.ConversionPattern", "%d{ABSOLUTE} %5p %c{1}:%L - %m%n");

    LogManager.resetConfiguration();
    PropertyConfigurator.configure(getProps());
}
于 2012-08-30T15:59:01.037 に答える