APM-Spans als JFR-Ereignisse aufzeichnen
APM-Tracer und APM-Agent unterstützen die Aufzeichnung von APM-Spans als JFR-Ereignisse.
Aktuell wird JDK 11 oder höher unterstützt.
Informationen zum Aufzeichnen von APM-Spans als JFR-Ereignisse bei Verwendung des APM-Agents finden Sie unter APM-Spans als JFR-Ereignisse aufzeichnen unter APM-Java-Agents auf Anwendungsservern durch Provisioning und Deployment bereitstellen.
Java Flight Recorder (JFR) ist ein Tool zum Erfassen von Diagnose- und Profilingdaten über eine ausgeführte Java-Anwendung. Informationen zu Java Flight Recorder (JFR) und Java Mission Control (JMC) finden Sie unter JDK Mission Control.
APM-Ereignisse in JFR-Aufzeichnungen erfassen
So erfassen Sie APM-Ereignisse in JFR-Aufzeichnungen bei Verwendung des APM-Tracers:
-
Stellen Sie sicher, dass der APM-Tracer ordnungsgemäß arbeitet.
Öffnen Sie den Trace-Explorer, und vergewissern Sie sich, dass Sie alle Traces anzeigen können. Informationen zum Öffnen und Verwenden des Trace-Explorers finden Sie unter Traces im Trace-Explorer überwachen.
-
Fügen Sie dem Maven-Projekt eine Abhängigkeit hinzu, mit der der APM-Tracer Ereignisse in die JFR-Aufzeichnungen der Helidon-JVM einfügen kann.
<dependency> <groupId>com.oracle.apm.agent.java</groupId> <artifactId>apm-java-agent-jfr11</artifactId> <version>[1.0.1389,)</version> </dependency>
-
Starten Sie eine Aufzeichnung.
Um zu testen, ob alles ordnungsgemäß funktioniert, müssen Sie anhand Ihrer bevorzugten Methode eine Aufzeichnung starten (entweder über die JDK Mission Control-UI oder das JCMD-Befehlszeilenutility). Nachdem eine Aufzeichnung gestartet wurde, werden Traceereignisse auf der JDK Mission Control-UI angezeigt, wenn die Aufzeichnung angezeigt wird.
Um zu überprüfen, ob APM-Traceereignisse ordnungsgemäß zu JFR-Aufzeichnungen hinzugefügt wurden, melden Sie sich bei JDK Mission Control an, und vergewissern Sie sich, dass die APM-Traces im Ereignisbrowser sichtbar sind: Klicken Sie auf APM OpenTracing, und vergewissern Sie sich, dass APM-Traceereignisse sichtbar sind.
JFR-Ereignisse im APM-Tracer konfigurieren
(Optional) Dieser Schritt ist optional, wenn Sie das Reporting der Ereignisse anpassen möchten.
Um die Analyse der JFR-Aufzeichnungsereignisse zu vereinfachen, ist jedes Ereignis in einer Kategorie oder einem Ereignistyp organisiert.
Standardkategorie
Im APM-Tracer wird die Standardkategorie für APM-JFR-Ereignisse anhand des Inhalts vonSpan Operation Name
(im Feld name
im Span) ermittelt. Das Tag component
kann nicht aufgefüllt werden und daher nicht als Standardkategorie verwendet werden.
Ereignisse
Mit einem Ereignistyp können die Ereignisse organisiert und auf der JMC-Benutzeroberfläche klassifiziert werden. Wenn der APM-Tracer einen Span abruft, kann er ein Ereignis für diesen Span generieren, muss jedoch den Ereignistyp dieses spezifischen Ereignisses ermitteln.
Beispiele für Ereignistypen sind servlet, jdbc und jax-rs.
Ereignistypkonfiguration
Die Konfiguration eines Ereignistyps oder einer Ereigniskategorie kann auf verschiedene Weise durchgeführt werden. Nachfolgend sind die verschiedenen Anwendungsfälle aufgeführt:
-
Fall 1:
component
-TagDies ist die einfachste Methode zur Klassifizierung eines Ereignisses. Dies ist die empfohlene Methode.
In den meisten Szenarios enthält der OpenTracing-Span das Tag
component
. Der Wert des Tagscomponent
wird zur Ermittlung des Ereignistyps herangezogen.Beispiel:
{ "id":"e926ff3d06013045", "trace-id":"49abd92e69786853e926ff3d06013045", "parent-id":"6ef54ec2c524c99a", "name":"content-write", "ts-micros":1614190751360177, "td-micros":219348, "attributes":{ "server":"Helidon SE", "http.url":"http://localhost:8079/health", "http.status_code":200, "component":"helidon-webserver", "http.method":"GET", "organization":"development" }, "events":[ ] },
In diesem Fall wird dem generierten Ereignis der Ereignistyp
helidon-webserver
zugewiesen, da dies der Wert des Tagscomponent
ist. -
Fall 2: Anderes Tag
Wenn die Anwendung nicht das Tag
component
, aber ein anderes Tag verwendet oder die Tags von einer Library generiert werden, kann der APM-Tracer so konfiguriert werden, dass der Ereignistyp aus diesem anderen Tag gelesen wird.Beispiel: Beim folgenden Span kann der Ereignistyp aus dem Tag
span.type
gelesen werden:{ "id":"e926ff3d06013045", "trace-id":"49abd92e69786853e926ff3d06013045", "parent-id":"6ef54ec2c524c99a", "name":"content-write", "ts-micros":1614190751360177, "td-micros":219348, "attributes":{ "server":"Helidon SE", "http.url":"http://localhost:8079/health", "http.status_code":200, "span.type":"helidon-webserver", "http.method":"GET", "organization":"development" }, "events":[ ] },
In diesem Fall kann der APM-Tracer den Ereignistyp aus dem Tag
span.type
lesen, indem Sie beim Starten der Java-Anwendung die folgende Systemeigenschaft verwenden:java -Dcom.oracle.apm.agent.jfr.category.tag=span.type ...
-
Fall 3: Vorgangsname verwenden, wenn keine Tags verfügbar sind
Wenn die Anwendung keine Tags mit nützlichen Kategorien verwendet, können Sie den Ereignistyp anhand von
Operation Name
ermitteln. Diese Methode wird jedoch nicht empfohlen.Das JFR-System erfordert, dass der Name des Ereignistyps eine gültige Java-ID ist.
Operation Name
enthält jedoch häufig Leerzeichen und auch andere unzulässige Zeichen. Der APM-Tracer konvertiertOperation Name
in eine gültige ID, indem alle unzulässigen Zeichen durch Unterstriche ersetzt werden.java -Dcom.oracle.apm.agent.jfr.category.default=ORACLE_APM_USE_SPAN_OPERATION_NAMES
Hinweis
Operation Name
wird nur verwendet, wenn das Kategorietag fehlt oder leer ist.Dies ist keine einfache Lösung, weil
Operation Name
eindeutige Token wie IDs enthalten kann, durch die jedes Ereignis einen eigenen Ereignistyp erhält. Darüber hinaus führt die Konvertierung vonOperation Name
in eine gültige ID zu weiteren Problemen bei der Konfiguration des Ereignistyps, um festzulegen, welche Felder im Ereignis benötigt werden. Außerdem muss die Konfiguration anhand des konvertiertenOperation Name
erfolgen, da andernfalls viele verschiedene Varianten vonOperation Name
auf dieselbe Weise konfiguriert werden müssten. -
Fall 4: Es sind keine Tags verfügbar, und alle Vorgangsnamen sind eindeutig.
In diesem Fall sind keine Informationen zur Klassifizierung der Ereignistypen verfügbar. Dies ist das Worst-Case-Szenario, bei dem alle Ereignisse den gleichen Ereignistyp erhalten. Dagegen erhalten alle Ereignisse einen eindeutigen Ereignistyp, wenn sie wie in Fall 3 oben beschrieben konfiguriert werden. Die einzige Möglichkeit dazu besteht darin, den Namen dieses Standardereignistyps auszuwählen. Dies kann wie nachfolgend beschrieben konfiguriert werden.
java -Dcom.oracle.apm.agent.jfr.category.default=Unknown
Hinweis
Der Standardwert wird nur verwendet, wenn das Kategorietag fehlt oder leer ist.In diesem Fall erhalten alle Ereignisse den Ereignistyp
Unknown
oder einen beliebigen benutzerdefinierten Wert.
Für jeden Ereignistyp kann mindestens ein Feld mit spezifischen Daten für dieses Ereignis hinzugefügt werden.
- Name.
- Typ (Ganzzahl, Float, Zeichenfolge, Thread).
- Label.
- Beschreibung.
- name: traceID
type: String
label: New Trace ID
description: New Opentracing Trace ID
ACML-Datei erstellen
Dies ist ein optionaler Schritt. Wenn die Standardeinstellungen wie erwartet funktionieren, können Sie diesen Schritt überspringen.
Sie können eine ACML-Datei erstellen, wenn Sie die Standardeinstellungen ändern und die Aufzeichnungen anpassen möchten.
Das folgende Beispiel zeigt das Format einer ACML-Datei zur Konfiguration des Ereignisloggings in JFR, indem die integrierten Standardeinstellungen für den Helidon-Microservices-Container überschrieben werden:
caseSensitiveFieldName: false
recordCallStack: true
eventTypes:
helidon-webserver:
name: helidon-webserver
label: Helidon Webserver Events
description: All events based on helidon webserver
recordCallStack: true
# All fields must be provided here.
# Fields are NOT incremental since that would make them impossible to remove
fields:
- name: traceID
type: String
label: New Trace ID
description: New Opentracing Trace ID
- name: spanID
type: String
label: New Span ID
description: New Opentracing Span ID
- name: http.url
type: String
label: New HTTP URL
description: The New URL for the HTTP endpoint being hit
- name: organization
type: String
label: Organization
description: The New Organization value of this call
- name: startThread
type: Thread
label: Start Thread
description: The thread on which this event started
- name: http.status_code
type: int
label: Status Code
description: The HTTP Response status code
- name: http.method
type: String
label: HTTP Method
description: The HTTP Method
Sie können das obige Format der ACML-Datei bei Verwendung von APM-Agent und APM-Tracer verwenden. Beim APM-Tracer funktioniert es für alle Container wie Helidon, Springboot und Micronaut.
Häufig gestellte Fragen
-
Welche Einstellung hat Priorität, wenn die Eigenschaften
com.oracle.apm.agent.jfr.category.tag
undcom.oracle.apm.agent.jfr.category.default
zusammen angegeben sind?Wenn beide einen Wert erhalten, wird zuerst im Span nach dem Kategorietag gesucht. Wenn es gefunden wird, wird es verwendet. Wenn es fehlt, wird der Standardwert verwendet.
-
Ist für den APM-Tracer eine Konfigurationsdatei erforderlich? Kann ich die Eigenschaften auch ohne Datei angeben?
Eine Konfigurationsdatei ist nicht erforderlich. Wenn die Standardeinstellung für Sie funktioniert, benötigen Sie keine Konfigurationsdatei und können dennoch die Eigenschaften angeben.
-
Warum sind in einigen Fällen Einträge scheinbar dupliziert? Beispiel: Das folgende Snippet aus der ACML-Konfigurationsdatei enthält den Eintrag
helidon-webserver
zweimal:eventTypes: helidon-webserver: name: helidon-webserver
Der erste Eintrag von
helidon-webserver
wird aus den Tags oder dem Vorgangsnamen gelesen. Wenn der Ereignistyp wie im obigen Beispiel klar, leicht lesbar und intuitiv ist, können Sie denselben Ereignistyp an die JFR-Aufzeichnung senden, sodass er auch in JMC angezeigt wird.Bei Verwendung vonoperation name
kann jedoch in bestimmten Fällen ein Ereignistyp wieq_AxPsCbac9Ykp0HjpU+ENCiYHKl5HzMCmR02AfGzow3A=
generiert werden. Hierbei handelt es sich um eine JDBC-Abfrage von einem DB-Client. In diesem Fall sollte der an die JFR-Aufzeichnung gesendete Name in einen intuitiven Namen geändert werden. Hierzu kann das folgende Beispiel verwendet werden:eventTypes: q_AxPsCbac9Ykp0HjpU+ENCiYHKl5HzMCmR02AfGzow3A=: name: jdbc-select-query
-
Warum muss
recordCallStack
auch auf der obersten Ebene vorhanden sein, wennrecordCallStack
für jeden Ereignistyp angegeben werden kann?Für maximale Flexibilität bei der Aufzeichnung des Aufrufstacks werden zwei Anwendungsfälle unterstützt. Die Aufzeichnung des Aufrufstacks kann global deaktiviert und für bestimmte Ereignistypen selektiv aktiviert werden. Ebenso kann sie global aktiviert und für bestimmte Ereignistypen selektiv deaktiviert werden. Beide Anwendungsfälle werden unterstützt, sodass die Einstellung sowohl auf der obersten Ebene als auch auf der Ereignisebene möglich ist.
-
Einige Spans wurden nicht konfiguriert und werden ignoriert. Können diese Ereignisse auch ohne Konfiguration erfasst werden?
Ja. Wenn Sie in der Hauptkonfiguration auf der obersten Ebene
allowUnconfiguredEvents: true
festlegen, werden diese Ereignisse erfasst. In diesem Fall kann nicht ermittelt werden, welche Felder erfasst werden sollen. Nur die folgenden Standardfelder werden erfasst:traceID
,spanID
,parentSpanID
,startThread
undoperationName
. -
Wenn ich
com.oracle.apm.agent.jfr.category.default=ORACLE_APM_USE_SPAN_OPERATION_NAMES
für durch den Vorgangsnamen definierte Kategorien verwende, muss der Vorgangsname genau mit dem Ereignistypnamen in der Konfigurationsdatei übereinstimmen? Falls ja, muss ich für jeden Vorgang einen Ereignistyp angeben, wenn die Vorgangsnamen eindeutig sind?Ja, der Name muss mit dem Ereignistypnamen in der Konfigurationsdatei übereinstimmen. Auch wenn viele eindeutige Vorgangsnamen vorhanden sind, müssen Sie für jeden Vorgang einen Ereignistyp angeben, da für jeden dieser Ereignistypen wahrscheinlich unterschiedliche Felder konfiguriert werden müssen.
-
Ich kann den Ereignistyp nicht konfigurieren, weil der Vorgangsname in eine Java-ID konvertiert wird. Wie kann ich bestimmen, in welche ID der Vorgangsname konvertiert wird?
Alle unzulässigen Zeichen werden durch Unterstriche ersetzt. Wenn Sie einen Java-Beispielcode benötigen, um Ihre Zeichenfolgen in IDs zu konvertieren, können Sie den folgenden Code verwenden. Dieser nutzt dieselbe Routine, mit der APM die Zeichenfolgen konvertiert.// Convert an arbitrary string into a valid java identifier by replacing non-identifier chars with an underscore public static String getJavaIdentifier(String inString) { if (inString == null || inString.length() == 0) return inString; StringBuilder stringBuilder = new StringBuilder(); char[] allChars = inString.toCharArray(); if(Character.isJavaIdentifierStart(allChars[0])) stringBuilder.append(allChars[0]); else stringBuilder.append("_"); for (int i = 1; i < allChars.length; i++) { if (Character.isJavaIdentifierPart(allChars[i])) stringBuilder.append(allChars[i]); else stringBuilder.append("_"); } return stringBuilder.toString(); }
-
Ist der Namensabgleich mit einem regulären Ausdruck möglich?
Nein, reguläre Ausdrücke werden nicht unterstützt.