web-dev-qa-db-ja.com

実行時にプログラムでLog4J2アペンダーを追加する方法

XML構成の仕様を使用して、プログラムでLog4J2アペンダーを追加することはできますか?

すべてをlog4j2.xmlで定義し、状況に応じてこのようなアペンダーを選択します(コンパイルできません)。

if (arg[0].equals("log") ) {
    Logger.getLogger("loggerNameFromXMLConfig").addAppender("appenderNameFromXMLConfig");
} else {
    //...
}
31
Brian Johnson

編集:log4j2の最新バージョンについては、代わりに https://stackoverflow.com/a/33472893/1899566 を参照してください。

私は彼らがあなたにこれを望んでいない印象を得るが、これは私のために働く:

if (arg[0].equals("log") ) {
  org.Apache.logging.log4j.Logger logger
    = org.Apache.logging.log4j.LogManager.getLogger("loggerNameFromXMLConfig");
  org.Apache.logging.log4j.core.Logger coreLogger
    = (org.Apache.logging.log4j.core.Logger)logger;
  org.Apache.logging.log4j.core.LoggerContext context
    = (org.Apache.logging.log4j.core.LoggerContext)coreLogger.getContext();
  org.Apache.logging.log4j.core.config.BaseConfiguration configuration
    = (org.Apache.logging.log4j.core.config.BaseConfiguration)context.getConfiguration();

  coreLogger.addAppender(configuration.getAppender("appenderNameFromXMLConfig"));
} else {
  //...
}
19
Robert Fleming

Log4j 2のプログラムによるより良い構成をサポートするために、多くの要求がありました。申し訳ありませんでした。 Log4j 2.4以降、APIがlog4j-coreに追加され、 プログラムによる構成 が容易になりました。

新しいConfigurationBuilder AP​​Iを使用すると、ユーザーはコンポーネントdefinitionsを構築できます。このAPIを使用すると、Log4jが内部でどのように機能するかについて多くの知識を必要とする実際の構成オブジェクト(LoggerConfigやFileAppenderなど)を直接操作する必要がありません。コンポーネント定義がConfigurationBuilderに追加され、すべての定義が収集されると、すべての実際の構成オブジェクト(ロガーやアペンダーなど)が構築されます。 Javaコードを記述していることを除いて、XML構成構文に少し似ています。

新しいConfigurationBuilder AP​​Iを使用すると、ユーザーコードで新しい構成を作成したり、既存の構成を完全に置き換えたりできます。ユースケースが異なり、Log4jの起動後に既存の構成を(置き換えではなく)プログラムで変更する場合は、実際の構成オブジェクトを操作する必要があります。その場合は、マニュアルの 初期化後にプログラムで現在の構成を変更する セクションを参照してください。

27
Remko Popma

上記で述べたように、私は https://logging.Apache.org/log4j/2.x/manual/customconfig.html#AddingToCurrent を取得できませんでした。それが期待されていました(私のアペンダーはメッセージをルーティングしません)。私は最終的に私のために働くパターンに出くわしました-実行時にアペンダーを追加し、そのアペンダーにログメッセージを実際にルーティングさせることができます。

Edit何もしていない混乱するコードをここから削除しました。..

    LoggerContext lc = (LoggerContext) LogManager.getContext(false);
    FileAppender fa = FileAppender.newBuilder().withName("mylogger").withAppend(false).withFileName(new File(outputDirectory, "ConsoleOutput.txt").toString())
            .withLayout(PatternLayout.newBuilder().withPattern("%-5p %d  [%t] %C{2} (%F:%L) - %m%n").build())
            .setConfiguration(lc.getConfiguration()).build();
    fa.start();
    lc.getConfiguration().addAppender(fa);
    lc.getRootLogger().addAppender(lc.getConfiguration().getAppender(fa.getName()));
    lc.updateLoggers();

私にとって重要な点は、addAppenderを呼び出してアペンダーを直接渡すことは機能しませんが、名前でアペンダーを返すように要求することです。それは理にかなっていない...しかし、仕事をして以来、私はとてもシンプルなものに時間を浪費するのにうんざりしている....

3
user2163960

有用かどうかはわかりません。現在の構成のaddLoggerAppenderメソッドを呼び出すことで、ロガーにアペンダーを追加できます。参照: http://logging.Apache.org/log4j/2.x/manual/architecture.html

2
Xiaoyuan

Log4j2構造内

        ---"Config"---
                Appenders
                        Appender(0)
                            Console
                        Appender(1)
                            File
                    LoggerConfigs
                        -- LoggerConfig(0) 
                        -- LoggerConfig(1)
                        -- LoggerConfig(2)

        ----"LoggerConfig"----
                - AppenderRefs
                    -- AppenderRef(0)
                        -- Name Console
                        -- Level : DEBUG
                - Appenders
                    -- Appender(0)
                        -- Name Console
                        -- Level : DEBUG
                - Level -- ALL

loggerConfig.getAppenders()->「Config」のアペンダーを返します。私にとってこれはバグです

loggerConfig.getAppenderRefs()->はうまく機能しています!!