JProfilerのカスタムプローブを開発するには、いくつかの基本的な概念と用語を理解しておく必要があります。 JProfilerのすべてのプローブに共通する基盤は、特定のメソッドをインターセプトし、インターセプトされた メソッドパラメータやその他のデータソースを使用して、JProfiler UIに表示したい有用な情報を含む文字列を 構築することです。
プローブを定義する際の最初の課題は、インターセプトするメソッドをどのように指定し、文字列を構築するための メソッドパラメータやその他の関連オブジェクトを使用できる環境をどのように取得するかです。JProfilerには、 これを行うための3つの異なる方法があります。
- スクリプトプローブは、完全にJProfiler UI内で 定義されます。呼び出しツリー内のメソッドを右クリックし、スクリプトプローブアクションを選択して、 組み込みコードエディタで文字列用の式を入力できます。これはプローブを試すには最適ですが、カスタムプローブの 機能の非常に限られた一部しか利用できません。
- 埋め込みプローブ APIは、独自のコードから 呼び出すことができます。ライブラリ、データベースドライバ、またはサーバーを作成する場合、製品にプローブを 同梱できます。JProfilerで製品をプロファイルするユーザーは誰でも、JProfiler UIにプローブが自動的に 追加されます。
- インジェクトプローブ APIを使用すると、 JProfilerのプローブシステムの全機能を活用して、サードパーティ製ソフトウェア用のプローブをIDE内で作成できます。 このAPIはアノテーションを利用してインターセプトを定義し、メソッドパラメータやその他の有用なオブジェクトを インジェクトします。
次の疑問は、作成した文字列をJProfilerでどのように処理すべきかということです。利用可能な戦略には、 ペイロードの作成または呼び出しツリーの分割という2つの異なる戦略があります。
ペイロードの作成
プローブによって構築された文字列は、プローブイベントを作成するために使用できます。イベントには、 その文字列に設定された説明、インターセプトされたメソッドの呼び出し時間と等しい所要時間、および関連する 呼び出しスタックが含まれます。対応する呼び出しスタックにおいて、プローブの説明とタイミングが累積され、 ペイロードとして呼び出しツリーに保存されます。イベントはある最大数に達した後に統合されますが、 呼び出しツリー内の累積されたペイロードは記録期間全体の合計数値を示します。CPUデータとプローブの両方が 記録されている場合、プローブ呼び出しツリービューにはペイロード文字列をリーフノードとして持つマージされた 呼び出しスタックが表示され、CPU呼び出しツリービューにはプローブ呼び出しツリービューへのアノテーション付きリンクが 含まれます。
CPUデータと同様に、ペイロードは呼び出しツリーまたはホットスポットビューに表示できます。ホットスポットは どのペイロードが消費時間の大部分を占めているかを示し、バックトレースはコードのどの部分がこれらのペイロードの 作成に関与しているかを示します。良好なホットスポットのリストを取得するには、ペイロード文字列に一意のIDや タイムスタンプを含めるべきではありません。すべてのペイロード文字列が異なると累積が行われず、ホットスポットの 明確な分布が得られないためです。例えば、JDBCのPrepared Statementの場合、パラメータはペイロード文字列に 含めるべきではありません。
スクリプトプローブは、設定されたスクリプトの戻り値から自動的にペイロードを作成します。インジェクトプローブも
同様で、PayloadInterceptionでアノテーションされたインターセプトハンドラーメソッドから、
ペイロードの説明を文字列として、または高度な機能のためにPayloadオブジェクトとして返します。
一方、埋め込みプローブは、引数としてペイロードの説明を渡してPayload.exitを呼び出すことで
ペイロードを作成します。この場合、Payload.enterとPayload.exitの間の時間が
プローブイベントの所要時間として記録されます。
ペイロードの作成は、さまざまな呼び出し元サイトで発生するサービスへの呼び出しを記録する場合に最も役立ちます。 典型的な例はデータベースドライバで、ペイロード文字列は何らかのクエリ文字列またはコマンドです。プローブは 呼び出し元サイトの視点をとり、測定される処理は別のソフトウェアコンポーネントによって実行されます。
呼び出しツリーの分割
プローブは実行サイトの視点をとることもできます。その場合、インターセプトされたメソッドがどのように呼び出されるかは 重要ではなく、その後にどのメソッドコールが実行されるかが重要になります。典型的な例はサーブレットコンテナ用の プローブで、抽出される文字列はURLです。
ペイロードを作成することよりも重要になるのは、プローブによって構築される個々の異なる文字列ごとに呼び出しツリーを 分割できる機能です。そのような文字列ごとに、対応するすべての呼び出しの累積された呼び出しツリーを含む分割ノードが 呼び出しツリーに挿入されます。通常であれば1つの累積された呼び出しツリーしか存在しないところに、呼び出しツリーを 個別に分析できる異なる部分へとセグメント化する分割ノードのセットが配置されます。
複数のプローブがネストされた分割を生成する場合もあります。単一のプローブはデフォルトで1つの分割レベルのみを 生成しますが、リエントラントとして設定されている場合は例外です(スクリプトプローブではサポートされていません)。
JProfiler UIでは、呼び出しツリーの分割はスクリプトプローブ機能にはバンドルされておらず、「メソッドの分割」と
呼ばれる別の機能になっています。これらはペイロードを作成せずに
呼び出しツリーを分割するだけなので、名前や説明を含むプローブビューは必要ありません。インジェクトプローブは
SplitInterceptionでアノテーションされたインターセプトハンドラーメソッドから分割文字列を返し、
埋め込みプローブは分割文字列を指定してSplit.enterを呼び出します。
テレメトリー
カスタムプローブには、イベント頻度と平均イベント所要時間の2つのデフォルトテレメトリーがあります。 インジェクトプローブと埋め込みプローブは、プローブ設定クラスのアノテーション付きメソッドで作成される 追加のテレメトリーをサポートしています。JProfiler UIでは、スクリプトテレメトリーはスクリプトプローブ機能から 独立しており、「テレメトリー」セクション内のツールバーにあるテレメトリーの設定ボタンの下にあります。
テレメトリーメソッドは毎秒1回ポーリングされます。Telemetryアノテーションでは、単位とスケールファクターを
設定できます。line属性を使用すると、複数のテレメトリーを単一のテレメトリービューに結合できます。
TelemetryFormatのstacked属性を使用すると、ラインを加算式にして積み上げ折れ線グラフとして
表示できます。埋め込みプローブとインジェクトプローブのテレメトリー関連APIは同等ですが、それぞれのプローブタイプにのみ
適用可能です。
制御オブジェクト
プローブイベントを、JProfilerで「制御オブジェクト」と呼ばれる関連付けられた長寿命のオブジェクトに紐付けると 有用な場合があります。例えばデータベースプローブでは、クエリを実行する物理接続がその役割を果たします。 このような制御オブジェクトは、埋め込みAPIおよびインジェクトプローブAPIでオープンおよびクローズでき、 プローブイベントビューに対応するイベントを生成します。プローブイベントの作成時に制御オブジェクトを指定できるため、 プローブイベントはプローブの「制御オブジェクト」ビューに表示される統計に寄与します。
制御オブジェクトには、オープン時に指定する必要がある表示名があります。プローブイベントの作成時に新しい 制御オブジェクトが使用される場合、プローブはその設定内で名前リゾルバーを提供する必要があります。
さらに、プローブはenumクラスを介してカスタムイベントタイプを定義できます。プローブイベントが作成されると、 それらのタイプのいずれかを指定でき、単一のイベントタイプでフィルタリングできるイベントビューに表示されます。 さらに重要な点として、制御オブジェクトを時間軸上のラインとして表示するプローブのタイムラインビューが、 イベントタイプに応じてカラー化されます。カスタムイベントタイプのないプローブの場合、カラー化はイベントが 記録されないアイドル状態と、プローブイベントの継続時間に対するデフォルトのイベント状態を表示します。 カスタムタイプを使用すると、例えば「read」と「write」などの状態を区別できます。
記録
すべてのプローブと同様に、カスタムプローブはデフォルトではデータを記録しないため、必要に応じて記録を 有効化および無効化する必要があります。プローブビューで手動の開始/停止アクションを使用することもできますが、 多くの場合、最初にプローブ記録をオンにしておく必要があります。JProfilerは事前にカスタムプローブを認識しないため、 記録プロファイルにはすべてのカスタムプローブに適用されるカスタムプローブチェックボックスがあります。
同様に、プローブ記録を開始および停止するトリガーアクションにはすべてのカスタムプローブを選択できます。
プログラムによる記録では、すべてのカスタムプローブを記録するために
Controller.startProbeRecording(Controller.PROBE_NAME_ALL_CUSTOM, ProbeRecordingOptions.EVENTS)
を呼び出すか、より詳細に指定するためにプローブのクラス名を渡すことができます。











