1.6.x ロギング・エージェント をカスタマイズし、オーケストレーテッド環境の Log4j で Java アプリケーションのカスタムマルチライン解析をサポートする

このチュートリアルでは、 Java アプリケーションの IBM® Cloud Logs ロギング・エージェント 複数行ログ処理を設定する方法を示します。 Log4j ロギングフレームワークを使います。 このコンフィギュレーションは、例えば IBM Cloud Kubernetes Service や Red Hat OpenShift on IBM Cloud のようなオーケストレーション環境向けで、 Helm を使用します。 この設定により、スタックトレースとマルチラインログが IBM Cloud Logs で正しくグループ化される。

このチュートリアルには IBM Cloud Logs ロギング・エージェント 1.6.0 以降が必要です。

開始前に

このチュートリアルを使い始める前に、 ロギング・エージェント とマルチラインの概念を理解するために、以下の情報を確認してください。

また、このチュートリアルは、あなたが持っていることを前提としている:

  • IBM Cloud Logs インスタンスのプロビジョニングとコンフィギュレーション。

  • ロギング・エージェント オーケストレーションされた環境で展開される。

サンプル Log4j コンフィギュレーション

あなたの Java アプリケーションの Log4j コンソール(stdout )にログを記録するのが以下のようなものだと仮定しよう:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

このコンフィギュレーションはログをフォーマットで出力する: yyyy-MM-dd HH:mm:ss.SSS [thread] LEVEL logger - message という形式でログを出力する。 スタック・トレースのような複数行のメッセージは、タイムスタンプの接頭辞を付けずに、それ以降の行に表示される。 以下に例を示します。

2025-07-28 10:32:15.423 [main] INFO com.example.logging.Main - Application starting up
2025-07-28 10:32:16.191 [main] INFO com.example.logging.Main - This is an info message
2025-07-18 10:32:18.801 [main] ERROR com.example.logging.Main - This is an error message
java.lang.NullPointerException: null
at com.example.logging.Main.lambda$main$3(Main.java:30) ~[java-log4j-1.0.0.jar:?]
at spark.RouteImpl$1.handle(RouteImpl.java:72) ~[java-log4j-1.0.0.jar:?]
at spark.http.matching.Routes.execute(Routes.java:61) ~[java-log4j-1.0.0.jar:?]
at spark.http.matching.MatcherFilter.doFilter(MatcherFilter.java:134) ~[java-log4j-1.0.0.jar:?]
at spark.embeddedserver.jetty.JettyHandler.doHandle(JettyHandler.java:50) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1584) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.Server.handle(Server.java:501) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:383) ~[java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:556) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:375) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:273) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:806) [java-log4j-1.0.0.jar:?]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:938) [java-log4j-1.0.0.jar:?]
at java.lang.Thread.run(Unknown Source) [?:?]

を使った複数行解析の設定 Helm

Helm を使って ロギング・エージェント をデプロイする場合、 Helm values.yaml ファイルでマルチライン解析を設定することができる。

複数行の解析を有効にする

マルチライン処理を有効にするには、 values.yaml ファイルで enableMultilinetrue に設定します:

enableMultiline: true

マルチライン・パーサーの定義

values.yaml ファイルの additionalMultilineParsers セクションの下にカスタム・マルチライン・パーサーを追加する。

適切なログのグループ化を確実にするために、 log4j.xml ファイルで定義されたパターンが、マルチラインパーサーの正規表現と一致することが重要である。

例:

additionalMultilineParsers:
  - name: multiline-java-example
    type: regex
    flush_timeout: 500
    rules:
      - state: start_state
        regex: '/^(\d+-\d+-\d+ \d+:\d+:\d+\.\d+)(.*)$/'
        next_state: cont
      - state: cont
        regex: '/^(?!\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}).*$/'
        next_state: cont

正規表現は、新しいログ行がそれぞれ yyyy-MM-dd HH:mm:ss.SSS. 最初のルールは、タイムスタンプを持つスタートラインをキャプチャし、継続状態に移行する。 2番目のルールは、タイムスタンプで始まらない行にマッチする。

このアプローチは、 Java スタックトレースや例外などの複数行のログ行を、 IBM Cloud Logs に転送する前に1つのログエントリとしてグループ化する方法を示す単なる例です。 同じことを達成するにも、さまざまな方法がある。

マルチライン・プリプロセッサの定義

ログにパーサーを適用するために、 multilinePreprocessor セクションでプリプロセッサを設定する。

以下に例を示します。

multilinePreprocessor:
  - name: multiline
    multiline.parser: multiline-java-example
    multiline.key_content: log

変更を適用します。

以前のバージョンの ロギング・エージェント をインストールしており、クラスタ内で config マップを直接変更してエージェントの設定を更新した場合は、 helm upgrade コマンドを実行する前に、クラスタから config マップのコピーを作成してください。 ロギング・エージェント が更新されると、コンフィグマップに加えられた変更は上書きされる。

values.yaml ファイルを更新したら、デプロイメントで以下を実行して変更を適用します。 これで必要なコンフィギュレーションが再生成される。

helm upgrade

マルチラインログの確認

IBM Cloud Logs インスタンスにアクセスし、マルチラインエントリ(スタックトレースなど)が正しくグループ化されていることを確認してください。

  1. IBM Cloud Logs インスタンスにアクセスします。

  2. Logs Explore logsアイコン ビューを使用して、マルチラインエントリーが正しくグループ化されていることを確認します。