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:

Lernprogramm für angepasste HTTP-Server

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: Traceerstellung Screenshot 01

Spur 2: Traceerstellung Screenshot 02

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.

Traceerstellung Screenshot 03

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-ID
  • X-INSTANA-S: ID der übergeordneten Spanne
  • X-INSTANA-L: Ebene bzw. Level 0 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:8080ausführen, wird der vollständige Trace in Instana angezeigt.

Traceerstellung Screenshot 04

Tags hinzufügen

Bisher ist unsere my-custom-http-server-Spanne nur eine generische ENTRY-Spanne ohne zusätzliche Annotationen. Wenn man sich die Details näher betrachtet, sehen diese ziemlich leer aus.

Bereich ohne Annotationen

Sie können die Methode SpanSupport.annotate() des SDK in einem aktiven @Span-Kontext aufrufen, um Annotationen zur aktuellen Spanne hinzuzufügen. Instana unterstützt einen Teil der semantischen Konventionen OpenTracing's, wie in der Java Trace SDK Dokumentation beschrieben. Zum Hinzufügen von HTTP-Annotationen fügen Sie die folgenden Zeilen oben in der Methode doApply() hinzu:

@Span(type = Span.Type.ENTRY, value = SPAN_NAME)
private String doApply(Map<String, String> headers) {
  SpanSupport.annotate(Span.Type.ENTRY, SPAN_NAME,"tags.http.url", "http://localhost:8080/greeting");
  SpanSupport.annotate(Span.Type.ENTRY, SPAN_NAME,"tags.http.method", "GET");
  SpanSupport.annotate(Span.Type.ENTRY, SPAN_NAME,"tags.http.status_code", "200");
  // ...
}

Jetzt enthalten die Details der ENTRY-Spanne für den angepassten HTTP-Server die angegebenen HTTP-Metadaten.

Bereich mit Annotationen

Beachten Sie, dass die entsprechende EXIT-Spanne von Jetty bis zum angepassten HTTP-Server bereits HTTP-Metadaten enthalten hat, da der Client den Apache-HTTP-Client verwendet, der vom automatischen Tracing von Instana unterstützt wird.

Spanne als fehlerhaft kennzeichnen

An einem bestimmten Punkt möchten Sie möglicherweise einen Aufruf als fehlerhaft kennzeichnen. Dies kann einfach durch Hinzufügen des ' error -Tags geschehen, wie in den semantischen KonventionenOpenTracing's festgelegt.

SpanSupport.annotate(Span.Type.ENTRY, SPAN_NAME,"tags.error", "true");

Durch das Hinzufügen von dieser Zeile wird Ihr Aufruf als fehlerhaft in Instana angezeigt.

Fehlerhafte Spannweite

Zusammenfassung und Ausblick

In diesem Lernprogramm wurde die wichtigste API vorgestellt, die erforderlich ist, um ein angepasstes HTTP-Framework mit dem verteilten Tracing von Instana zu instrumentieren.

Eine vollständige Referenz zu unserem SDK finden Sie im JavaDocdes SDK. Mithilfe der Annotationen @SpanParam und @SpanReturn können Sie beispielsweise Parameter oder Rückgabewerte als zusätzliche Informationen auf einfache Weise erfassen, was möglicherweise bequemer ist, als explizit SpanSupport.annotate() in einigen Szenarios aufzurufen.