タイトル:ログトレース相関

より有用な追跡情報でログを有益なものにするには、コンテキストアウェア ロギングを適用するために、次のようにログトレース SDK をプロジェクトの依存関係に追加する必要があります:

<dependency>
<groupId>org.apache.skywalking</groupId>
<artifactId>apm-toolkit-log4j-2.x</artifactId>
<version>{project.release.version}</version>
</dependency>

ログにトレースIDを記録する

  • log4j2.xml に%traceId パターンを設定します。
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%traceId] %-5p %c{1}:%L - %m%n"/>
</Console>
</Appenders>
  • log4j2 AsyncRootをサポートする。追加の設定は必要ありません。以下の log4j2.xml を参照ください。詳細は Log4j2 Async Loggers を参照ください。
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%traceId] %-5p %c{1}:%L - %m%n"/>
</Console>
</Appenders>
<Loggers>
<AsyncRoot level="INFO">
<AppenderRef ref="Console"/>
</AsyncRoot>
</Loggers>
</Configuration>
  • log4j2 AsyncAppenderをサポート。追加の設定は必要ありません。以下のlog4j2.xmlを参照してください。

詳細については すべてのロガーを非同期にする を参照ください。

Log4j-2.9 以降では、クラスパスにおいて disruptor-3.3.4.jar 以上が必要です。Log4j-2.9 以前においては、disruptor-3.0.0.jar 以上が必要となります。この簡単な設定により、高度なパフォーマンスが可能となります。すべてのロガーを非同期にするには、disruptor jar をクラスパスに追加し、システムプロパティ log4j2.contextSelectororg.apache.logging.log4j.core.async.AsyncLoggerContextSelector に設定します。

<Configuration sta tus="WARN">
<Appenders>
<!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
<RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] [%traceId] %m %ex%n</Pattern>
</PatternLayout>
</RandomAccessFile>
</Appenders>
<Loggers>
<Root level="info" includeLocation="false">
<AppenderRef ref="RandomAccessFile"/>
</Root>
</Loggers>
</Configuration>

詳細は 同期と非同期が混在する場合 を参照ください。

Log4j-2.9 以降では、クラスパスにおいて disruptor-3.3.4.jar 以上が必要です。Log4j-2.9 以前では、disruptor-3.0.0.jar 以上が必要となります。システムプロパティ Log4jContextSelector を任意の値に設定する必要はありません。

<Configuration status="WARN">
<Appenders>
<!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
<RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
immediateFlush="false" append="false">
<PatternLayout>
<Pattern>%d %p %class{1.} [%t] [%traceId] %location %m %ex%n</Pattern>
</PatternLayout>
</RandomAccessFile>
</Appenders>
<Loggers>
<!-- pattern layout actually uses location, so we need to include it -->
<AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
<AppenderRef ref="RandomAccessFile"/>
</AsyncLogger>
<Root level="info" includeLocation="true">
<AppenderRef ref="RandomAccessFile"/>
</Root>
</Loggers>
</Configuration>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%traceId] %-5p %c{1}:%L - %m%n"/>
</Console>
<Async name="Async">
<AppenderRef ref="Console"/>
</Async>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Async"/>
</Root>
</Loggers>
</Configuration>
  • スカイウォーキング トレーサーをアクティブ化する際に -javaagent を使用すると、log4j2 が traceId を出力します。トレーサーがアクティブでない場合には、出力は TID: N/A となります。

gRPC レポート機能

gRPC レポートにより、収集したログを SkyWalking OAP サーバー、または SkyWalking Satellite サイドカーに転送されます。トレースID、セグメントID、スパンID は自動的にログに添付されます。ユーザーにてレイアウトを変更する必要はありません。

log4j2.xml に GRPCLogClientAppender を追加します。

<GRPCLogClientAppender name="grpc-log">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</GRPCLogClientAppender>
  • プラグイン設定を追加、もしくはデフォルト設定を使用します。
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:127.0.0.1}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}`

フォーマットされていないメッセージの送信

log4j 2.x gRPC レポーターにより、フォーマット済、またフォーマットされていないログの両方の送信することが可能です。デフォルトでは「フォーマット済のデータを送信する」設定になっていますが、エージェントの設定に以下を追加することで、その設定を無効化することができます:

plugin.toolkit.log.transmit_formatted=false

上記の結果、ログパターンには argument.0argument.1 等の追加のログタグが使用され、各ログ引数を表示することとなります。また、スロー可能なオブジェクトもログに記録されている場合にのみ、追加の例外タグも表示されることになります。

例:以下のコードを使用した際は、

log.info("{} {} {}", 1, 2, 3);

次のようになります:

{
"content": "{} {} {}",
"tags": [
{
"key": "argument.0",
"value": "1"
},
{
"key": "argument.1",
"value": "2"
},
{
"key": "argument.2",
"value": "3"
}
]
}
note

最初に Java エージェントをインストールする必要があります。詳細については Javaエージェント を参照ください