New Relic の Java エージェントは、 Web トランザクション と バックグラウンドタスクなどの非 Web トランザクション の情報を収集して報告します。エージェントは、サポートされているフレームワークを自動的に計測し、アプリケーションのコードを変更する必要はありません。ただし、カスタムコードや 「Compatibility and requirements for the Java agent」 のドキュメントに記載されていないフレームワークやテクノロジーに加えて、サポートされているフレームワークの実装によっては、 カスタムインスツルメンテーション が必要になる場合があります。
このドキュメントでは、Java エージェントAPI を使用して、外部呼び出し、メッセージング フレームワーク、ディストリビューティッド(分散)トレーシング 、データストア、および Web フレームワークを計測する方法について説明します。 API使用時に最良の結果を得るには、最新の Java エージェント リリースを 使用していることを確認してください。 例で使用されるいくつかのAPIには、Javaagent 3.36.0 以上が必要です。
外部API External API により、アプリケーションは New Relic に外部サービス呼び出しを報告できるようになります。 この情報は、APM のExternal services ページ に表示されます。 HTTP 外部アクティビティをレポートするには、 HttpParameters
ビルダーを使用してExternalParameters
のインスタンスを作成し、レポートするトレースされたメソッドでreportAsExternal(ExternalParameters parameters)
を呼び出すだけです。
外部API String library = "HttpClient" ;
URI uri = request . getURI ( ) ;
String procedure = "execute" ;
ExternalParameters params = HttpParameters
. inboundHeaders ( inboundHeaders )
NewRelic . getAgent ( ) . getTracedMethod ( ) . reportAsExternal ( params ) ;
外部パラメータービルダー ExternalParameters
を作成するためのビルダーがいくつかあります。
DatastoreParameters
HttpParameters
GenericParameters
MessageConsumeParameters
MessageProduceParameters
これらのビルダーは、 TracedMethod
の reportAsExternal
API コールの入力コンテナー オブジェクトを作成します。 これらの論点オブジェクトは、ディストリビューティッド(分散)トレーシングを介した HTTP 外部呼び出しのリンク、データ ストアへの外部呼び出しのトレース、追加の低速処理を伴うデータ ストアへの外部呼び出しのトレース、メッセージ プロデューサー間の呼び出しのトレースなどに使用されます。そして消費者。
重要 このクラスのメソッドはすべて、機密性の高い個人情報を公開する可能性があります。引数を作成する際には、URIや文字列値に特に注意してください。
分散型トレーシングAPI 分散型トレーシング API は、New Relic Java エージェントが、New Relic Java エージェントまたは他のオープンインスツルメンテーション標準ツールによってインスツルメンテーションされたアプリケーション間のトランザクションをリンクすることを可能にします。このAPIは、エージェントがリクエストのヘッダーを読み書きできるようにするためのラッパーを使用しています。
ヘッダーのラッパー エージェントはインターフェースHeaders
を使用して、リクエストのヘッダーを読み書きします。クライアントとサーバーの両方が、通信フレームワークのクラスを使用してこのインターフェイスを実装する必要があります。例えば:
class HeadersWrapper implements Headers {
private final HttpMessage delegate ;
public HeadersWrapper ( HttpMessage request ) {
public void setHeader ( String name , String value ) {
delegate . setHeader ( name , value ) ;
public HeaderType getHeaderType ( ) {
public String getHeader ( String name ) {
return delegate . getFirstHeader ( name ) . getValue ( ) ;
public Collection < String > getHeaders ( String name ) {
return Arrays . stream ( delegate . getHeaders ( name ) )
. map ( NameValuePair :: getValue )
. collect ( Collectors . toList ( ) ) ;
public void addHeader ( String name , String value ) {
delegate . addHeader ( name , value ) ;
public Collection < String > getHeaderNames ( ) {
return Arrays . stream ( delegate . getAllHeaders ( ) )
. map ( NameValuePair :: getName )
. collect ( Collectors . toSet ( ) ) ;
public boolean containsHeader ( String name ) {
return Arrays . stream ( delegate . getAllHeaders ( ) )
. map ( NameValuePair :: getName )
. anyMatch ( headerName -> headerName . equals ( name ) ) ;
ラッパーを使った分散型トレーシングの実装 前のセクションで説明したラッパー・オブジェクトを使って、Javaエージェントがクライアント側とサーバー側でトレースを報告することを可能にすることができます。例えば、以下のようになります。
分散型トレーシング。クライアントサイド public int makeExternalCall ( URI uri ) throws IOException {
HttpUriRequest request = RequestBuilder . get ( ) . setUri ( uri ) . build ( ) ;
Headers outboundHeaders = new HeadersWrapper ( request ) ;
Transaction transaction = NewRelic . getAgent ( ) . getTransaction ( ) ;
transaction . insertDistributedTraceHeaders ( outboundHeaders ) ;
CloseableHttpClient connection = HttpClientBuilder . create ( ) . build ( ) ;
CloseableHttpResponse response = connection . execute ( request ) ;
return response . getStatusLine ( ) . getStatusCode ( ) ;
このサンプルコードでは、リクエストを開始したクライアント上で分散型トレーシングを使用して外部からの呼び出しを報告するようにエージェントが設定されています。これらの手順は、以下のようにまとめられます。
クライアントでフレームワーク クラスを使用してHeaders
を実装します。 insertDistributedTraceHeaders(Headers headers)
を使用して、エージェントが適切なヘッダーをアウトバウンド リクエストに追加するようにします。分散型トレーシング。サーバーサイド @Trace ( dispatcher = true )
public Response serve ( IHTTPSession request ) {
Transaction tx = NewRelic . getAgent ( ) . getTransaction ( ) ;
NewRelic . setTransactionName ( "Custom" , "ExternalHTTPServer" ) ;
Headers req = new HeadersWrapper ( request ) ;
tx . acceptDistributedTraceHeaders ( TransportType . HTTP , req ) ;
return newFixedLengthResponse ( "<html><body><h1>SuccessfulResponse</h1>\n</body></html>\n" ) ;
このサンプルコードでは、エージェントはリクエストからヘッダーを読み取るように設定されています。これらの手順をまとめると以下のようになります。
サーバーでフレームワーク クラスを使用してHeaders
を実装します。 acceptDistributedTraceHeaders(TransportType transportType, Headers headers)
を使用して、このトランザクションを呼び出しを行ったトランザクションにリンクします。クロスアプリケーショントレースAPI 重要 クロスアプリケーショントレースは、エージェントバージョン7.4.0では非推奨となっており、将来のエージェントバージョンでは削除されます。
クロスアプリケーショントレーシングを使用する代わりに、ディストリビューティッド(分散)トレーシング機能 を使用することをお勧めします。ディストリビューティッド(分散)トレーシングはクロスアプリケーショントレーシングの機能を向上させたものであり、大規模な分散システムに適しています。
クロスアプリケーショントレーシング (CAT) API は、New Relic Java エージェントが New Relic で監視しているアプリケーション間のトランザクションをリンクさせることができます。この API は、クライアントおよびサーバーのラッパーを使用しており、エージェントはリクエストからヘッダーを読み取り、レスポンスにヘッダーを追加することができます。
クライアント・ラッパー エージェントがリクエストを開始するクライアントでアウトバウンド リクエスト ヘッダーを書き込むには、 OutboundHeaders
インターフェースを使用します。例えば:
class OutboundWrapper implements OutboundHeaders {
private final HttpUriRequest delegate ;
public OutboundWrapper ( HttpUriRequest request ) {
public void setHeader ( String name , String value ) {
delegate . addHeader ( name , value ) ;
public HeaderType getHeaderType ( ) {
エージェントが応答を受信するクライアントで受信応答ヘッダーを読み取るには、 InboundHeaders
を実装します。例えば:
class InboundWrapper implements InboundHeaders {
private final CloseableHttpResponse responseHeaders ;
public InboundWrapper ( CloseableHttpResponse responseHeaders ) {
this . responseHeaders = responseHeaders ;
public HeaderType getHeaderType ( ) {
public String getHeader ( String name ) {
return responseHeaders . getFirstHeader ( name ) . getValue ( ) ;
サーバーラッパー エージェントがウェブ リクエスト ヘッダーを取得するには、 ExtendedRequest
クラスを拡張する必要があります。
ExtendedRequestクラスの拡張 class RequestWrapper extends ExtendedRequest {
private IHTTPSession session ;
public RequestWrapper ( IHTTPSession session ) {
public String getRequestURI ( ) {
public String getHeader ( String name ) {
return session . getHeaders ( ) . get ( name ) ;
public String getRemoteUser ( ) {
@SuppressWarnings ( "rawtypes" )
public Enumeration getParameterNames ( ) {
return Collections . enumeration ( session . getParms ( ) . keySet ( ) ) ;
public String [ ] getParameterValues ( String name ) {
return new String [ ] { session . getParms ( ) . get ( name ) } ;
public Object getAttribute ( String name ) {
public String getCookieValue ( String name ) {
public HeaderType getHeaderType ( ) {
public String getMethod ( ) {
return session . getMethod ( ) . toString ( ) ;
エージェントが Web 応答ヘッダーを設定するには、 Response
インターフェースを実装します。
レスポンスインターフェースの実装 public class ResponseWrapper implements com . newrelic . api . agent . Response {
private final Response httpResponse ;
public ResponseWrapper ( Response httpResponse ) {
this . httpResponse = httpResponse ;
public int getStatus ( ) throws Exception {
public String getStatusMessage ( ) throws Exception {
public void setHeader ( String name , String value ) {
httpResponse . addHeader ( name , value ) ;
public String getContentType ( ) {
public HeaderType getHeaderType ( ) {
ラッパーによるCAT実装 前のセクションで説明したラッパー・オブジェクトを使って、Javaエージェントがクライアント側とサーバー側でクロス・アプリケーション・トレーシング(CAT)を行えるようにすることができます。例えば、以下のようになります。
クロスアプリケーショントレースクライアントサイド public int makeExternalCall ( URI uri ) throws IOException {
String library = "HTTPClient" ;
String procedure = "Execute" ;
HttpUriRequest request = RequestBuilder . get ( ) . setUri ( uri ) . build ( ) ;
OutboundWrapper outboundHeaders = new OutboundWrapper ( request ) ;
TracedMethod tracedMethod = NewRelic . getAgent ( ) . getTracedMethod ( ) ;
tracedMethod . addOutboundRequestHeaders ( outboundHeaders ) ;
CloseableHttpClient connection = HttpClientBuilder . create ( ) . build ( ) ;
CloseableHttpResponse response = connection . execute ( request ) ;
InboundWrapper inboundHeaders = new InboundWrapper ( response ) ;
ExternalParameters params = HttpParameters
. inboundHeaders ( inboundHeaders )
tracedMethod . reportAsExternal ( params ) ;
return response . getStatusLine ( ) . getStatusCode ( ) ;
このサンプルコードでは、リクエストを開始したクライアントのCATを使用して外部からの電話を報告するようにエージェントが設定されています。これらの手順は、以下のようにまとめられます。
クライアントでフレームワーク クラスを使用してOutboundHeaders
とInboundHeaders
を実装します。 addOutboundRequestHeaders(OutboundHeaders outboundHeaders)
を使用して、エージェントが適切なヘッダーをアウトバウンド リクエストに追加するようにします。HttpParameters
ビルダーを使用してExternalParameters
オブジェクトを作成し、受信応答ヘッダーを提供します。reportAsExternal(ExternalParameters params)
を使用して外部リクエストとして報告します。クロスアプリケーショントレースサーバーサイド @Trace ( dispatcher = true )
public Response serve ( IHTTPSession session ) {
Transaction tx = NewRelic . getAgent ( ) . getTransaction ( ) ;
NewRelic . setTransactionName ( "Custom" , "ExternalHTTPServer" ) ;
ExtendedRequest req = new RequestWrapper ( session ) ;
Response res = newFixedLengthResponse ( "<html><body><h1>SuccessfulResponse</h1>\n</body></html>\n" ) ;
tx . setWebResponse ( new ResponseWrapper ( res ) ) ;
tx . addOutboundResponseHeaders ( ) ;
このサンプルコードでは、リクエストに応答しているサーバーのCATを使用して、エージェントが外部からの電話を報告するように設定されています。これらの手順をまとめると、以下のようになります。
Response
を実装し、サーバー上のフレームワーク クラスを使用してExtendedRequest
クラスを拡張します。
setWebRequest(ExtendedRequest request)
とsetWebResponse(Response response)
を使用してトランザクションを Web トランザクションに変換し、一緒にエージェントにインバウンド リクエスト ヘッダーとアウトバウンド ヘッダーを記録する場所を提供します。
トランザクション名はリクエスト オブジェクトに依存し、レスポンス コードはレスポンス オブジェクトに依存するため、 setWebRequest(ExtendedRequest request)
とsetWebResponse(Response response)
の両方を一緒に使用することが重要です。
addOutboundResponseHeaders()
を使用して、エージェントが適切なヘッダーを送信応答に追加するようにします。
markResponseSent()
への呼び出しで応答の終わりをマークします。
Messaging API メッセージング API を使用すると、アプリケーションはメッセージ キュー ブローカーとのやり取りをレポートできます。MessageConsumerParametersMessage
とMessageConsumerParameters
を提供することで、外部 API の上に構築されます。
このAPIは、メッセージ・ブローカー・インタラクションを識別するために必要なメトリクスを生成します。UIはこれらのメトリクスを使用して、適切なアクションとカウント(メッセージプット、またはメッセージテイク)を持つトランザクション内のセグメント、トランザクショントレース内の専用メッセージタブなど、メッセージングデータを表示します。APIにインバウンドおよびアウトバウンドヘッダを提供することで、エージェントはCATヘッダを追加し、CATメトリクスを記録することができます。これにより、UIはアプリケーション間の接続を示す サービスマップ を描くことができます。
重要 メッセージングAPIは、プロデューサとコンシューマの間の双方向通信に依存しています。Fire and Forgetパターンのように、プロデューサーがコンシューマーから確認応答を受け取らない場合、メッセージングAPIはメッセージキュー・ブローカーとのやり取りを正確に反映しません。
以下の例は、架空のJMSライブラリをインストルメント化する方法を示しています。
Messaging APIの実装 public class MessageProducer {
public void sendMessageToQueue ( Message message ) {
ExternalParameters messageProduceParameters = MessageProduceParameters . library ( "JMS" )
. destinationType ( DestinationType . NAMED_QUEUE )
. destinationName ( message . getJMSDestination ( ) )
. outboundHeaders ( new OutboundWrapper ( message ) )
NewRelic . getAgent ( ) . getTracedMethod ( ) . reportAsExternal ( messageProduceParameters ) ;
簡単にするために、エージェントは、 sendMessageToQueue
が常にメッセージを名前付きキューに入れると想定しています。実際には、名前付きキュー、一時キュー、トピック、一時トピックなど、さまざまな種類の宛先にメッセージを送信できます。API は、メッセージをさまざまな宛先タイプ ( NAMED_QUEUE
、 TEMP_QUEUE
、 NAMED_TOPIC
、 TEMP_TOPIC
) に報告する列挙型を提供します。UI には名前付きキューと名前付きトピックの名前が表示され、一時キューと一時トピックの名前は省略されるため、適切な宛先タイプを指定することが重要です。
ライブラリが CAT ヘッダーを送信できる場合、エージェントが CAT ヘッダーを追加できるように、 OutboundHeaders
オブジェクトが API に提供されます。
CATヘッダー実装のメッセージ public class MessageConsumer {
public Message messageReceive ( ) {
ExternalParameters messageConsumeParameters = MessageConsumeParameters . library ( "JMS" )
. destinationType ( DestinationType . NAMED_QUEUE )
. destinationName ( message . getJMSDestination ( ) )
. inboundHeaders ( new InboundWrapper ( message ) )
NewRelic . getAgent ( ) . getTracedMethod ( ) . reportAsExternal ( messageConsumeParameters ) ;
Datastore API トレースされたメソッドが外部データストア呼び出しとして報告されると、その呼び出しは APMデータベース ページに表示されます。データストアは実行中のアプリケーションの外部にあるため、メソッドはreportAsExternal(ExternalParameters params)
メソッドを使用してデータストア アクティビティとしてレポートされます。唯一の違いは、別のビルダーDatastoreParameters
を使用して適切なExternalParameters
オブジェクトを作成することです。
Datastore APIの実装 TracedMethod tracedMethod = NewRelic . getAgent ( ) . getTracedMethod ( ) ;
tracedMethod . reportAsExternal (
. instance ( "localhost" , 8080 )
Datastore API。クエリが遅い この API 呼び出しは、 Datastore API 呼び出し と同じ動作を提供し、遅いクエリ 情報を追跡できるように拡張します。同じreportAsExternal(ExternalParameters params)
メソッドとビルダーが使用されますが、ビルダー メソッドが追加されています。
クエリの実装が遅いデータストア 適切なExternalParameters
オブジェクトの作成を以下に示します。
TracedMethod tracedMethod = NewRelic . getAgent ( ) . getTracedMethod ( ) ;
tracedMethod . reportAsExternal (
. instance ( "localhost" , 8080 )
. slowQuery ( rawQuery , QUERY_CONVERTER )
private static QueryConverter < String > QUERY_CONVERTER = new QueryConverter < String > ( ) {
public String toRawQueryString ( String statement ) {
public String toObfuscatedQueryString ( String statement ) {
return obfuscateQuery ( statement ) ;
WebFrameworksのAPI WebFrameworks API では、エージェントが アプリケーションに関する追加の識別情報を報告することができます。
NewRelic . setServerInfo ( String dispatcherName , String version )
NewRelic . setAppServerPort ( int port )
NewRelic . setInstanceName ( String instanceName )
ヒント これらの値は一度しか設定できません。それ以降の呼び出しには影響しません。
WebFrameworksのAPI実装 public NewRelicApiClient ( ) throws IOException , URISyntaxException {
NewRelic . setServerInfo ( "NanoHttp" , "2.3.1" ) ;
NewRelic . setAppServerPort ( 8080 ) ;
NewRelic . setInstanceName ( "Client:8080" ) ;
start ( NanoHTTPD . SOCKET_READ_TIMEOUT , false ) ;
System . out . println ( "\nRunning on http://localhost:8080/ \n" ) ;