このドキュメントでは、New Relic Java エージェント API を使用して、シンプルなクライアントとサーバーのアプリケーションをインストルメントする方法を紹介します。インスツルメンテーションには次のような目的があります。
- 外部のHTTPとデータストアを記録するために トランザクション.
- New Relic エージェントを実行している 2 つのアプリケーション間の外部トランザクションをリンクさせること( distributed tracing または DT として知られている)。
利用可能なAPIクラスとメソッドの完全な説明については、 JavaエージェントAPI Javadoc を参照してください。
重要
APIを使用する際に最良の結果を得るためには、 最新のJavaエージェント・リリース を持っていることを確認してください。例題で使用しているいくつかのAPIには、Java agent 3.36.0以降が必要です。
クライアントサイドの例
ここでは、簡単なクライアント・サーバー・アプリケーションのクライアント側のコードの例を示します。
package com.newrelic.example;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
import java.util.Arrays;
import java.util.Collection;
import java.util.stream.Collectors;
// New Relic API imports
import com.newrelic.api.agent.ExternalParameters;
import com.newrelic.api.agent.HeaderType;
import com.newrelic.api.agent.Headers;
import com.newrelic.api.agent.HttpParameters;
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.TracedMethod;
import com.newrelic.api.agent.Transaction;
import fi.iki.elonen.NanoHTTPD;
import org.apache.http.HttpMessage;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.methods.RequestBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
public class NewRelicApiExample extends NanoHTTPD {
public NewRelicApiExample() throws IOException, URISyntaxException {
super(8080);
// Set Dispatcher name and version
NewRelic.setServerInfo("NanoHttp", "2.3.1");
// Set Appserver port for JVM identification
NewRelic.setAppServerPort(8080);
// Set JVM instance name
NewRelic.setInstanceName("Client");
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
System.out.println("Running at: http://localhost:8080/");
}
public static void main(String[] args) throws URISyntaxException {
try {
new NewRelicApiExample();
} catch (IOException ioe) {
System.err.println("Unable to start the server:\n" + ioe);
}
}
@Trace(dispatcher = true)
@Override
public Response serve(IHTTPSession session) {
URI uri = null;
int status = 0;
try {
createDB();
Thread.sleep(1000);
uri = new URI("http://localhost:8081");
status = makeExternalCall(uri);
} catch (URISyntaxException | InterruptedException | IOException e) {
e.printStackTrace();
}
if (status == 200) {
return newFixedLengthResponse("<html><body><h1>Successful Response</h1>\n</body></html>\n");
} else {
return newFixedLengthResponse("<html><body><h1>Error\n" + status + "</h1>\n</body></html>\n");
}
}
@Trace
public int makeExternalCall(URI uri) throws IOException {
HttpUriRequest request = RequestBuilder.get().setUri(uri).build();
// Wrap the outbound Request object
Headers outboundHeaders = new HeadersWrapper(request);
// Obtain a reference to the current transaction
Transaction transaction = NewRelic.getAgent().getTransaction();
// Add headers for outbound external request
transaction.insertDistributedTraceHeaders(outboundHeaders);
CloseableHttpClient connection = HttpClientBuilder.create().build();
CloseableHttpResponse response = connection.execute(request);
// Wrap the incoming Response object
Headers inboundHeaders = new HeadersWrapper(response);
// Create an input parameter object for a call to an external HTTP service
ExternalParameters params = HttpParameters
.library("HttpClient")
.uri(uri)
.procedure("execute")
.inboundHeaders(inboundHeaders)
.build();
// Obtain a reference to the method currently being traced
TracedMethod tracedMethod = NewRelic.getAgent().getTracedMethod();
// Report a call to an external HTTP service
tracedMethod.reportAsExternal(params);
return response.getStatusLine().getStatusCode();
}
// Implement Headers interface to create a wrapper for the outgoing Request/incoming Response headers
static class HeadersWrapper implements Headers {
private final HttpMessage delegate;
public HeadersWrapper(HttpMessage request) {
this.delegate = request;
}
@Override
public void setHeader(String name, String value) {
delegate.setHeader(name, value);
}
@Override
public HeaderType getHeaderType() {
return HeaderType.HTTP;
}
@Override
public String getHeader(String name) {
return delegate.getFirstHeader(name).getValue();
}
@Override
public Collection<String> getHeaders(String name) {
return Arrays.stream(delegate.getHeaders(name))
.map(NameValuePair::getValue)
.collect(Collectors.toList());
}
@Override
public void addHeader(String name, String value) {
delegate.addHeader(name, value);
}
@Override
public Collection<String> getHeaderNames() {
return Arrays.stream(delegate.getAllHeaders())
.map(NameValuePair::getName)
.collect(Collectors.toSet());
}
@Override
public boolean containsHeader(String name) {
return Arrays.stream(delegate.getAllHeaders())
.map(NameValuePair::getName)
.anyMatch(headerName -> headerName.equals(name));
}
}
@Trace
public void createDB() {
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:/tmp/test.db");
System.out.println("Opened database successfully");
stmt = c.createStatement();
String dropSql = "DROP TABLE IF EXISTS COMPANY;";
stmt.executeUpdate(dropSql);
String sql = "CREATE TABLE COMPANY " +
"(ID INT PRIMARY KEY NOT NULL," +
" NAME TEXT NOT NULL, " +
" AGE INT NOT NULL, " +
" ADDRESS CHAR(50), " +
" SALARY REAL)";
stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " +
"VALUES (1, 'Paul', 32, 'California', 20000.00 );";
stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " +
"VALUES (2, 'Allen', 25, 'Texas', 15000.00 );";
stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " +
"VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );";
stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " +
"VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );";
stmt.executeUpdate(sql);
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
}
}ここでは、同じクライアントアプリのコードを、APIの使用方法を説明するセクションに分けています。
このセクションでは、サンプルコードの後半で、クライアントアプリケーションに分散型トレースを追加するために使用するJavaエージェントAPIインポートを呼び出します。
import java.io.IOException;import java.net.URI;import java.net.URISyntaxException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.Statement;import java.util.Arrays;import java.util.Collection;import java.util.stream.Collectors;
// New Relic API importsimport com.newrelic.api.agent.ExternalParameters;import com.newrelic.api.agent.HeaderType;import com.newrelic.api.agent.Headers;import com.newrelic.api.agent.HttpParameters;import com.newrelic.api.agent.NewRelic;import com.newrelic.api.agent.Trace;import com.newrelic.api.agent.TracedMethod;import com.newrelic.api.agent.Transaction;
import fi.iki.elonen.NanoHTTPD;import org.apache.http.HttpMessage;import org.apache.http.NameValuePair;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpUriRequest;import org.apache.http.client.methods.RequestBuilder;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClientBuilder;このセクションでは、ポート 8080 でクライアント サーバーを起動し、API のNewRelicクラスを使用してメソッドsetServerInfo 、 setAppServerPort 、およびsetInstanceNameを呼び出します。これらの API 呼び出しは、New Relic UI に表示される内容に影響します。
public NewRelicApiExample() throws IOException, URISyntaxException { super(8080);
// Set Dispatcher name and version NewRelic.setServerInfo("NanoHttp", "2.3.1"); // Set Appserver port for jvm identification NewRelic.setAppServerPort(8080); // Set JVM instance name NewRelic.setInstanceName("Client");
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); System.out.println("Running at: http://localhost:8080/");}
public static void main(String[] args) throws URISyntaxException { try { new NewRelicApiExample(); } catch (IOException ioe) { System.err.println("Unable to start the server:\n" + ioe); }}このメソッドは、サンプル データベースを作成し、スレッドをスリープ状態にし、ポート 8081 でリッスンしているサーバー アプリに外部呼び出しを行います。 @Trace(dispatcher = true)アノテーションは、serve メソッドが既存のトランザクションの一部として呼び出されない場合 (この場合は呼び出されない場合)、新しいトランザクションを開始するようにエージェントに指示します。既存のトランザクションの一部として呼び出された場合、新しいトランザクションを開始するのではなく、単にそのトランザクションの一部として含まれます。
@Trace(dispatcher = true)@Overridepublic Response serve(IHTTPSession session) { URI uri = null; int status = 0;
try { createDB(); Thread.sleep(1000); uri = new URI("http://localhost:8081"); status = makeExternalCall(uri); } catch (URISyntaxException | InterruptedException | IOException e) { e.printStackTrace(); }
if (status == 200) { return newFixedLengthResponse("<html><body><h1>Successful Response</h1>\n</body></html>\n"); } else { return newFixedLengthResponse("<html><body><h1>Error\n" + status + "</h1>\n</body></html>\n"); }}このセクションには、リクエストを行うアプリケーションへの分散トレースを開始するコードが含まれています。@Traceアノテーションは、 serveメソッドによって開始された既存のトランザクションの一部として、このメソッドを追跡するようにエージェントに指示します。
リクエスト オブジェクトは、Java エージェント API のHeadersインターフェースを実装するクラスによってラップされます。これにより、適切なHeaderTypeが設定されます (この場合はHTTP )。insertDistributedTraceHeadersを呼び出すと、ヘッダーがrequestに追加され、リクエストがサーバーに送信されます。
responseが返されると、Java エージェント API のInboundHeadersインターフェースを実装するクラスによってラップされます。HeadersはInboundHeadersのサブ インターフェースであり、この場合、ラッパー クラスを再利用できます。
inboundHeadersは、"library"、URI、および"procedure"引数とともに、HttpParametersオブジェクトを構築するために使用されます。次に、 params オブジェクトが引数として reportAsExternal メソッドに渡され、 TracedMethod が外部 HTTP 呼び出しとして報告されます。
@Tracepublic int makeExternalCall(URI uri) throws IOException { HttpUriRequest request = RequestBuilder.get().setUri(uri).build();
// Wrap the outbound Request object Headers outboundHeaders = new HeadersWrapper(request);
// Obtain a reference to the current transaction Transaction transaction = NewRelic.getAgent().getTransaction(); // Add headers for outbound external request transaction.insertDistributedTraceHeaders(outboundHeaders);
CloseableHttpClient connection = HttpClientBuilder.create().build(); CloseableHttpResponse response = connection.execute(request);
// Wrap the incoming Response object Headers inboundHeaders = new HeadersWrapper(response);
// Create an input parameter object for a call to an external HTTP service ExternalParameters params = HttpParameters .library("HttpClient") .uri(uri) .procedure("execute") .inboundHeaders(inboundHeaders) .build();
// Obtain a reference to the method currently being traced TracedMethod tracedMethod = NewRelic.getAgent().getTracedMethod(); // Report a call to an external HTTP service tracedMethod.reportAsExternal(params);
return response.getStatusLine().getStatusCode();}Java エージェント API のHeadersインターフェースの実装を使用して、クライアント サーバーのリクエスト オブジェクトをラップします。この例では、タイプはHttpUriRequestです。リクエストはHeadersWrapperクラスのコンストラクターに渡され、必要なメソッドの実装が提供されます。
getHeaderTypeメソッドは、Java エージェント API で定義されているように、 HeaderType.HTTPまたはHeaderType.MESSAGEのいずれかになるHeaderType列挙を返します。この例では、外部呼び出しプロトコルが HTTP であるため、 HeaderType.HTTPが返されます。
// Implement Headers interface to create a wrapper for the outgoing Request/incoming Response headersstatic class HeadersWrapper implements Headers { private final HttpMessage delegate;
public HeadersWrapper(HttpMessage request) { this.delegate = request; }
@Override public void setHeader(String name, String value) { delegate.setHeader(name, value); }
@Override public HeaderType getHeaderType() { return HeaderType.HTTP; }
@Override public String getHeader(String name) { return delegate.getFirstHeader(name).getValue(); }
@Override public Collection<String> getHeaders(String name) { return Arrays.stream(delegate.getHeaders(name)) .map(NameValuePair::getValue) .collect(Collectors.toList()); }
@Override public void addHeader(String name, String value) { delegate.addHeader(name, value); }
@Override public Collection<String> getHeaderNames() { return Arrays.stream(delegate.getAllHeaders()) .map(NameValuePair::getName) .collect(Collectors.toSet()); }
@Override public boolean containsHeader(String name) { return Arrays.stream(delegate.getAllHeaders()) .map(NameValuePair::getName) .anyMatch(headerName -> headerName.equals(name)); }}このメソッドは、サンプルの SQLite データベースを作成するだけです。@Traceアノテーションは、 serveメソッドによって開始された既存のトランザクションの一部として、このメソッドを追跡するようにエージェントに指示します。
@Tracepublic void createDB() { Connection c = null; Statement stmt = null;
try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:/tmp/test.db"); System.out.println("Opened database successfully");
stmt = c.createStatement();
String dropSql = "DROP TABLE IF EXISTS COMPANY;"; stmt.executeUpdate(dropSql);
String sql = "CREATE TABLE COMPANY " + "(ID INT PRIMARY KEY NOT NULL," + " NAME TEXT NOT NULL, " + " AGE INT NOT NULL, " + " ADDRESS CHAR(50), " + " SALARY REAL)"; stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (1, 'Paul', 32, 'California', 20000.00 );"; stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (2, 'Allen', 25, 'Texas', 15000.00 );"; stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );"; stmt.executeUpdate(sql);
sql = "INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) " + "VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );"; stmt.executeUpdate(sql);
stmt.close(); c.close(); } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); System.exit(0); }}サーバーサイドの例
以下は、このアプリケーション例のサーバー側のコードです。
package com.newrelic.example;
import java.io.IOException;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Collection;
import java.util.Collections;
// New Relic API imports
import com.newrelic.api.agent.DatastoreParameters;
import com.newrelic.api.agent.HeaderType;
import com.newrelic.api.agent.Headers;
import com.newrelic.api.agent.NewRelic;
import com.newrelic.api.agent.Trace;
import com.newrelic.api.agent.TracedMethod;
import com.newrelic.api.agent.Transaction;
import com.newrelic.api.agent.TransportType;
import fi.iki.elonen.NanoHTTPD;
public class NewRelicApiServer extends NanoHTTPD {
public NewRelicApiServer() throws IOException, URISyntaxException {
super(8081);
// Set Dispatcher name and version
NewRelic.setServerInfo("NanoHttp", "2.3.1");
// Set Appserver port for jvm identification
NewRelic.setAppServerPort(8081);
// Set JVM instance name
NewRelic.setInstanceName("Server");
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false);
System.out.println("\nRunning on http://localhost:8081/ \n");
}
public static void main(String[] args) throws URISyntaxException {
try {
new NewRelicApiServer();
} catch (IOException ioe) {
System.err.println("Unable to start the server:\n" + ioe);
}
}
@Trace(dispatcher = true)
@Override
public Response serve(IHTTPSession session) {
// Obtain a reference to the current Transaction
Transaction tx = NewRelic.getAgent().getTransaction();
// Set the name of the current transaction
NewRelic.setTransactionName("Custom", "ExternalHTTPServer");
// Wrap the Request object
Headers req = new HeadersWrapper(session);
// Set the request for the current transaction and convert it into a web transaction
tx.acceptDistributedTraceHeaders(TransportType.HTTP, req);
queryDB();
return newFixedLengthResponse("<html><body><h1>SuccessfulResponse</h1>\n</body></html>\n");
}
// Implement Headers interface to create a wrapper for the outgoing Request/incoming Response headers
static class HeadersWrapper implements Headers {
private final IHTTPSession delegate;
public HeadersWrapper(IHTTPSession request) {
this.delegate = request;
}
@Override
public HeaderType getHeaderType() {
return HeaderType.HTTP;
}
@Override
public String getHeader(String name) {
return delegate.getHeaders().get(name);
}
@Override
public Collection<String> getHeaders(String name) {
return Collections.singletonList(getHeader(name));
}
@Override
public void setHeader(String name, String value) {
delegate.getHeaders().put(name, value);
}
@Override
public void addHeader(String name, String value) {
delegate.getHeaders().put(name, value);
}
@Override
public Collection<String> getHeaderNames() {
return delegate.getHeaders().keySet();
}
@Override
public boolean containsHeader(String name) {
return delegate.getHeaders().containsKey(name);
}
}
@Trace
public void queryDB() {
Connection c = null;
Statement stmt = null;
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:/tmp/test.db");
c.setAutoCommit(false);
System.out.println("Opened database successfully");
stmt = c.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM COMPANY;");
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String address = rs.getString("address");
float salary = rs.getFloat("salary");
System.out.println("ID = " + id);
System.out.println("NAME = " + name);
System.out.println("AGE = " + age);
System.out.println("ADDRESS = " + address);
System.out.println("SALARY = " + salary);
System.out.println();
}
rs.close();
stmt.close();
c.close();
} catch (Exception e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
System.exit(0);
}
// Obtain a reference to the method currently being traced
TracedMethod method = NewRelic.getAgent().getTracedMethod();
// Create a DatastoreParameters object and report a call to an external datastore service
method.reportAsExternal(
DatastoreParameters
.product("sqlite")
.collection("test.db")
.operation("select")
.instance("localhost", 8080)
.databaseName("test.db")
.build());
}
}ここでは、同じサーバーコードの例を、APIがどのように使用されるかを説明するセクションに分けています。
このセクションでは、外部データストア呼び出しの分散型トレースとレポートをサーバーアプリケーションに追加するために必要な、関連するJavaエージェントAPIのインポートを示します。
import java.io.IOException;import java.net.URISyntaxException;import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.Statement;import java.util.Collection;import java.util.Collections;
// New Relic API importsimport com.newrelic.api.agent.DatastoreParameters;import com.newrelic.api.agent.HeaderType;import com.newrelic.api.agent.Headers;import com.newrelic.api.agent.NewRelic;import com.newrelic.api.agent.Trace;import com.newrelic.api.agent.TracedMethod;import com.newrelic.api.agent.Transaction;import com.newrelic.api.agent.TransportType;
import fi.iki.elonen.NanoHTTPD;このセクションでは、ポート 8081 でサーバーを起動し、API のNewRelicクラスを使用してメソッドsetServerInfo 、 setAppServerPort 、およびsetInstanceNameを呼び出します。これらの API 呼び出しは、APM UI に表示される内容に影響します。
public NewRelicApiServer() throws IOException, URISyntaxException { super(8081);
// Set Dispatcher name and version NewRelic.setServerInfo("NanoHttp", "2.3.1"); // Set Appserver port for jvm identification NewRelic.setAppServerPort(8081); // Set JVM instance name NewRelic.setInstanceName("Server");
start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); System.out.println("\nRunning on http://localhost:8081/ \n");}
public static void main(String[] args) throws URISyntaxException { try { new NewRelicApiServer(); } catch (IOException ioe) { System.err.println("Unable to start the server:\n" + ioe); }}@Trace(dispatcher = true)アノテーションは、serve メソッドが既存のトランザクションの一部として呼び出されていない場合 (この場合は呼び出されない場合)、新しいトランザクションを開始するようにエージェントに指示します。既存のトランザクションの一部として呼び出された場合、新しいトランザクションを開始するのではなく、単にそのトランザクションの一部として含まれます。
現在のTransactionへの参照はgetTransactionへの呼び出しによって取得され、トランザクションの名前はsetTransactionNameメソッドへの呼び出しによって設定されます。
この例ではタイプIHTTPSessionのリクエスト オブジェクトは、Java エージェント API のHeadersクラスを拡張するクラスを使用してラップされます。現在のTransactionは、ラップされたExtendedRequestを引数として取るsetWebRequestへの呼び出しを介して親トレースにリンクされます。
その後、データベースへの呼び出しが行われ、レスポンスオブジェクトが返されます。
@Trace(dispatcher = true)@Overridepublic Response serve(IHTTPSession session) { // Obtain a reference to the current Transaction Transaction tx = NewRelic.getAgent().getTransaction(); // Set the name of the current transaction NewRelic.setTransactionName("Custom", "ExternalHTTPServer");
// Wrap the Request object Headers req = new HeadersWrapper(session);
// Set the request for the current transaction and convert it into a web transaction tx.acceptDistributedTraceHeaders(TransportType.HTTP, req);
queryDB();
return newFixedLengthResponse("<html><body><h1>SuccessfulResponse</h1>\n</body></html>\n");}Java エージェント API のHeadersクラスの別の実装を使用して、サーバーのリクエスト オブジェクトをラップします。この例では、タイプはIHTTPSessionです。リクエストはHeadersWrapperクラスのコンストラクターに渡されます。このコンストラクターは、 getRequestURI 、 getHeader 、 getRemoteUser 、 getParameterNames 、 getParameterValues 、 getAttribute 、 getCookieValue 、 getHeaderTypeの実装を提供します。 、およびgetMethodメソッド。
getHeaderTypeメソッドは、Java エージェント API で定義されているように、 HeaderType.HTTPまたはHeaderType.MESSAGEのいずれかになるHeaderType列挙を返します。この例では、外部呼び出しプロトコルが HTTP であるため、 HeaderType.HTTPが返されます。
// Implement Headers interface to create a wrapper for the outgoing Request/incoming Response headersstatic class HeadersWrapper implements Headers { private final IHTTPSession delegate;
public HeadersWrapper(IHTTPSession request) { this.delegate = request; }
@Override public HeaderType getHeaderType() { return HeaderType.HTTP; }
@Override public String getHeader(String name) { return delegate.getHeaders().get(name); }
@Override public Collection<String> getHeaders(String name) { return Collections.singletonList(getHeader(name)); }
@Override public void setHeader(String name, String value) { delegate.getHeaders().put(name, value); }
@Override public void addHeader(String name, String value) { delegate.getHeaders().put(name, value); }
@Override public Collection<String> getHeaderNames() { return delegate.getHeaders().keySet(); }
@Override public boolean containsHeader(String name) { return delegate.getHeaders().containsKey(name); }}このメソッドは、クライアントによって作成された SQLite データベースへの外部呼び出しを行います。@Traceアノテーションは、 serveメソッドによって開始された既存のトランザクションの一部として、このメソッドを追跡するようにエージェントに指示します。
現在のTracedMethodへの参照は、 getTracedMethodへの呼び出しを介して取得されます。その後、ビルダー パターンを使用してDatastoreParametersオブジェクトが作成されます。次に、 ExternalParametersオブジェクトが引数としてreportAsExternalメソッドに渡されます。これにより、 TracedMethodが外部データストア呼び出しとして報告されます。
@Tracepublic void queryDB() { Connection c = null; Statement stmt = null; try { Class.forName("org.sqlite.JDBC"); c = DriverManager.getConnection("jdbc:sqlite:/tmp/test.db"); c.setAutoCommit(false); System.out.println("Opened database successfully");
stmt = c.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM COMPANY;"); while (rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); int age = rs.getInt("age"); String address = rs.getString("address"); float salary = rs.getFloat("salary"); System.out.println("ID = " + id); System.out.println("NAME = " + name); System.out.println("AGE = " + age); System.out.println("ADDRESS = " + address); System.out.println("SALARY = " + salary); System.out.println(); } rs.close(); stmt.close(); c.close(); } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); System.exit(0); } // Obtain a reference to the method currently being traced TracedMethod method = NewRelic.getAgent().getTracedMethod();
// Create a DatastoreParameters object and report a call to an external datastore service method.reportAsExternal( DatastoreParameters .product("sqlite") .collection("test.db") .operation("select") .instance("localhost", 8080) .databaseName("test.db") .build());}