Java-Trace-SDK
Mithilfe des Trace SDK von Instana Java ( GitHub ) ist es möglich, Ein- und Ausgänge, die Instana noch nicht kennt, manuell zu instrumentieren sowie interessante Abschnitte von benutzerdefiniertem Code zu markieren. Darüber hinaus wird das Erstellen von angepassten Korrelationen zwischen Binärprotokollen und das Hinzufügen von benutzerdefinierten Schlüssel/Wert-Paaren zu Spannen (zum Extrahieren von relevanten Informationen) unterstützt.
Konfiguration
Um das konfigurationsbasierte „ Java “-Trace-SDK zu verwenden, müssen Sie das „ Java “-Trace-SDK wie unter „Aktivieren des „ Java “-Trace-SDK“ beschrieben aktivieren.
Ausgänge und Eingänge für angepasste Binärprotokolle
Die veröffentlichte Beispiel-App (https://github.com/instana/instana-java-sdk/tree/master/instana-java-sdk-sample) enthält einen CustomTCP -Server und -Client und veranschaulicht, wie das SDK zum Markieren von Einträgen, Exits und zum Ausführen von Korrelationen verwendet werden kann.
instana-java-sdk verwenden
Für das „ Java “ Trace SDK müssen Sie Ihrer Anwendung eine JAR-Datei hinzufügen. Diese JAR-Datei enthält die Annotationen und Helper-Klassen, die zum Kennzeichnen der Codeabschnitte verwendet werden, die von Instana verarbeitet werden sollen. Bei der Verwendung von Maven kann die Abhängigkeit ohne großen Aufwand hinzugefügt werden mit:
<dependency>
<groupId>com.instana</groupId>
<artifactId>instana-java-sdk</artifactId>
<version>1.2.0</version>
</dependency>
Das Artefakt instana-java-sdk ist über das zentrale Standardrepository von Maven verfügbar.
Wenn kein Agent das „ JVM “ überwacht – das diese Bibliothek enthält und Abschnitte aufweist, die mit Anmerkungen versehen sind –, verhalten sich diese wie No-Ops. Es ist sicher, die Annotationen zu verwenden, da sie keinerlei Auswirkungen haben, solange kein Agent die JVM überwacht. Damit ein Instana-Agent die Annotationen tatsächlich verwenden kann, müssen Sie angeben, welche Java-Paketnamen diese Annotationen enthalten. Das liegt daran, dass das Durchsuchen nach Annotationen ein ressourcenintensiver Vorgang ist und das Durchsuchen des gesamten Klassenpfads umfangreicher Anwendungen viel Zeit in Anspruch nehmen kann.
Der erforderliche configuration.yaml Abschnitt sieht wie folgt aus:
# Java Tracing
com.instana.plugin.javatrace:
instrumentation:
# By default no packages are scanned for SDK annotations.
sdk:
packages:
- 'com.mycompany.backend'
- 'com.mycompany.frontend'
Die Pakete werden rekursiv durchsucht. Wenn also com.mycompany.backend für das Durchsuchen nach
Annotationen konfiguriert ist, werden com.mycompany.backend.impl und andere Unterpakete ebenfalls durchsucht.
Zwischenspanne kennzeichnen
Um eine Methode in einer Zwischenspanne zu kennzeichnen, fügen Sie einfach die folgende Annotation hinzu:
@Span(value = "custom-tcp-server")
Bei der Zwischenspanne handelt es sich um den Standardtyp von SDK-Spannen, der verwendet wird, wenn keine andere Angabe erfolgt. Diese Art von Spannen kennzeichnen "interessante" Methoden in Ihrer Anwendung, für die Sie sich einen besseren Einblick wünschen. Bitte beachten Sie, dass dies kein Ersatz für einen echten Profiler ist, wie beispielsweise unseren Instana AutoProfile™.
Eingang kennzeichnen
Um eine Methode in einem Entry-Bereich zu kennzeichnen, fügen Sie einfach die folgende Anmerkung hinzu, wie in diesem Beispiel gezeigt:
@Span(type = Type.ENTRY, value = "custom-tcp-server")
Sobald Instana die Eingabe dieser Methode über Code erkennt, wird ein Trace gestartet. Eingangspannen weisen normalerweise auf eingehende Aufrufe von externen Systemen oder geplanten Tasks hin.
Ausgang kennzeichnen
Um eine Methode in einem Exit-Bereich zu kennzeichnen, fügen Sie einfach die folgende Anmerkung hinzu, wie in diesem Beispiel gezeigt:
@Span(type = Type.EXIT, value = "custom-tcp-client", capturedStackFrames = 5)
Wenn diese Methode erkannt wird, erfasst Instana eine Spanne mit einer Bezeichnung als Ausgangs-/Exitaufruf. Ausgänge kennzeichnen abgehende Aufrufe an externe Systeme.
Ausgang und Eingang korrelieren
In vielen Fällen, in denen Instana Eingang und Ausgang noch nicht bekannt sind, verwenden Anwendungen sie für eine Art von ferner Datenübertragung. Wenn ein Ausgang festgestellt und keine Korrelation ausgeführt wird, wird der Trace "unterbrochen", d. h. dass zwei Traces beobachtet werden: einer, der beim Ausgang endet, und ein neuer, der beim Eingang beginnt.
Es ist möglich, Instana beim Ausführen einer Korrelation zu unterstützen, indem Korrelationsinformationen manuell über die ferne Datenübertragung versendet werden. Auf der Ausgangsseite wird durch die Ausgangsannotation sichergestellt, dass die erforderlichen Korrelationskennungen vorhanden sind. Man kann einfach ( https://github.com/instana/instana-java-sdk/blob/master/instana-java-sdk/src/main/java/com/instana/sdk/support/SpanSupport.java#L182 ) aufrufen:
SpanSupport.addTraceHeadersIfTracing(Type.EXIT, params);
um die angegebene Parameterzuordnung mit den erforderlichen IDs zu füllen. Wenn das Protokoll andere Möglichkeiten zum Übertragen anderer Daten unterstützt, können die IDs auch über die folgenden Optionen abgerufen werden:
currentTraceId(type)
currentSpanId(type)
Auf der Eingangsseite ist es wichtig, die Parameter zu lesen und sie für die Eingangsspanne festzulegen, bevor die Spanne durch Annotationen erstellt wird:
SpanSupport.inheritNext(SpanSupport.stringAsId(trace), SpanSupport.stringAsId(span));
Dadurch verbindet sich die Eingangsspanne automatisch mit dem fernen Trace und wird als untergeordnete Spanne des aufrufenden Ausgangs hinzugefügt.
Konvertierung und Benennung
In bestimmten Situationen kann es von Vorteil sein, SDK-Spannen in einen anderen Typ wie HTTP oder RPC umzuwandeln, um den Ursprung dieser Spannen besser darzustellen. Dies kann durch Hinzufügen von Konvertierungs-Tags zu den Spans erfolgen, wie im Abschnitt „Verarbeitungs-Tags“ der Best Practices für benutzerdefiniertes Tracing beschrieben.
Diese Tags können mithilfe der Methode SpanSupport.annotate(type, name, key, value) festgelegt werden.
Instana behandelt diese Tags so, wie automatische Agenteninstrumentierung funktioniert, sobald diese Felder unter dem
Schlüssel tags. verschachtelt sind. Um beispielsweise das Feld http.url zu definieren,
würde der Methodenaufruf wie folgt aussehen:
SpanSupport.annotate(<type>, <name>, "tags.http.url", "service://my-awesome-service/some/path")
Ebenso ist es möglich, den Dienst, den Endpunkt und den Aufrufnamen zu ändern, wie auf der Seite „Best Practices für benutzerdefinierte Ablaufverfolgung“ beschrieben.
Wenn keine bestimmten Felder angegeben werden, lautet der Name des Service für alle SDK-Spannen
SDK. Der Endpunkt und der Aufrufname sind der angegebene Wert für name in der Annotation
@Span oder in der Methode SpanSupport.annotate().
Speichern und Wiederherstellen des Trace-Kontexts
Mit der Klasse ContextSupport kann der aktuelle Tracekontext gespeichert und wiederhergestellt werden. Die Methode takeSnapshot() speichert Tracekontextinformationen, wie z. B. Trace-ID und Bereichs-ID, in einer internen Map. Die Methode restoreSnapshot() liest die von der Methode takeSnapshot() gespeicherten Informationen und verwendet sie, um den aktuellen Tracekontext festzulegen. Diese Methoden sind in Situationen nützlich, in denen eine Anwendung die asynchrone Verarbeitung verwendet, um eine Task abzuschließen, und der Trace in einem anderen Thread fortgesetzt wird.
Der aktuelle Tracekontext kann beispielsweise wie folgt gespeichert werden:
snapShotKey = ContextSupport.takeSnapshot();
Anschließend kann der Tracekontext wie folgt in einem anderen Thread wiederhergestellt werden:
ContextSupport.restoreSnapshot(snapShotKey);
Lernprogramme
Die folgenden Lernprogramme führen Sie durch einige der allgemeinen Anwendungsfälle für das Java-Trace-SDK:
Fehlerbehebung
Werden keine SDK-Traces in der Benutzerschnittstelle angezeigt, lohnt sich die Überprüfung verschiedener Punkte:
- Ist die JAR-Datei
instana-java-sdkim Lieferumfang der Anwendung enthalten? Ist dies nicht der Fall, tut der Agent nichts, da er sich im Modusno-opbefindet. - Referenziert die Datei
configuration.yamlalle Pakete mit Annotationen? - Ist das Tracing aktiv?
- Stimmt die YAML-Syntax?
- Sind andere APM-Agenten aktiv? Die meisten anderen APM-Agenten sind dafür bekannt, Instana zu beeinträchtigen, sodass
der Instana-Agent kein Tracing ausführt, wenn er andere Agenten erkennt. Wenn dies der Fall ist, wird in den Protokollen
Folgendes angezeigt:
JVM <PID> is running the <3rdParty> agent, which is known to be causing problems for the Instana Agent. Tracing will not be enabled for this JVM. - Aktivieren Sie die DEBUG-Protokollierung und suchen Sie nach einer Meldung wie:
2016-09-05T08:26:14.094+0200 | DEBUG | na-http-thread-1 | LoggerEndpoint | 48 - com.instana.agent - 1.1.194 | JVM (11403). Successfully instrumented class com.acme.resources.HelloWorldResource [sun.misc.Launcher$AppClassLoader@3d4eac69]` 2016-09-05T08:26:14.145+0200 | DEBUG | na-http-thread-1 | LoggerEndpoint | 48 - com.instana.agent - 1.1.194 | JVM (11403) - Spent 188ms and 124kb transforming SDK classes. - Gibt es für die annotierten Methoden tatsächlich einen Treffer von einem Benutzer/Lasttreiber? Der Instana-Agent interagiert nach dem Start kurz mit jeder einzelnen JVM. Dies führt dazu, dass Transaktionen nicht erfasst werden, die vor dem Anschluss des Agenten erfolgt sind. Stellen Sie sicher, dass Sie Methoden, für die es normalerweise während der Lebensdauer der Anwendung Treffer gibt, mit Annotationen versehen.
- Befolgen Sie die Schritte im Abschnitt „Überprüfen Ihrer SDK-Konfiguration “.
Häufig gestellte Fragen
Warum zeigen erfasste Parameter- und Rückgabewerte nur Klassennamen und Hash-Speicheradressen an?
Die Instrumentierung ruft toString() für jeden erfassten Parameter- und Rückgabewert auf. Dies bedeutet,
dass die innerhalb von Instana sichtbaren Werte direkt von den spezifischen
toString()-Methodenimplementierungen der Klassen der Parameter- und Rückgabewerte abhängen.
Wenn toString() nicht überschrieben wird, wird letztendlich java.lang.Object#toString() verwendet. Diese
Methode gibt getClass().getName() + '@' + Integer.toHexString(hashCode()) zurück und führt zu dem angezeigten
Format.
Für einen besseren Einblick in erfasste Parameter. und Rückgabewerte wird empfohlen, toString()
ordnungsgemäß zu überschreiben.
Warum sind Rückgabewerte manchmal nicht verfügbar?
Rückgabewerte sind möglicherweise nicht verfügbar, obwohl captureReturn=true festgelegt ist, wenn ...
- eine Ausnahme von der Methode ausgelöst wird,
- die Methode einen
void-Rückgabetyp aufweist oder - die Methode
nullzurückgibt.