テックブログ

Java Agent入門:コードを変更せずトレースを取得する

Java Agent入門:コードを変更せずトレースを取得する

OpenTelemetry Java Agentは、Javaアプリケーションを起動するときに指定するJARです。対応するHTTPサーバーやクライアント、データベース用ライブラリなどへ実行時に計装を適用し、アプリのソースコードを変更せずにトレースのSpanを生成できます。ただし、Agentを付けるだけで全ての業務処理が見えるわけではなく、対応ライブラリ、出力先、実際のリクエスト発生を順に確認する必要があります。

1. Java Agentは何をするのか

起動時にJVMへ装着する

Java Agentは、Java仮想マシン(JVM)に読み込ませる追加のJARです。java -javaagent:/path/to/opentelemetry-javaagent.jar -jar app.jarのように、アプリのJARより前にオプションを指定します。

Agentは対応するライブラリの動作に計測処理を差し込みます。HTTP受信、外部へのHTTP呼び出し、DBアクセスなどからSpanが作られ、同一リクエストの処理を追えるようになります。アプリのビルドへ依存ライブラリを追加しなくても導入できるのが出発点です。

「ゼロコード」はソース変更なしで始められるという意味であり、設定や運用が不要という意味ではありません。AgentのJAR、JVM起動引数、サービス名、エクスポート先は環境ごとに管理します。

自動計装の範囲を見極める

自動計装されるのは、使用しているAgentのバージョンが対応するライブラリやフレームワークの処理です。たとえば対応するWebフレームワークで受信したHTTPリクエストには、サーバー側のSpanが作られます。

一方、注文の承認判定のようなアプリ固有の処理は、自動生成されたHTTP Spanだけでは独立した区間として現れないことがあります。その区間まで見たい場合はOpenTelemetry APIによる手動計装を検討します。

先に公式の対応ライブラリ一覧と利用中の実際の依存関係を照合しましょう。「Agentを導入したのに特定の処理が出ない」ときに、対応範囲なのか設定の問題なのかを切り分けやすくなります。

2. コンソールで最初のSpanを確認する

Agentとテスト対象を用意する

公式のGetting startedにある配布先からJava AgentのJARを取得し、使うバージョンを固定します。以下は/opt/otel/opentelemetry-javaagent.jarに置き、既存のHTTPエンドポイントを持つapp.jarを起動する例です。パスとエンドポイントは自分の環境へ置き換えてください。

JVMで動作するJava 8以上のアプリが対象です。アプリケーションサーバーに配備する場合は、そのサーバーのJVM起動引数へ-javaagentを加えます。JARを配置しただけでは計装は始まりません。

まずは外部の収集基盤を用意せず、Spanをコンソールへ出すと、Agentが作動するかを送信経路と分けて確かめられます。

Bashで起動してリクエストを送る

次はトレースだけをコンソールへ出力し、検証中はメトリクスとログのエクスポートを止める例です。OTEL_SERVICE_NAMEはデータを生成したサービスを識別します。

OTEL_SERVICE_NAME=order-api \
OTEL_TRACES_EXPORTER=console \
OTEL_METRICS_EXPORTER=none \
OTEL_LOGS_EXPORTER=none \
java -javaagent:/opt/otel/opentelemetry-javaagent.jar -jar app.jar

アプリが起動したら別の端末から、実在するHTTPエンドポイントへリクエストを送ります。たとえばcurl http://localhost:8080/healthは、そのパスが用意されている場合だけ使えます。Agentの起動メッセージだけで成功と判断せず、アプリ側の標準出力にSpanの内容が出ることを確認してください。

単発のアクセスでも、ライブラリや除外設定によって特定のエンドポイントにSpanが出ない場合があります。実際の業務APIを一度呼び出し、サービス名・Span名・Trace IDを確認するとより確実です。コンソール出力には機密情報が混じる可能性があるため、検証環境で使い、本番の長期運用には使いません。

3. 収集先へ送るときの設定

OTLP/HTTPの受信先を明示する

CollectorなどのOTLP/HTTP受信口をすでに用意している場合、コンソール出力から送信へ切り替えます。下記のlocalhostは、Javaプロセスと受信口が同じホストにあるときだけ有効です。

OTEL_SERVICE_NAME=order-api \
OTEL_TRACES_EXPORTER=otlp \
OTEL_METRICS_EXPORTER=none \
OTEL_LOGS_EXPORTER=none \
OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 \
java -javaagent:/opt/otel/opentelemetry-javaagent.jar -jar app.jar

