Tutorial: Instrumentierung eines benutzerdefinierten Java HTTP Frameworks mit dem Instana Tracing SDK
Der Instana-Agent unterstützt viele Java-HTTP-Frameworks und in den meisten Fällen wird Tracing ohne Vorbereitungs- oder Anpassungsaufwand unterstützt, sobald Sie den Java-Agenten ausführen.
Falls Sie jedoch einen benutzerdefinierten internen HTTP haben, der nicht unterstützt wird, können Sie das Java Trace SDK verwenden, um Tracing für Ihr Framework hinzuzufügen.
In diesem Lernprogramm wird gezeigt, wie Sie dies tun können.
Beispielcode
Der Beispielcode für das Lernprogramm custom-http-sample
finden Sie unter github.com. Er implementiert das folgende Szenario:
Wenn Sie das Beispiel ausführen und http://localhost:8080öffnen, erhalten Sie die Antwort Hello, Stan!
. Wenn Sie jedoch die Aufrufe in Instana analysieren, werden Sie feststellen, dass der
Trace unterbrochen ist.
Spur 1:
Spur 2:
Die abgehenden Anforderungen werden mithilfe des Apache-HTTP-Clients implementiert, der vom automatischen
Tracing von Instana unterstützt wird. Der fehlende Link ist die Eingangsspanne (eingehender Aufruf) GET /greeting
beim angepassten HTTP-Server.
Tracing für angepassten HTTP-Server aktivieren
Bei unterstützten Frameworks werden die Java-Anwendungen vom Instana-Agenten automatisch instrumentiert. Bei einem angepassten HTTP-Server müssen einige Annotationen hinzugefügt werden, um dem Instana-Agenten mitzuteilen, welche Methodenaufrufe eine neue Spanne starten sollen.
Fügen Sie als erstes mvn dependency hinzu.
<dependency>
<groupId>com.instana</groupId>
<artifactId>instana-java-sdk</artifactId>
<version>1.2.0</version>
</dependency>
Fügen Sie als zweites eine Annotation vom Typ @Span
zu der Methode hinzu, von der die
HTTP-Anforderung auf dem angepassten HTTP-Server verarbeitet wird.
@Span(type = Span.Type.ENTRY, value = "my-custom-http-server")
public String apply(Map<String, String> headers) {
// ...
}
Diese Annotation weist den Java-Agenten an, einen ENTRY
-Bereich zu generieren (siehe). Server span), wenn diese Methode aufgerufen wird.
Fügen Sie als drittes zur Datei configuration.yaml
des Instana-Agenten das Folgende hinzu, um
anzugeben, dass Java-Klassen im Paket com.instana.sample.*
auf die Annotation
@Span
hin durchsucht werden sollen:
com.instana.plugin.javatrace:
instrumentation:
sdk:
packages:
- 'com.instana.sample'
Jetzt wird der angepasste Server instrumentiert und Sie sehen, dass der abgehende Aufruf an /name
vom
eingehenden Aufruf an /greeting
ausgelöst wird.
Der Trace ist jedoch immer noch unterbrochen, da die Trace-ID nicht zwischen dem eingehenden Aufruf und dem abgehenden Aufruf übertragen wird.
Eingehende Tracing-Header handhaben
Instana verwendet die folgenden HTTP-Header, um Traceinformationen von einem Service zum nächsten zu übergeben:
X-INSTANA-T
: Trace-IDX-INSTANA-S
: ID der übergeordneten SpanneX-INSTANA-L
: Ebene bzw. Level0
bedeutet, dass der Trace unterdrückt werden soll, was bei Zustandsprüfungen nützlich sein kann
Um den Tracekontext auf dem angepassten HTTP-Server korrelieren zu können, müssen Sie die folgende Methode zu
GreetingHandler
hinzufügen:
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);
}
}
Beachten Sie, dass wir die Header nach ihrer Evaluierung wieder entfernen und somit nur die ursprünglichen Header bleiben, als wenn sie ohne Instana-Tracing gesendet würden.
Jedoch können Sie nicht nur correlateTracing()
in
apply()
aufrufen, da die Header evaluiert werden müssen, bevor die Methode mit der Annotation
@Span
aufgerufen wird. Als Workaround können Sie die Methode apply()
in doApply()
umbenennen und einen Schritt wie folgt hinzufügen:
@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) {
// ...
}
Wenn Sie nun curl http://localhost:8080
ausführen, wird der vollständige Trace in Instana angezeigt.