Log4j 2を使ったプログラムによる設定

Log4j 2を使用したプログラム構成

1. 前書き

このチュートリアルでは、Apache Log4j2をプログラムで構成するさまざまな方法を見ていきます。

2. 初期設定

Log4j 2の使用を開始するには、log4j-corelog4j-slf4j-implの依存関係をpom.xmlに含める必要があります。


    org.apache.logging.log4j
    log4j-core
    2.11.0


    org.apache.logging.log4j
    log4j-slf4j-impl
    2.11.0

3. ConfigurationBuilder

Mavenを構成したら、ConfigurationBuilderを作成する必要があります。これは、appenders, filters, layouts,loggers.を構成できるクラスです。

Log4j 2は、ConfigurationBuilderを取得するいくつかの方法を提供します。

最も直接的な方法から始めましょう:

ConfigurationBuilder builder
 = ConfigurationBuilderFactory.newConfigurationBuilder();

また、コンポーネントの構成を開始するために、ConfigurationBuilderには、各コンポーネントに対応するnewAppender newLayoutなどのnewメソッドが装備されています。

一部のコンポーネントには、FileAppenderConsoleAppender,などの異なるサブタイプがあり、これらはAPIではpluginsと呼ばれます。

3.1. アペンダーの構成

appenderを構成して、各ログ行の送信先をbuilderに伝えましょう。

AppenderComponentBuilder console
  = builder.newAppender("stdout", "Console");

builder.add(console);

AppenderComponentBuilder file
  = builder.newAppender("log", "File");
file.addAttribute("fileName", "target/logging.log");

builder.add(file);

ほとんどのnewメソッドはこれをサポートしていませんが、newAppender(name, plugin)を使用すると、アペンダーに名前を付けることができます。これは後で重要になることがわかります。 これらのアペンダーは、stdoutlog, と呼んでいますが、名前を付けることもできます。

また、使用するplugin (または、より簡単に言えば、どの種類のアペンダー)をbuilderに指示しました。 ConsoleFileは、それぞれ標準出力とファイルシステムへの書き込み用のLog4j2のアペンダーを参照します。

Log4j 2 supports several appendersですが、configuring them using Java can be a bit tricky since AppenderComponentBuilder is a generic class for all appender types.

これにより、setFileNameaddTriggeringPolicyの代わりに、addAttributeaddComponent のようなメソッドが使用されます。

AppenderComponentBuilder rollingFile
  = builder.newAppender("rolling", "RollingFile");
rollingFile.addAttribute("fileName", "rolling.log");
rollingFile.addAttribute("filePattern", "rolling-%d{MM-dd-yy}.log.gz");
rollingFile.addComponent(triggeringPolicies);

builder.add(rollingFile);

そして最後に、don’t forget to call builder.add to append it to the main configuration!

3.2. フィルタの構成

各アペンダーにフィルターを追加して、各ログ行で追加するかどうかを決定できます。

コンソールアペンダーのMarkerFilterプラグインを使用してみましょう。

FilterComponentBuilder flow = builder.newFilter(
  "MarkerFilter",
  Filter.Result.ACCEPT,
  Filter.Result.DENY);
flow.addAttribute("marker", "FLOW");

console.add(flow);

このnewメソッドではフィルターに名前を付けることはできませんが、フィルターが成功または失敗した場合の対処方法を指定するように求められることに注意してください。

この場合、MarkerFilterが合格すると、ACCEPTがログラインになることを明記して、シンプルにしています。 それ以外の場合は、DENY it。

この場合、これをbuilderに追加するのではなく、このフィルターを使用するアペンダーに追加することに注意してください。

3.3. レイアウトの構成

次に、各ログ行のレイアウトを定義しましょう。 この場合、PatternLayoutプラグインを使用します。

LayoutComponentBuilder standard
  = builder.newLayout("PatternLayout");
standard.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable");

console.add(standard);
file.add(standard);
rolling.add(standard);

繰り返しになりますが、これらをbuilderに直接追加するのではなく、適切なアペンダーに直接追加しました。

3.4. ルートロガーの構成

ログの送信先がわかったので、各ログをどの宛先に送信するかを構成します。

ルートロガーは最高のロガーであり、JavaのObjectのようなものです。 このロガーは、オーバーライドされない限り、デフォルトで使用されます。

それでは、ルートロガーを使用して、デフォルトのログレベルをERRORに設定し、デフォルトのアペンダーを上からstdoutアペンダーに設定しましょう。

RootLoggerComponentBuilder rootLogger
  = builder.newRootLogger(Level.ERROR);
rootLogger.add(builder.newAppenderRef("stdout"));

builder.add(rootLogger);

ロガーを特定のアペンダーに向けるために、ロガーにビルダーのインスタンスを提供しません。 代わりに、we refer to it by the name that we gave it earlier.

3.5. 追加のロガーの構成

子ロガーを使用して、特定のパッケージまたはロガー名をターゲットにすることができます。

アプリケーションにcomパッケージのロガーを追加し、ログレベルをDEBUGに設定して、それらをlog appenderに移動させましょう。

LoggerComponentBuilder logger = builder.newLogger("com", Level.DEBUG);
logger.add(builder.newAppenderRef("log"));
logger.addAttribute("additivity", false);

