Java トレース SDK

Instana Java Trace SDK ( github ) を使用することで、 Instana がまだ認識していないエントリとエグジットを手動で計測したり、カスタムコードの注目すべきセクションをマークアップしたりすることが可能です。 また、バイナリー・プロトコル間のカスタム相関を作成したり、(関連情報の抽出のために) カスタム定義のキーと値ペアをスパンに追加したりすることもできます。

構成

設定ベースの Java トレースSDKを使用するには、 Java トレースSDKの有効化の手順に従い、 Java トレースSDKを有効にする必要があります。

instana-java-sdk の使用

Java トレースSDKでは、アプリケーションにjarファイルを追加する必要があります。 この jar ファイルには、Instana で処理する必要があるコード・セクションのマークアップに使用される注釈とヘルパー・クラスが含まれています。 Maven を使用すると、以下を使用して依存関係を簡単に追加できます。

<dependency>
  <groupId>com.instana</groupId>
  <artifactId>instana-java-sdk</artifactId>
  <version>1.2.0</version>
</dependency>
 

instana-java-sdk 成果物は、デフォルトの Maven 中央リポジトリーから入手できます。

エージェントが JVM を監視していない場合(このライブラリを含み、注釈でマークされたセクションを持つ)、それらはNo-Opとして動作する。 注釈の使用は安全です。注釈は、JVM をモニターしているエージェントがない限り、何の影響も及ぼしません。 Instana エージェントが実際に注釈を利用できるようにするには、それらの注釈を含む Java パッケージ名をエージェントに通知する必要があります。 これは、アノテーションのスキャンが負荷の高い処理であり、大規模なアプリケーションの完全なクラスパスをスキャンするには長い時間がかかるためです。

必要な configuration.yaml セクションは次のようになります:

# Java Tracing
com.instana.plugin.javatrace:
  instrumentation:
    # By default no packages are scanned for SDK annotations.
    sdk:
      packages:
        - 'com.mycompany.backend'
        - 'com.mycompany.frontend'
 

パッケージは再帰的にスキャンされます。 このため、com.mycompany.backend で注釈がスキャンされるように構成されている場合、com.mycompany.backend.impl および他のサブパッケージもスキャンされます。

中間スパンへのマーク付け

中間 (Intermediate) スパン内のメソッドにマークを付けるには、以下の注釈を追加します。

@Span(value = "custom-tcp-server")

中間スパンは SDK スパンのデフォルト・タイプで、特に指定がない場合に使用されます。 この種のスパンでは、アプリケーション内の「対象の」メソッドに、可視性を高めるためのマークが付けられます。 実際のプロファイラ(例:当社の Instana AutoProfile™ )の代わりにはならない点にご留意ください。

エントリー・スパンへのマーク付け

エントリ スパン内のメソッドをマークするには、 次の例に示すように、以下の注釈を追加するだけです:

@Span(type = Type.ENTRY, value = "custom-tcp-server")

Instana がこのメソッドを入力するコードを見つけるとすぐに、トレースが開始されます。 エントリー・スパンは通常、外部システムまたはスケジュール済みのタスクからの着信呼び出しを示します。

エグジット・スパンへのマーク付け

メソッドを終了スパンでマークするには、次のに示すように、以下のアノテーションを追加するだけです:

@Span(type = Type.EXIT, value = "custom-tcp-client", capturedStackFrames = 5)

このメソッドが検出されるたびに、Instana は、これに Exit 呼び出しとしてのラベルを付けるスパンを記録します。 Exit は、外部システムへの発信呼び出しにマークを付けます。

Exit と Entry の相関付け

Exit と Entry がまだ Instana に認識されていなくても、多く場合、アプリケーションはこれらを使用して何らかのリモート通信を実行します。 Exit が検出され、相関付けが実行されない場合は、トレースが中断されます。つまり、Exit で終わるトレースと Entry で始まる新規トレースという 2 つのトレースが観測されることになります。

