Enregistrement des étendues APM en tant qu'événements JFR
Le traceur APM et l'agent APM prennent en charge l'enregistrement des étendues APM en tant qu'événements JFR.
Actuellement, les versions 11 et ultérieures de JDK sont prises en charge.
Pour plus d'informations sur l'enregistrement des étendues APM en tant qu'événements JFR à l'aide de l'agent APM, reportez-vous à Enregistrement des étendues APM en tant qu'événements JFR sous Provisionnement et déploiement d'agents Java APM sur des serveurs d'applications.
JFR (Java Flight Recorder) est un outil de collecte de données de diagnostic et de profilage sur une application Java en cours d'exécution. Pour plus d'informations sur JFR et JMC (Java Mission Control), reportez-vous à JDK Mission Control.
Capture d'événements APM dans des enregistrements JFR
Pour capturer les événements APM dans des enregistrements JFR à l'aide du traceur APM, procédez comme suit :
-
Assurez-vous que le traceur APM fonctionne correctement.
Ouvrez l'explorateur de traces et vérifiez que vous pouvez visualiser toutes les traces. Pour plus d'informations sur l'ouverture et l'utilisation de l'explorateur de traces, reportez-vous à Surveillance des traces dans l'explorateur de traces.
-
Ajoutez au projet Maven une dépendance qui permettra au traceur APM d'ajouter des événements dans les enregistrements JFR réalisés par la JVM Helidon.
<dependency> <groupId>com.oracle.apm.agent.java</groupId> <artifactId>apm-java-agent-jfr11</artifactId> <version>[1.0.1389,)</version> </dependency>
-
Lancez un enregistrement.
Pour vérifier que tout fonctionne correctement, vous devez lancer un enregistrement à l'aide de la méthode de votre choix (vous pouvez utiliser l'interface utilisateur de JDK Mission Control ou l'utilitaire de ligne de commande JCMD). Une fois l'enregistrement lancé, les événements de trace apparaissent dans l'interface utilisateur de JDK Mission Control lorsque vous consultez l'enregistrement.
Pour vérifier que les événements de trace APM sont correctement ajoutés aux enregistrements JFR, connectez-vous à JDK Mission Control et vérifiez que les traces APM apparaissent sous Navigateur d'événements : cliquez sur APM OpenTracing et vérifiez que les événements de trace APM sont visibles.
Configuration d'événements JFR dans le traceur APM
(Facultatif) Il s'agit d'une étape facultative permettant de personnaliser la génération des rapports relatifs aux événements.
Pour simplifier l'analyse des événements d'enregistrement JFR, chaque événement est classé dans une catégorie ou un type d'événement.
Catégorie par défaut
Dans le traceur APM, la catégorie par défaut des événements JFR APM est obtenue à l'aide du contenu deSpan Operation Name
(dans un champ nommé name
au sein de l'étendue). La balise component
peut ne pas être renseignée. Elle ne peut donc pas être utilisée comme catégorie par défaut.
Evénements
Les types d'événement permettent d'organiser et de classer les événements dans l'interface utilisateur de JMC. Lorsque le traceur APM obtient une étendue, il peut générer un événement correspondant, mais il doit déterminer le type de l'événement en question.
Exemples de type d'événement : servlet, jdbc et jax-rs.
Configuration du type d'événement
Il existe plusieurs façons de configurer le type ou la catégorie d'un événement. Voici les différents cas d'emploi :
-
Cas 1 : balise
component
Il s'agit de la méthode la plus simple pour classer un événement. Cette méthode est recommandée.
Dans la plupart des scénarios, l'étendue OpenTracing contient une balise nommée
component
. La valeur de cette balisecomponent
est utilisée pour déterminer le type d'événement.Par exemple, reportez-vous à l'étendue suivante :
{ "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":[ ] },
Dans ce cas, le type d'événement
helidon-webserver
est affecté à l'événement généré car il s'agit de la valeur de la balisecomponent
. -
Cas 2 : autre balise
Si votre application n'utilise pas la balise
component
, mais qu'elle utilise une autre balise ou qu'il existe une bibliothèque dans laquelle elle génère des balises, vous pouvez configurer le traceur APM de façon à lire le type d'événement à partir d'une autre balise.Par exemple, dans l'étendue suivante, vous pouvez lire le type d'événement à partir de la balise nommée
span.type
:{ "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":[ ] },
Dans ce cas, vous pouvez demander au traceur APM de lire le type d'événement à partir de la balise
span.type
en utilisant la propriété système suivante lors du démarrage de l'application Java :java -Dcom.oracle.apm.agent.jfr.category.tag=span.type ...
-
Cas 3 : utilisation du nom d'opération lorsqu'aucune balise n'est disponible
Si votre application n'utilise aucune balise possédant des catégories utiles, vous pouvez utiliser la valeur
Operation Name
pour déterminer le type d'événement. Cette méthode n'est toutefois pas recommandée.Le système JFR a besoin que le nom du type d'événement soit un identificateur Java valide, mais la valeur
Operation Name
comporte souvent des espaces et d'autres caractères non autorisés. Le traceur APM convertit la valeurOperation Name
en identificateur valide en remplaçant tous les caractères non autorisés par un trait de soulignement.java -Dcom.oracle.apm.agent.jfr.category.default=ORACLE_APM_USE_SPAN_OPERATION_NAMES
Remarque
La valeurOperation Name
n'est utilisée que si la balise de catégorie est manquante ou vide.Cette solution n'est pas simple car la valeur
Operation Name
peut contenir des jetons uniques tels que des ID. Dans ce cas, chaque événement devient son propre type d'événement. En outre, la conversion de la valeurOperation Name
en un identificateur valide entraîne d'autres problèmes lors de la configuration du type d'événement pour configurer les champs nécessaires à l'événement. De plus, vous devrez effectuer la configuration en fonction de la valeurOperation Name
convertie, sous peine de devoir configurer plusieurs variantes de la valeurOperation Name
en suivant la même procédure. -
Cas 4 : aucune balise n'est disponible et tous les noms d'opération sont uniques
Dans ce cas, aucune information n'est disponible pour classer les types d'événement. Il s'agit du scénario le plus défavorable dans lequel tous les événements sont classés dans le même type d'événement, ou dans lequel ils sont chacun classés dans un type unique en cas de configuration à l'aide du scénario du cas d'emploi 3 ci-dessus. Tout ce que vous pouvez faire, c'est choisir le nom du type d'événement par défaut, qui peut être configuré comme indiqué ci-dessous.
java -Dcom.oracle.apm.agent.jfr.category.default=Unknown
Remarque
La valeur par défaut ne sera utilisée que si la balise de catégorie est manquante ou vide.Dans ce cas, tous les événements sont classés dans le type d'événement nommé
Unknown
ou toute valeur personnalisée sélectionnée.
Pour chaque type d'événement, vous pouvez ajouter des champs contenant des données propres à cet événement.
- Nom.
- Type (nombre entier, nombre à virgule flottante, chaîne, thread).
- Libellé.
- Description.
- name: traceID
type: String
label: New Trace ID
description: New Opentracing Trace ID
Création d'un fichier ACML
Cette étape est facultative. Si les paramètres par défaut fonctionnent comme prévu, vous pouvez ignorer cette étape.
Vous pouvez créer un fichier ACML si vous souhaitez modifier les paramètres par défaut et personnaliser les enregistrements.
L'exemple suivant présente le format d'un fichier ACML qui configure la journalisation des événements dans JFR en écrasant les paramètres par défaut intégrés du conteneur de microservices Helidon :
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
Vous pouvez utiliser le format de fichier ACML ci-dessus lorsque vous utilisez l'agent APM et le traceur APM. Dans le cas du traceur APM, ce format fonctionne pour n'importe quel conteneur, par exemple Helidon, Spring Boot ou Micronaut.
Foire aux questions
-
Lorsque les deux paramètres
com.oracle.apm.agent.jfr.category.tag
etcom.oracle.apm.agent.jfr.category.default
sont fournis, lequel est prioritaire ?Si une valeur leur est affectée à tous les deux, nous recherchons d'abord la balise de catégorie dans l'étendue. Si elle est trouvée, elle est utilisée. Si elle est manquante, la valeur par défaut est utilisée.
-
Pour le traceur APM, un fichier de configuration est-il obligatoire ? Puis-je simplement spécifier les propriétés sans fichier ?
Le fichier de configuration n'est pas obligatoire. Si la valeur par défaut vous convient, vous n'avez pas besoin d'un fichier de configuration et vous pouvez toujours spécifier les propriétés.
-
Pourquoi les entrées semblent-elles être dupliquées dans certains cas ? Par exemple, le fragment de code suivant du fichier de configuration ACML comporte deux fois l'entrée
helidon-webserver
:eventTypes: helidon-webserver: name: helidon-webserver
La première entrée
helidon-webserver
correspond à la valeur lue ou déduite à partir des balises ou du nom de l'opération. Si le type d'événement est clair, facile à lire et intuitif, comme dans l'exemple ci-dessus, vous pouvez l'utiliser pour l'envoi à l'enregistrement JFR. Le résultat est alors affiché de cette façon dans JMC.Toutefois, lorsque vous utilisez la valeuroperation name
, vous pouvez obtenir un type d'événement commeq_AxPsCbac9Ykp0HjpU+ENCiYHKl5HzMCmR02AfGzow3A=
qui représente une requête JDBC d'un client de base de données. Dans ce cas, vous avez tout intérêt à remplacer le nom envoyé à l'enregistrement JFR par un nom intuitif. L'exemple ci-dessous peut alors être utilisé :eventTypes: q_AxPsCbac9Ykp0HjpU+ENCiYHKl5HzMCmR02AfGzow3A=: name: jdbc-select-query
-
Si
recordCallStack
peut être spécifié pour chaque type d'événement, pourquoi un paramètrerecordCallStack
de niveau supérieur doit-il également être utilisé ?Nous prenons en charge deux cas d'utilisation pour assurer une flexibilité maximale dans l'enregistrement de la pile d'appels. L'enregistrement de la pile d'appels peut être désactivé globalement, puis activé de manière sélective pour certains types d'événement. Vous pouvez également l'activer globalement, puis le désactiver de manière sélective pour certains types d'événement. Etant donné que ces deux cas d'utilisation sont pris en charge, le paramètre est défini à la fois au niveau de l'événement et au niveau supérieur.
-
J'ai quelques étendues qui n'ont pas été configurées et qui sont ignorées. Est-il possible de capturer ces événements sans les configurer ?
Oui. Si vous définissez
allowUnconfiguredEvents: true
dans la configuration principale de niveau supérieur, ces événements sont capturés. Lorsque cela se produit, nous ne savons pas quels champs collecter. Seuls les champs par défaut suivants sont collectés :traceID
,spanID
,parentSpanID
,startThread
etoperationName
. -
Si je me suis servi de
com.oracle.apm.agent.jfr.category.default=ORACLE_APM_USE_SPAN_OPERATION_NAMES
pour utiliser des catégories définies en fonction du nom de l'opération, le nom de l'opération doit-il correspondre exactement au nom du type d'événement dans le fichier de configuration ? Si tel est le cas, et si j'ai des noms d'opération uniques, dois-je spécifier un type d'événement pour chaque opération ?Oui, le nom de l'opération doit correspondre au nom du type d'événement dans le fichier de configuration. Même si vous disposez de nombreux noms d'opération uniques, vous devez indiquer un type d'événement pour chaque opération, car chacun de ces types d'événement est susceptible d'avoir un ensemble de champs différents à configurer.
-
Le nom de mon opération est converti en identificateur Java. Par conséquent, je ne peux pas configurer son type d'événement. Comment puis-je déterminer la valeur convertie du nom de mon opération ?
Tous les caractères non autorisés ont été remplacés par un trait de soulignement. Si vous avez besoin d'un échantillon de code Java pour convertir vos chaînes en identificateurs, vous pouvez utiliser le code ci-dessous. Il s'agit de la même routine qu'APM utilise pour convertir les chaînes.// 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(); }
-
Le nom correspondant peut-il être une expression régulière ?
Non. Les expressions régulières ne sont pas prises en charge.