コンテンツにスキップ

Trace 設定

Trace 初期設定

FTSdk.initTraceWithConfig(new FTTraceConfig()
    .setSamplingRate(0.8f)
    .setEnableAutoTrace(true)
    .setEnableLinkRUMData(true));
FTSdk.initTraceWithConfig(
    FTTraceConfig()
        .setSamplingRate(0.8f)
        .setEnableAutoTrace(true)
        .setEnableLinkRUMData(true)
)
メソッド名 タイプ 必須 説明
setSamplingRate Float いいえ サンプリングレートを設定します。値の範囲は [0,1] で、0 はサンプリングなし、1 は全サンプリング、デフォルト値は 1 です。
setTraceType TraceType いいえ 分散型トレーシングのタイプを設定します。デフォルトは DDTrace です。現在サポートされているのは ZipkinJaegerDDTraceSkywalking (8.0+)TraceParent (W3C) です。OpenTelemetry に接続する際に対応するトレースタイプを選択する場合は、サポートされているタイプと agent の関連設定を確認してください。
setEnableLinkRUMData Boolean いいえ RUM データと関連付けるかどうかを指定します。デフォルトは false です。
setEnableAutoTrace Boolean いいえ 自動 HTTP トレースを有効にするかどうかを設定します。この設定は ft-plugin に依存し、現在は OkHttp の自動トレースのみをサポートしています。デフォルトは false です。
setOkHttpTraceHeaderHandler Callback いいえ ASM でグローバルな FTTraceInterceptor.HeaderHandler を設定します。デフォルトでは設定されません。ft-sdk 1.6.8 以降でサポートされています。ft-sdk 1.6.17 以降では、getTraceContext(Request) をオーバーライドすることで、Header、traceIdspanId を一度に返すことが推奨されます。サンプルはカスタム Trace を参照してください。

Tracer ネットワーク分散型トレーシング

FTTraceConfigenableAutoTrace を有効にすると自動的にトレースデータが追加されます。または、手動で FTTraceManager を使用して HTTP リクエストに Propagation Header を追加することもできます。以下に例を示します。

String url = "https://request.url";
String uuid = "uuid";
// トレースヘッダーパラメータを取得
Map<String, String> headers = FTTraceManager.get().getTraceHeader(uuid, url);

OkHttpClient client = new OkHttpClient.Builder().addInterceptor(chain -> {
    Request original = chain.request();
    Request.Builder requestBuilder = original.newBuilder();
    // リクエストにトレースヘッダーパラメータを追加
    for (String key : headers.keySet()) {
        requestBuilder.header(key, headers.get(key));
    }
    Request request = requestBuilder.build();

    Response response = chain.proceed(request);

    if (response != null) {
        Map<String, String> requestHeaderMap = new HashMap<>();
        Map<String, String> responseHeaderMap = new HashMap<>();
        for (Pair<String, String> header : response.request().headers()) {
            requestHeaderMap.put(header.first, header.second);
        }
        for (Pair<String, String> header : response.headers()) {
            responseHeaderMap.put(header.first, header.second);
        }
    }

    return response;
}).build();

Request.Builder builder = new Request.Builder().url(url).method(RequestMethod.GET.name(), null);
client.newCall(builder.build()).execute();
val url = "https://request.url"
val uuid = "uuid"
// トレースヘッダーパラメータを取得
val headers = FTTraceManager.get().getTraceHeader(uuid, url)

val client: OkHttpClient = OkHttpClient.Builder().addInterceptor { chain ->
    val original = chain.request()
    val requestBuilder = original.newBuilder()
    // リクエストにトレースヘッダーパラメータを追加
    for (key in headers.keys) {
        requestBuilder.header(key!!, headers[key]!!)
    }
    val request = requestBuilder.build()

    val response = chain.proceed(request)

    if (response != null) {
        val requestHeaderMap = HashMap<String, String>()
        val responseHeaderMap = HashMap<String, String>()
        request.headers.forEach {
            requestHeaderMap[it.first] = it.second
        }
        response.headers.forEach {
            responseHeaderMap[it.first] = it.second
        }
    }

    response
}.build()

val builder: Request.Builder = Request.Builder().url(url).method(RequestMethod.GET.name, null)
client.newCall(builder.build()).execute()

OkHttp Interceptor による Resource と TraceHeader のカスタマイズ

Resource

FTRUMConfig.setEnableTraceUserResource(true) または FTRUMConfig.setOkHttpResourceContentHandler(...) が有効な場合、OkHttp のカスタム Interceptor が優先的に読み込まれます。

new OkHttpClient.Builder()
    .addInterceptor(new FTTraceInterceptor())
    .addInterceptor(new FTResourceInterceptor(new FTResourceInterceptor.ContentHandlerHelper() {
        @Override
        public void onRequest(Request request, HashMap<String, Object> extraData) {
            String contentType = request.header("Content-Type");
            extraData.put("df_request_header", request.headers().toString());
            if ("application/json".equals(contentType) ||
                    "application/x-www-form-urlencoded".equals(contentType) ||
                    "application/xml".equals(contentType)) {
                extraData.put("df_request_body", request.body());
            }
        }

        @Override
        public void onResponse(Response response, HashMap<String, Object> extraData) throws IOException {
            String contentType = response.header("Content-Type");
            extraData.put("df_response_header", response.headers().toString());
            if ("application/json".equals(contentType) ||
                    "application/xml".equals(contentType)) {
                // 大量データ処理を避けるため、body の一部をコピーして読み取り
                ResponseBody body = response.peekBody(33554432);
                extraData.put("df_response_body", body.string());
            }
        }

        @Override
        public void onException(Exception e, HashMap<String, Object> extraData) {
        }
    }))
    .eventListenerFactory(new FTResourceEventListener.FTFactory())
    .build();
