JFRイベントとしてのAPMスパンの記録
APMトレーサおよびAPMエージェントでは、JFRイベントとしてのAPMスパンの記録をサポートしています。
現在、JDK 11以上がサポートされています。
APMエージェント使用時におけるJFRイベントとしてのAPMスパンの記録の詳細は、アプリケーション・サーバーでのAPM JavaエージェントのプロビジョニングおよびデプロイのJFRイベントとしてのAPMスパンの記録を参照してください。
Java Flight Recorder (JFR)は、Javaアプリケーションの実行に関する診断データおよびプロファイリング・データを収集するためのツールです。Java Flight Recorder (JFR)およびJava Mission Control (JMC)の詳細は、JDK Mission Controlを参照してください。
JFR記録でのAPMイベントの取得
APMトレーサの使用時にJFR記録でAPMイベントを取得するには、次のステップを実行します:
-
APMトレーサが正しく動作していることを確認します。
トレース・エクスプローラを開き、すべてのトレースが表示されることを確認します。トレース・エクスプローラのオープンおよび使用の詳細は、トレース・エクスプローラでのトレースのモニターを参照してください。
-
Helidon JVMによって行われたJFR記録にAPMトレーサがイベントを追加できるように、Mavenプロジェクトに依存関係を追加します。
<dependency> <groupId>com.oracle.apm.agent.java</groupId> <artifactId>apm-java-agent-jfr11</artifactId> <version>[1.0.1389,)</version> </dependency>
-
記録を開始します。
すべてが正しく機能していることをテストするには、希望の方法を使用して記録を開始する必要があります(JDK Mission Control UIまたはJCMDコマンドライン・ユーティリティを使用できます)。記録が開始された後は、記録を表示するとJDK Mission Control UIにトレース・イベントが表示されます。
APMトレース・イベントが正しくJFR記録に追加されていることを確認するには、JDK Mission Controlに接続し、「イベント・ブラウザ」でAPMトレースが表示されていることを確認します: 「APM OpenTracing」をクリックし、APMトレース・イベントが表示されることを確認します。
APMトレーサでのJFRイベントの構成
(オプション)これは、イベントのレポートをカスタマイズする場合のオプションのステップです。
JFR記録イベント分析を簡略化するために、各イベントはカテゴリまたはイベント・タイプ別に編成されます。
デフォルト・カテゴリ
APMトレーサでは、APM JFRイベントのデフォルト・カテゴリは、Span Operation Name
の内容(スパン内のname
というフィールド)を使用して取得されます。component
タグは移入できないため、デフォルト・カテゴリとして使用できません。
イベント
イベント・タイプを使用すると、JMCユーザー・インタフェース内でイベントを編成および分類できます。APMトレーサはスパンを取得すると、このスパンにイベントを生成できますが、その特定のイベントのイベント・タイプを決定する必要があります。
イベント・タイプの例として、サーブレット、jdbcおよびjax-rsがあります。
イベント・タイプ構成
イベント・タイプまたはカテゴリの構成を行うには、いくつかの方法があります。次に示す様々なユース・ケースを参照してください:
-
ケース1:
component
タグこれがイベントを分類する最も単純な方法です。この方法を使用することをお薦めします。
ほとんどのシナリオにおいて、Opentracingスパンには
component
というタグが含まれます。component
タグの値は、イベント・タイプの判別に使用されます。たとえば、次のスパンを見てみます:
{ "id":"e926ff3d06013045", "trace-id":"49abd92e69786853e926ff3d06013045", "parent-id":"6ef54ec2c524c99a", "name":"content-write", "ts-micros":1614190751360177, "td-micros":219348, "attributes":{ "server":"Helidon SE", "http.url":"http://localhost:8079/health", "http.status_code":200, "component":"helidon-webserver", "http.method":"GET", "organization":"development" }, "events":[ ] },
この場合、生成されたイベントには
helidon-webserver
イベント・タイプが割り当てられます(それがcomponent
タグの値であるため)。 -
ケース2: 他のタグ
アプリケーションで
component
タグを使用していないが、別のタグを使用しているか、タグを生成しているライブラリがある場合は、その別のタグからイベント・タイプを読み取るようにAPMトレーサを構成できます。たとえば、次のスパンでは、
span.type
というタグからイベント・タイプを読み取ることができます:{ "id":"e926ff3d06013045", "trace-id":"49abd92e69786853e926ff3d06013045", "parent-id":"6ef54ec2c524c99a", "name":"content-write", "ts-micros":1614190751360177, "td-micros":219348, "attributes":{ "server":"Helidon SE", "http.url":"http://localhost:8079/health", "http.status_code":200, "span.type":"helidon-webserver", "http.method":"GET", "organization":"development" }, "events":[ ] },
この場合、javaアプリケーションの起動時に次のシステム・プロパティを使用して、
span.type
タグからイベント・タイプを読み取るようにAPMトレーサを構成できます:java -Dcom.oracle.apm.agent.jfr.category.tag=span.type ...
-
ケース3: 使用可能なタグがない場合は操作名を使用する
有用なカテゴリを持つタグがアプリケーションで使用されていない場合は、
Operation Name
を使用してイベント・タイプを決定できますが、この方法はお薦めしません。JFRシステムでは、イベント・タイプの名前が有効なJava識別子である必要がありますが、
Operation Name
にはスペースや他の不正な文字が含まれていることがよくあります。APMトレーサは、すべての不正な文字をアンダースコアで置換して、Operation Name
を有効な識別子に変換します。java -Dcom.oracle.apm.agent.jfr.category.default=ORACLE_APM_USE_SPAN_OPERATION_NAMES
ノート
Operation Name
は、カテゴリ・タグが存在しないか空の場合のみにのみ使用されます。これは単純な解決策とならない理由は、
Operation Name
にIDなどの一意のトークンが含まれていると、すべてのイベントが独自のイベント・タイプになるためです。さらに、Operation Name
を有効な識別子に変換すると、イベント・タイプを構成してイベントに必要なフィールドを設定する際に、さらに問題が発生します。また、構成は、変換されたOperation Name
に基づいて実行する必要があります。そうしない場合、Operation Name
の様々なバリアントを同じ方法で多数構成する必要があります。 -
ケース4: 使用可能なタグがなく、すべての操作名が一意である
このケースでは、イベント・タイプの分類に使用できる情報はありません。これは、すべてのイベントが結果として同じイベント・タイプになるか、前述のユース・ケース3シナリオを使用して構成された場合はすべてのイベントが一意になるという、最悪のケース・シナリオです。唯一可能な方法は、このデフォルト・イベント・タイプの名前を選択できるようにすることです。これは次のように構成できます。
java -Dcom.oracle.apm.agent.jfr.category.default=Unknown
ノート
デフォルトは、カテゴリ・タグが存在しないか空の場合のみにのみ使用されます。この場合、すべてのイベントは、
Unknown
というイベント・タイプ、または選択したカスタム値に設定されます。
イベント・タイプごとに、そのイベント固有のデータを含む1つ以上のフィールドを追加できます。
- 名前。
- タイプ(int、float、string、thread)。
- ラベル。
- 説明。
- name: traceID
type: String
label: New Trace ID
description: New Opentracing Trace ID
ACMLファイルの作成
このステップはオプションです。デフォルトの設定で期待どおりに動作していれば、このステップはスキップできます。
デフォルトの設定を変更して記録をカスタマイズする場合は、ACMLファイルを作成できます。
次の例は、Helidonマイクロサービス・コンテナの組込みのデフォルト設定を上書きしてJFRへのイベント・ロギングを構成するACMLファイルのフォーマットを示しています:
caseSensitiveFieldName: false
recordCallStack: true
eventTypes:
helidon-webserver:
name: helidon-webserver
label: Helidon Webserver Events
description: All events based on helidon webserver
recordCallStack: true
# All fields must be provided here.
# Fields are NOT incremental since that would make them impossible to remove
fields:
- name: traceID
type: String
label: New Trace ID
description: New Opentracing Trace ID
- name: spanID
type: String
label: New Span ID
description: New Opentracing Span ID
- name: http.url
type: String
label: New HTTP URL
description: The New URL for the HTTP endpoint being hit
- name: organization
type: String
label: Organization
description: The New Organization value of this call
- name: startThread
type: Thread
label: Start Thread
description: The thread on which this event started
- name: http.status_code
type: int
label: Status Code
description: The HTTP Response status code
- name: http.method
type: String
label: HTTP Method
description: The HTTP Method
APMエージェントおよびAPMトレーサを使用する場合は、前述のフォーマットのACMLファイルを使用できます。APMトレーサの場合は、Helidon、Springboot、Micronautなどの任意のコンテナで動作します。
FAQ
-
com.oracle.apm.agent.jfr.category.tag
プロパティとcom.oracle.apm.agent.jfr.category.default
プロパティの両方が設定されている場合、どちらの設定が優先されますか。両方に値が指定されている場合、まずスパン内にカテゴリ・タグがあるか調べます。見つかれば、それが使用されます。ない場合は、デフォルトが使用されます。
-
APMトレーサの場合、構成ファイルは必須ですか。ファイルなしでプロパティを指定できますか。
構成ファイルは必須ではありません。デフォルトで問題がなければ構成ファイルは不要ですが、自分でプロパティを指定することもできます。
-
エントリが重複しているように見える場合があるのはなぜですか。たとえば、ACML構成ファイルの次のスニペットには、
helidon-webserver
エントリが2回出現します:eventTypes: helidon-webserver: name: helidon-webserver
タグまたは操作名から読み取る/推測するのは、最初の
helidon-webserver
エントリです。上の例のように、イベント・タイプがクリーンで準備しやすく直感的である場合、JFR記録に送信するのに同じイベント・タイプを使用できます。JMCではその形式で表示されます。ただし、operation name
の使用時に、dbクライアントからのJDBC問合せを表す、q_AxPsCbac9Ykp0HjpU+ENCiYHKl5HzMCmR02AfGzow3A=
のようなイベント・タイプを取得する場合があります。この場合、JFR記録に送信された名前を直感的な名前に変更するために、次の例を使用できます:eventTypes: q_AxPsCbac9Ykp0HjpU+ENCiYHKl5HzMCmR02AfGzow3A=: name: jdbc-select-query
-
イベント・タイプごとに
recordCallStack
を指定できる場合、トップ・レベルrecordCallStack
も必要になるのはなぜですか。コール・スタックの記録の柔軟性を最大限にするために、2つのユース・ケースをサポートしています。コール・スタック記録をグローバルにオフにしてから、特定のイベント・タイプに対して選択的にオンにできます。もう1つのオプションは、グローバルにオンにしてから、特定のイベント・タイプに対して選択的にオフにすることです。どちらのユース・ケースもサポートされているため、設定はトップ・レベルとイベント・レベルの両方にあります。
-
まったく構成されていないスパンがいくつかあり、無視されています。構成せずにこれらのイベントを取得することは可能ですか。
はい。メイン・トップ・レベル構成で
allowUnconfiguredEvents: true
を設定すると、これらのイベントが取得されます。この場合、どのフィールドを収集するかがわかりません。デフォルト・フィールドのうち、traceID
、spanID
、parentSpanID
、startThread
およびoperationName
のセットのみが収集されます。 -
操作名で定義されたカテゴリを使用するために
com.oracle.apm.agent.jfr.category.default=ORACLE_APM_USE_SPAN_OPERATION_NAMES
を使用した場合、構成ファイル内で操作名がイベント・タイプ名と正確に一致している必要がありますか。その場合、一意の操作名があると、操作ごとにイベント・タイプを指定する必要がありますか。はい、構成ファイル内のイベント・タイプ名と一致している必要があります。一意の操作名が多数ある場合でも、操作ごとにイベント・タイプを指定する必要があります。これは、これらのイベント・タイプそれぞれに異なるフィールド・セットを設定する必要があるためです。
-
操作名がJava識別子に変換されているため、そのイベント・タイプを構成できません。操作名が何に変換されたかはどのように判断できますか。
不正な文字はすべてアンダースコアで置き換えられています。文字列を識別子に変換するためのサンプルJavaコードが必要な場合は、次のコードを使用できます。これは、APMが文字列の変換に使用するルーチンと同じです。// Convert an arbitrary string into a valid java identifier by replacing non-identifier chars with an underscore public static String getJavaIdentifier(String inString) { if (inString == null || inString.length() == 0) return inString; StringBuilder stringBuilder = new StringBuilder(); char[] allChars = inString.toCharArray(); if(Character.isJavaIdentifierStart(allChars[0])) stringBuilder.append(allChars[0]); else stringBuilder.append("_"); for (int i = 1; i < allChars.length; i++) { if (Character.isJavaIdentifierPart(allChars[i])) stringBuilder.append(allChars[i]); else stringBuilder.append("_"); } return stringBuilder.toString(); }
-
名前一致をRegExにできますか。
いいえ。RegExはサポートされていません。