builder.add(logger);

ロガーでadditivity を設定できることに注意してください。これは、このロガーがその祖先からログレベルやアペンダータイプなどのプロパティを継承する必要があるかどうかを示します。

3.6. その他のコンポーネントの構成

すべてのコンポーネントがConfigurationBuilderに専用のnewメソッドを持っているわけではありません。

したがって、その場合、newComponent.と呼びます。

たとえば、TriggeringPolicyComponentBuilderがないため、ローリングファイルアペンダーのトリガーポリシーを指定するなどの目的でnewComponent を使用する必要があります。

ComponentBuilder triggeringPolicies = builder.newComponent("Policies")
  .addComponent(builder.newComponent("CronTriggeringPolicy")
    .addAttribute("schedule", "0 0 0 * * ?"))
  .addComponent(builder.newComponent("SizeBasedTriggeringPolicy")
    .addAttribute("size", "100M"));

rolling.addComponent(triggeringPolicies);

3.7. 同等のXML

ConfigurationBuilder は、同等のXMLを出力するための便利なメソッドを備えています。

builder.writeXMLConfiguration(System.out);

上記の行を実行すると出力されます:



   
      
         
         
      
      
         
         
            
            
         
      
      
         
      
   
   
      
         
      
      
         
      
   

これは、構成を再確認したい場合や、構成をファイルシステムなどに保持したい場合に便利です。

3.8. すべてを一緒に入れて

完全に構成されたので、Log4j2に構成を使用するように指示しましょう。

Configurator.initialize(builder.build());

これが呼び出された後、future calls to Log4j 2 will use our configuration

これは、LogManager.getLoggerを呼び出す前に、Configurator.initializeを呼び出す必要があることを意味します。

4. ConfigurationFactory

ConfigurationBuilderを取得して適用する方法が1つあるので、もう1つ見てみましょう。

public class CustomConfigFactory
  extends ConfigurationFactory {

    public Configuration createConfiguration(
      LoggerContext context,
      ConfigurationSource src) {

        ConfigurationBuilder builder = super
          .newConfigurationBuilder();

        // ... configure appenders, filters, etc.

        return builder.build();
    }

    public String[] getSupportedTypes() {
        return new String[] { "*" };
    }
}

この場合、ConfigurationBuilderFactoryを使用する代わりに、Configurationのインスタンスを作成することを目的とした抽象クラスであるConfigurationFactoryをサブクラス化しました。

次に、最初に行ったようにConfigurator.initializeを呼び出す代わりに、Log4j2に新しい構成ファクトリについて通知する必要があります。

これを行うには3つの方法があります。

  • 静的初期化

  • ランタイムプロパティ、または

  • @Plugin annotation

4.1. 静的初期化を使用する

Log4j 2は、静的初期化中のsetConfigurationFactory の呼び出しをサポートしています。

static {
    ConfigurationFactory custom = new CustomConfigFactory();
    ConfigurationFactory.setConfigurationFactory(custom);
}

このアプローチには、前回見たアプローチと同じ制限があります。つまり、before any calls to LogManager.getLogger.を呼び出す必要があります。

4.2. ランタイムプロパティを使用する

Java起動コマンドにアクセスできる場合、Log4j 2は、-Dパラメータを介して使用するConfigurationFactory の指定もサポートします。

-Dlog4j2.configurationFactory=com.example.log4j2.CustomConfigFactory

このアプローチの主な利点は、最初の2つのアプローチのように、初期化の順序について心配する必要がないことです。

4.3. @Plugin Annotationを使用する

最後に、-Dを追加してJava起動コマンドをいじりたくない状況では、CustomConfigurationFactoryにLog4j 2@Plugin annotationを付けるだけです。

@Plugin(
  name = "CustomConfigurationFactory",
  category = ConfigurationFactory.CATEGORY)
@Order(50)
public class CustomConfigFactory
  extends ConfigurationFactory {

  // ... rest of implementation
}

Log4j 2は、@Plugin annotationを持つクラスのクラスパスをスキャンし、ConfigurationFactory categoryでこのクラスを見つけるとそれを使用します。

4.4. 静的構成との組み合わせ

ConfigurationFactory拡張子を使用するもう1つの利点は、カスタム構成をXMLなどの他の構成ソースと簡単に組み合わせることができることです。

public Configuration createConfiguration(
  LoggerContext context,
  ConfigurationSource src) {
    return new WithXmlConfiguration(context, src);
}

sourceパラメータは、Log4j2が検出する静的XMLまたはJSON構成ファイルを表します。

その構成ファイルを取得して、XmlConfigurationのカスタム実装に送信し、必要なオーバーライド構成を配置できます。

public class WithXmlConfiguration extends XmlConfiguration {

    @Override
    protected void doConfigure() {
        super.doConfigure(); // parse xml document

        // ... add our custom configuration
    }
}

5. 結論

この記事では、Log4j 2で利用可能な新しいConfigurationBuilderAPIの使用方法について説明しました。

また、より高度なユースケースのために、ConfigurationFactory inとConfigurationBuilderの組み合わせをカスタマイズすることも検討しました。

私の完全な例over on GitHubをチェックすることを忘れないでください。