OkHttpClient.Builder()
    .addInterceptor(FTTraceInterceptor())
    .addInterceptor(FTResourceInterceptor(object : FTResourceInterceptor.ContentHandlerHelper {
        override fun onRequest(request: Request, extraData: HashMap<String, Any>) {
            val contentType = request.header("Content-Type")
            extraData["df_request_header"] = request.headers().toString()
            if ("application/json" == contentType ||
                "application/x-www-form-urlencoded" == contentType ||
                "application/xml" == contentType) {
                extraData["df_request_body"] = request.body()
            }
        }

        override fun onResponse(response: Response, extraData: HashMap<String, Any>) {
            val contentType = response.header("Content-Type")
            extraData["df_response_header"] = response.headers().toString()
            if ("application/json" == contentType ||
                "application/xml" == contentType) {
                // 大量データ処理を避けるため、応答体の一部をコピー
                val body = response.peekBody(33554432)
                extraData["df_response_body"] = body.string()
            }
        }

        override fun onException(e: Exception, extraData: HashMap<String, Any>) {
            // 例外処理
        }
    }))
    .eventListenerFactory(FTResourceEventListener.FTFactory())
    .build()

TraceHeader

FTTraceConfig.setEnableAutoTrace(true) または FTTraceConfig.setOkHttpTraceHeaderHandler(...) が有効な場合、OkHttp のカスタム Interceptor が優先的に読み込まれます。以下は W3C Trace Context の例です。

ft-sdk < 1.4.1 の場合は、FTTraceConfig.setEnableAutoTrace(false) で無効にする必要があります。 ft-sdk > 1.6.7 では、カスタム Trace Header と RUM データの関連付けをサポートしています。 ft-sdk >= 1.6.17 では、getTraceContext(Request) が追加され、リクエスト Header、traceIdspanId を一度に返せるようになりました。この方法を優先的に使用することを推奨します。

推奨方法:getTraceContext(Request) の使用

new OkHttpClient.Builder()
    .addInterceptor(new FTTraceInterceptor(new FTTraceInterceptor.HeaderHandler() {
        @Override
        public TraceContext getTraceContext(Request request) {
            HashMap<String, String> headers = FTTraceManager.get()
                    .getTraceHeader(request.url().toString());
            return TraceContext.Simple.fromTraceType(headers);
        }
    }))
    .addInterceptor(new FTResourceInterceptor())
    .eventListenerFactory(new FTResourceEventListener.FTFactory())
    .build();
OkHttpClient.Builder()
    .addInterceptor(
        FTTraceInterceptor(object : FTTraceInterceptor.HeaderHandler() {
            override fun getTraceContext(request: Request): TraceContext? {
                val headers = FTTraceManager.get().getTraceHeader(request.url.toString())
                return TraceContext.Simple.fromTraceType(headers)
            }
        })
    )
    .addInterceptor(FTResourceInterceptor())
    .eventListenerFactory(FTResourceEventListener.FTFactory())
    .build()

互換性のある旧方式:getTraceHeader / getTraceID / getSpanID の個別実装

new OkHttpClient.Builder()
    .addInterceptor(new FTTraceInterceptor(new FTTraceInterceptor.HeaderHandler() {
        private String[] splits;

        @Override
        public HashMap<String, String> getTraceHeader(Request request) {
            HashMap<String, String> map = new HashMap<>();

            String headerString = FTTraceManager.get()
                    .getTraceHeader(request.url().toString())
                    // header から propagation header を取得
                    .get(FTTraceHandler.W3C_TRACEPARENT_KEY);

            splits = headerString.split("-");
            map.put(W3C_TRACEPARENT_KEY, headerString);
            return map;
        }

        @Override
        public String getSpanID() {
            if (splits != null) {
                return splits[2];
            }
            return null;
        }

        @Override
        public String getTraceID() {
            if (splits != null) {
                return splits[1];
            }
            return null;
        }
    }))
    .addInterceptor(new FTResourceInterceptor())
    .eventListenerFactory(new FTResourceEventListener.FTFactory())
    .build();
OkHttpClient.Builder()
    .addInterceptor(
        FTTraceInterceptor(object : FTTraceInterceptor.HeaderHandler {
            private var splits: Array<String>? = null

            override fun getTraceHeader(request: Request): HashMap<String, String> {
                val map = HashMap<String, String>()

                val headerString = FTTraceManager.get()
                    .getTraceHeader(request.url.toString())
                    // header から propagation header を取得
                    .get(FTTraceHandler.W3C_TRACEPARENT_KEY)

                splits = headerString?.split("-")?.toTypedArray()

                headerString?.let {
                    map[W3C_TRACEPARENT_KEY] = it
                }

                return map
            }

            override fun getSpanID(): String? {
                return splits?.getOrNull(2)
            }

            override fun getTraceID(): String? {
                return splits?.getOrNull(1)
            }
        })
    )
    .addInterceptor(FTResourceInterceptor())
    .eventListenerFactory(FTResourceEventListener.FTFactory())
    .build()

OkHttp への ResourceID の追加

OkHttp Request に uuid を追加します。同じリクエストが高頻度で同時に発生するシナリオでは、有効にすることを推奨します。ft-plugin 1.3.5 以降、ft-sdk 1.6.10 以降で FTSDKConfig.setEnableOkhttpRequestTag(true) を有効にすると、自動的に RequestResourceID が追加されます。

new Request.Builder()
    .tag(ResourceID.class, new ResourceID());
Request.Builder()
    .tag(ResourceID::class.java, ResourceID())

フィードバック

このページは役に立ちましたか?