相関情報をリモート通信を介して手動で送信すると、Instana が相関付けの実行に利用できることがあります。 出口側で、Exit の注釈によって、必要な相関 ID の存在を確認します。 単に( https://github.com/instana/instana-java-sdk/blob/master/instana-java-sdk/src/main/java/com/instana/sdk/support/SpanSupport.java#L182 )を呼び出せばよい

SpanSupport.addTraceHeadersIfTracing(Type.EXIT, params);

これで、必要な ID を使用して所定のパラメーター・マップを埋めることができます。 他のデータをトランスポートする別の手段がプロトコルでサポートされている場合は、以下を使用して ID を取得できます。

currentTraceId(type)

currentSpanId(type)

入り口側では、注釈によってスパンが作成される前に、パラメーターを読み取ってそれをエントリー・スパンに設定することが重要です。

(https://github.com/instana/instana-java-sdk/blob/master/instana-java-sdk-sample/custom-http-sample/src/main/java/com/instana/sample/GreetingHandler.java#L52):

SpanSupport.inheritNext(SpanSupport.stringAsId(trace), SpanSupport.stringAsId(span));

これにより、エントリー・スパンは自動的にリモート・トレースを結合し、それ自体を呼び出し側 Exit の子スパンとして追加します。

変換と命名

状況によっては、SDK スパンを HTTP や RPC などの別のタイプに変換した方が、これらのスパンの発信元を適切に表すのに有利な場合があります。 これは、カスタムトレーシングのベストプラクティスの処理タグセクションに記載されているように、スパンに変換タグを追加することで実現できます。

これらのタグは、SpanSupport.annotate(type, name, key, value) メソッドを使用して設定できます。

Instana は、これらのフィールドが tags. キーにネストされるとすぐに、自動エージェント・インスツルメンテーションでの処理方法に従ってこれらのタグを処理します。 したがって、例えば http.url フィールドを設定する場合は、メソッド呼び出しが以下のようになります。

SpanSupport.annotate(<type>, <name>, "tags.http.url", "service://my-awesome-service/some/path")

同様に、 カスタムトレースのベストプラクティスページに記載されている方法に従い、サービス、エンドポイント、呼び出し名を変更することも可能です。

特定のフィールドが指定されていない場合、すべての SDK スパンのサービスの名前が SDK になります。 エンドポイント名と呼び出し名は、@Span 注釈または SpanSupport.annotate() メソッドで指定された name になります。

トレースコンテキストの保存と復元

ContextSupport クラスを使用すると、現在のトレース・コンテキストを保存して復元することができます。 takeSnapshot() メソッドは、トレース ID やスパン ID などのトレース・コンテキスト情報を内部マップに保管します。 restoreSnapshot() メソッドは、takeSnapshot() メソッドによって保存された情報を読み取り、それを使用して現在のトレース・コンテキストを設定します。 これらのメソッドは、アプリケーションが非同期処理を使用してタスクを完了し、トレースを別のスレッドで続行する必要がある場合に役立ちます。

例えば、現在のトレース・コンテキストは、以下のようにして保存できます。

snapShotKey = ContextSupport.takeSnapshot();

その後、以下を使用して、トレース・コンテキストを別のスレッドに復元することができます。

ContextSupport.restoreSnapshot(snapShotKey);

トラブルシューティング

SDK トレースが UI に表示されない場合は、いくつかの項目を検査することをお勧めします。

  • instana-java-sdkjar がアプリケーションに付属していますか? そうでない場合、エージェントは no-op モードになるため、サイレント状態になり、何もしません。
  • その configuration.yaml ファイルは注釈付きのすべてのパッケージを参照していますか?
  • トレースはアクティブですか?
  • YAML 構文は正しいですか?
  • 他の APM エージェントはアクティブですか? 他のほとんどの APM エージェントは Instana に干渉すると判明しているため、Instana のエージェントは他のエージェントを検出するとトレースを実行しません。 この場合は、ログに以下のように表示されます。
    JVM <PID> is running the <3rdParty> agent, which is known to be causing problems for the Instana Agent. Tracing will not be enabled for this JVM.
     
  • DEBUGログを有効にし、次のようなメッセージを探してください:
    2016-09-05T08:26:14.094+0200 | DEBUG | na-http-thread-1 | LoggerEndpoint                   | 48 - com.instana.agent - 1.1.194 | JVM (11403). Successfully instrumented class com.acme.resources.HelloWorldResource [sun.misc.Launcher$AppClassLoader@3d4eac69]`
    2016-09-05T08:26:14.145+0200 | DEBUG | na-http-thread-1 | LoggerEndpoint                   | 48 - com.instana.agent - 1.1.194 | JVM (11403) - Spent 188ms and 124kb transforming SDK classes. 
     
  • 注釈付きメソッドがユーザー/ロード・ドライバーで実際にヒットされますか? Instana エージェントは、始動後すぐに各 JVM と対話します。 そのため、エージェントが接続される前に発生するトランザクションはキャプチャーされません。 アプリケーションの存続期間中に通常ヒットされるメソッドには、必ず注釈を付けてください。
  • SDK設定の確認セクションに記載されている手順に従ってください。

FAQ

キャプチャーされたパラメーターおよび戻り値がクラス名とハッシュ・メモリー・アドレスのみを表示するのはなぜですか?

インスツルメンテーションは、キャプチャーされたパラメーターおよび戻り値ごとに toString() を呼び出します。 つまり、Instana 内で表示可能な値は、パラメーター・クラスおよび戻り値クラスの特定の toString() メソッド実装に直接依存します。

toString() がオーバーライドされなかった場合、最終的に java.lang.Object#toString() が使用されます。 このメソッドは、getClass().getName() + '@' + Integer.toHexString(hashCode()) を返し、その結果、表示される形式になります。

キャプチャーされたパラメーターおよび戻り値の可視性を向上させるには、toString() を適切にオーバーライドすることをお勧めします。

戻り値が使用できない場合があるのはなぜですか?

以下の場合、captureReturn=true が設定されていても戻り値を使用できないことがあります。

  • メソッドによって例外がスローされる。
  • メソッドの戻りの型が void である。
  • メソッドは返します null