4318は一般的なOTLP/HTTPのポートです。共通のOTEL_EXPORTER_OTLP_ENDPOINTにはベースURLを指定し、HTTP用のトレース送信パス/v1/tracesが組み立てられます。トレース専用のOTEL_EXPORTER_OTLP_TRACES_ENDPOINTを指定する場合は、通常そのURLへ/v1/tracesまで含めます。

受信先がなければ送信に失敗します。またコンテナ内のlocalhostはそのコンテナ自身を指すため、Collectorが別コンテナなら到達可能なサービス名とポートを指定します。受信側のプロトコルとTLS設定にも合わせてください。

Java Agent 2.xの既定値に注意する

Java Agent 2.0以降の既定のOTLPプロトコルはhttp/protobufです。一方、一般のJava SDKの自動設定ではgrpcが既定です。同じ環境変数を明示せずに実行すると、想定と違う受信口へ送ろうとすることがあります。

項目よく使う値確認すること
OTLP/HTTPhttp/protobuf・4318HTTP受信口が有効か
OTLP/gRPCgrpc・4317gRPC受信口が有効か
共通endpoint例:http://localhost:4318HTTPでは信号別パスが追加される

ポートは慣例であり、実際のCollectorやベンダーの設定が優先です。通信方式・endpoint・受信口をセットで確認すると、接続問題を小さく切り分けられます。

4. 取得結果をどう読むか

Spanが意味する境界を確認する

HTTPサーバーSpanが出れば、対応ライブラリの受信処理をAgentが捕捉できたと判断できます。同じ要求からHTTPクライアントやDBへの呼び出しが発生すれば、対応している範囲で子Spanも確認できます。

ただしSpanの数は処理の正しさの指標ではありません。呼び出しをしていないDBのSpanは出ませんし、未対応の独自処理が自動で詳細化されるわけでもありません。実際に発生させた処理と出力を照合します。

通常のアプリログへTrace IDが自動で入るかはログ実装と計装の対応によります。ログとの相関は別途、利用するロギングフレームワークの設定を確かめる必要があります。

読めない・出ないときの初手

まずJVM引数に-javaagentが入り、指定したJARが読み込めているかを確認します。続いてAgentの対応ライブラリ、リクエストの有無、エクスポーターの設定を順に見ます。これだけでも「生成されていない」と「生成されたが送れていない」を分けられます。

どうしても分からなければ検証環境でOTEL_JAVAAGENT_DEBUG=trueを使い、Agentの詳細ログを一時的に有効にします。ログ量が多いため常用は避け、調査後に戻してください。

本番導入前にはAgentがJVM内で消費するCPU・メモリ・ネットワークと、出力する属性の個人情報を確認します。検証で動いた設定をそのまま公開環境へ持ち込まず、通信の暗号化と送信先のアクセス制御も設計します。

5. 導入判断と実務の境界

既存アプリに段階的に入れる

既存のコードを改修しにくいJavaサービスでは、まず一つのサービスへAgentを適用し、HTTP受信Spanが見えるか確認するのが現実的です。サービス名を固定すれば、複数環境のデータを取り違えにくくなります。

Agentを導入してから観測基盤全体を一度に作る必要はありません。コンソール確認、閉じた検証環境のOTLP受信口、実運用のバックエンドという順で接続範囲を広げます。

その際はAgentと使用するフレームワークの互換性を固定バージョンで確認し、性能影響をトラフィック条件に合わせて測定します。

自動計装で足りない場面

外部呼び出しの時間だけでなく「在庫引当て」のような業務処理の区間を追いたい場合は、自動計装だけでは十分ではありません。OpenTelemetry APIを使い、その処理の開始・終了を明示的なSpanとして追加します。

一方、手動Spanを増やし過ぎると保存量と理解コストが増えます。障害対応で区別したい業務境界か、既存のHTTP・DB Spanだけでは原因を判断できないかを基準に追加してください。

まとめ

Java AgentはJVMの起動引数へJARを指定し、対応ライブラリの通信をコード変更なしでSpanにします。最初はconsoleで生成を確かめ、その後に通信方式と受信口を合わせてOTLPへ切り替えます。自動計装の対応範囲、業務処理の可視化、機密情報と性能影響は別に評価してください。

参考リンク