このドキュメントでは、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());}