教程:使用 Instana 跟踪 SDK 仪器化自定义 Java HTTP 框架
Instana 代理程序支持许多 Java HTTP 框架,并且在大多数情况下,只要运行 Java 代理程序,就会立即支持现成的跟踪。
但是,如果具有不受支持的定制内部 HTTP 服务器,那么可以使用 Java Trace SDK 来为框架添加跟踪。
本教程说明了如何执行此操作。
示例代码
custom-http-sample 教程的示例代码可以在 github.com 中找到。 它实现了以下方案:

如果运行该示例并打开 http://localhost:8080,那么将获得响应 Hello, Stan!。 但是,如果分析 Instana 中的调用,那么将看到跟踪已中断。
跟踪 1: 
跟踪 2: 
出局请求是使用 Apache HTTP 客户机实现的,该客户机受 Instana 的自动跟踪支持。 缺少的链接是定制 HTTP Server 上的条目范围(入局呼叫)GET /greeting。
启用自定义跟踪 HTTP Server
对于受支持的框架,Instana 代理程序会自动检测 Java 应用程序。 对于定制 HTTP Server,我们需要添加一些注释,以告知 Instana 代理程序,哪些方法调用应该启动新的范围。
首先,添加 mvn 依赖关系
<dependency>
<groupId>com.instana</groupId>
<artifactId>instana-java-sdk</artifactId>
<version>1.2.0</version>
</dependency>
其次,在定制 HTTP 服务器为 HTTP 请求的方法添加 @Span 注释。
@Span(type = Span.Type.ENTRY, value = "my-custom-http-server")
public String apply(Map<String, String> headers) {
// ...
}
该注解告诉 Java 代理生成 ENTRY span(又称 "span")。 服务器 span)。
第三,将以下内容添加到 Instana 代理程序的 configuration.yaml 文件中,以告知它应该扫描包 com.instana.sample.* 中的 Java 类以获取 @Span 注释:
com.instana.plugin.javatrace:
instrumentation:
sdk:
packages:
- 'com.instana.sample'
现在,已检测到定制服务器,并且会看到针对 /name 的出局呼叫是从 /greeting 的入局呼叫触发的。

但是,由于在入局呼叫和出局呼叫之间未传递跟踪标识,因此跟踪仍处于中断状态。
处理传入的跟踪标题
Instana 使用以下 HTTP 头将跟踪信息从一个服务传递到下一个服务:
X-INSTANA-T: 跟踪标识X-INSTANA-S: 父范围标识X-INSTANA-L: 级别0表示应该禁止跟踪,这对于运行状况检查可能很有用
为了关联客户 HTTP Server 中的跟踪上下文,需要将以下方法添加到 GreetingHandler:
private void correlateTracing(Map<String, String> request) {
String level = request.remove(SpanSupport.LEVEL);
String traceId = request.remove(SpanSupport.TRACE_ID);
String parentSpanId = request.remove(SpanSupport.SPAN_ID);
if (SpanSupport.SUPPRESS.equals(level)) {
SpanSupport.suppressNext();
} else if (traceId != null && parentSpanId != null) {
SpanSupport.inheritNext(traceId, parentSpanId);
}
}
请注意,我们在评估头之后会将其移除,只保留原始头,因为将在不进行 Instana 跟踪的情况下发送这些头。
但是,不能仅在 apply() 中调用 correlateTracing(),因为在调用具有 @Span 注释的方法之前需要对头进行求值。 作为变通方法,可以将 apply() 方法重命名为 doApply(),并添加如下步骤:
@Override
public String apply(Map<String, String> headers) {
correlateTracing(headers);
return doApply(headers);
}
@Span(type = Span.Type.ENTRY, value = "my-custom-http-server")
private String doApply(Map<String, String> headers) {
// ...
}
现在运行 curl http://localhost:8080 时,将在 Instana 中看到完整的跟踪



