Trace Configuration¶
Trace Initialization Configuration¶
| Method Name | Type | Required | Description |
|---|---|---|---|
| setSamplingRate | Float | No | Sets the sampling rate, range [0,1]. 0 means no sampling, 1 means full sampling. Default is 1. |
| setTraceType | TraceType | No | Sets the type of trace. Default is DDTrace. Currently supports Zipkin, Jaeger, DDTrace, Skywalking (8.0+), TraceParent (W3C). When integrating OpenTelemetry and selecting the corresponding trace type, please refer to the supported types and agent configuration. |
| setEnableLinkRUMData | Boolean | No | Whether to correlate with RUM data. Default is false. |
| setEnableAutoTrace | Boolean | No | Sets whether to enable automatic HTTP Trace. This configuration depends on ft-plugin. Currently only supports automatic tracing for OkHttp. Default is false. |
| setOkHttpTraceHeaderHandler | Callback | No | ASM sets the global FTTraceInterceptor.HeaderHandler. Not set by default. Supported in ft-sdk 1.6.8 and above. Starting from ft-sdk 1.6.17, overriding getTraceContext(Request) is prioritized, which can return Header, traceId, and spanId at once. Example reference Custom Trace. |
Tracer Network Trace¶
Configure FTTraceConfig to enable enableAutoTrace for automatic trace data addition, or manually use FTTraceManager to add Propagation Header in HTTP requests, as shown below.
String url = "https://request.url";
String uuid = "uuid";
// Get trace header parameters
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();
// Add trace header parameters to the request
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"
// Get trace header parameters
val headers = FTTraceManager.get().getTraceHeader(uuid, url)
val client: OkHttpClient = OkHttpClient.Builder().addInterceptor { chain ->
val original = chain.request()
val requestBuilder = original.newBuilder()
// Add trace header parameters to the request
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()
Customizing Resource and TraceHeader via OKHttp Interceptor¶
Resource¶
When FTRUMConfig.setEnableTraceUserResource(true) or FTRUMConfig.setOkHttpResourceContentHandler(...) is enabled, custom Interceptor in OkHttp will be loaded first.
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)) {
// Copy and read part of the body to avoid high data processing consumption
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) {
// Copy part of the response body to avoid high data consumption
val body = response.peekBody(33554432)
extraData["df_response_body"] = body.string()
}
}
override fun onException(e: Exception, extraData: HashMap<String, Any>) {
// Handle exception cases
}
}))
.eventListenerFactory(FTResourceEventListener.FTFactory())
.build()
TraceHeader¶
When FTTraceConfig.setEnableAutoTrace(true) or FTTraceConfig.setOkHttpTraceHeaderHandler(...) is enabled, custom Interceptor in OkHttp will be loaded first. The following example uses W3C Trace Context.
When ft-sdk < 1.4.1,
FTTraceConfig.setEnableAutoTrace(false)needs to be disabled. ft-sdk > 1.6.7 supports custom Trace Header correlation with RUM data. ft-sdk >= 1.6.17 addsgetTraceContext(Request), which can return request Header,traceId, andspanIdat once. It is recommended to use this method first.
Recommended Method: Using 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()
Compatible Old Method: Implementing getTraceHeader / getTraceID / getSpanID Separately¶
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())
// Get propagation header from 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())
// Get propagation header from 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()
Adding ResourceID to OKHttp¶
Add uuid to OkHttp Request. It is recommended to enable this for high-frequency concurrent scenarios with the same request. After enabling FTSDKConfig.setEnableOkhttpRequestTag(true) in ft-plugin version 1.3.5 and above, and ft-sdk version 1.6.10 and above, ResourceID can be automatically added to the Request.