L'agent Application Real-Time Monitoring Service (ARMS) instrumente automatiquement les frameworks Java courants afin de collecter des données de trace sans modification du code. Pour capturer des données de trace reflétant votre logique métier spécifique, ajoutez une instrumentation personnalisée à l'aide du SDK OpenTelemetry pour Java. Cette rubrique explique comment utiliser le SDK OpenTelemetry pour Java afin d'ajouter une instrumentation personnalisée, d'accéder au contexte de trace, de définir un Baggage personnalisé et de configurer des attributs personnalisés.
Pour obtenir la liste des composants et frameworks pris en charge par l'agent ARMS, consultez la rubrique Composants et frameworks Java pris en charge par ARMS.
Prérequis
Connectez votre application à Application Real-Time Monitoring Service (ARMS). Pour plus d'informations, consultez la rubrique Présentation de l'intégration de la surveillance des applications.
Votre agent ARMS doit être en version 2.9.1.2 ou ultérieure. Pour mettre à niveau l'agent, consultez la rubrique Mettre à niveau l'agent ARMS.
Ajouter des dépendances
Ajoutez les dépendances Maven suivantes à votre projet. Pour plus d'informations, consultez la documentation officielle d'OpenTelemetry.
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.23.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Compatibilité de l'agent ARMS avec l'instrumentation OpenTelemetry
Concepts clés
Cette section décrit uniquement les termes courants. Pour plus d'informations sur les autres termes, consultez les spécifications OpenTelemetry.
span : opération spécifique dans une requête, telle qu'un point d'entrée d'appel distant ou un appel de méthode interne.
SpanContext : contexte d'une trace, incluant des informations telles que l'ID de trace et l'ID de span.
attribute : champ supplémentaire sur un span qui enregistre des informations clés.
Baggage : paires clé-valeur propagées tout au long de la trace.
Utiliser le SDK OpenTelemetry pour Java
Le SDK OpenTelemetry vous permet d'effectuer les opérations suivantes :
Ajouter une instrumentation pour générer des spans.
Ajouter des attributs aux spans.
Propager le Baggage dans le contexte de trace.
Obtenir le contexte de trace actuel et afficher des informations telles que l'ID de trace et l'ID de span.
L'exemple de code suivant montre comment utiliser le SDK OpenTelemetry pour réaliser ces opérations.
Important : Vous devez obtenir l'instance OpenTelemetry en appelant GlobalOpenTelemetry.get(). N'utilisez pas une instance construite manuellement avec le SDK OpenTelemetry. Dans le cas contraire, les spans générés par l'instrumentation du SDK ne seront pas visibles dans l'agent ARMS v4.x.
@RestController
@RequestMapping("/ot")
public class OpenTelemetryController {
private Tracer tracer;
private ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
@PostConstruct
public void init() {
OpenTelemetrySdk.builder()
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
tracer = GlobalOpenTelemetry.get().getTracer("manual-sdk", "1.0.0");
ses.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
Span span = tracer.spanBuilder("schedule")
.setAttribute("schedule.time", System.currentTimeMillis())
.startSpan();
try (Scope scope = span.makeCurrent()) {
System.out.println("scheduled!");
Thread.sleep(500L);
span.setAttribute("schedule.success", true);
System.out.println(Span.current().getSpanContext().getTraceId()); // Get the trace ID
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, t.getMessage());
} finally {
span.end();
}
}
}, 10, 30, TimeUnit.SECONDS);
}
@ResponseBody
@RequestMapping("/parent")
public String parent() {
Span span = tracer.spanBuilder("parent").setSpanKind(SpanKind.SERVER).startSpan();
try (Scope scope = span.makeCurrent()) {
// Use Baggage to propagate custom business tags.
Baggage baggage = Baggage.current().toBuilder()
.put("user.id", "1")
.put("user.name", "name")
.build();
try (Scope baggageScope = baggage.storeInContext(Context.current()).makeCurrent()) {
child();
}
span.setAttribute("http.method", "GET");
span.setAttribute("http.uri", "/parent");
} finally {
span.end();
}
return "parent";
}
private void child() {
Span span = tracer.spanBuilder("child").startSpan();
try (Scope scope = span.makeCurrent()) {
System.out.println("current traceId = " + Span.current().getSpanContext().getTraceId());
System.out.println("userId in baggage = " + Baggage.current().getEntryValue("user.id"));
Thread.sleep(1000);
} catch (Throwable e) {
span.setStatus(StatusCode.ERROR, e.getMessage());
} finally {
span.end();
}
}
}
Parcours de l'exemple :
Dans la méthode
initdeOpenTelemetryController, une tâche planifiée démarre. Un span est créé au début de chaque exécution et se termine à la fin de celle-ci.-
Dans la méthode
parentdeOpenTelemetryController, plusieurs méthodes du SDK OpenTelemetry sont appelées.À chaque appel de la méthode, un span nommé
parentest créé et se termine à la fin de la méthode.Le SDK Baggage est utilisé pour ajouter deux éléments Baggage :
user.idetuser.name. Ces éléments sont propagés vers les applications en aval.Deux attributs sont ajoutés au span créé à l'étape 2.a.
-
La méthode
childdeOpenTelemetryControllereffectue les opérations suivantes :
Différences entre les versions de l'agent ARMS
La prise en charge des opérations du code précédent varie selon les versions de l'agent ARMS.
|
Étape |
Agent ARMS v4.x et versions ultérieures |
Agent ARMS v3.x et versions antérieures |
|
1 |
Prise en charge. Un nouveau span est généré. |
Prise en charge. Un nouveau span est généré. |
|
2.a |
Prise en charge |
Prise en charge |
|
2.b |
Prise en charge |
Non pris en charge |
|
2.c |
Prise en charge |
Prise en charge |
|
3.a |
Prise en charge |
Prise en charge. Ce span apparaît comme une pile de méthodes au sein du span créé à l'étape 2.a. |
|
3.b |
Prise en charge. L'ID de trace affiché est identique à l'ID de trace dans ARMS. |
Non pris en charge. L'ID de trace affiché diffère de l'ID de trace dans l'agent ARMS. |
|
3.c |
Prise en charge |
Prise en charge |
Résultats de l'instrumentation
v4.x et versions ultérieures
-
Résultat de l'instrumentation de l'étape 1 :
Vous pouvez voir le span généré par le SDK OpenTelemetry.
Dans les détails du span d'une trace dans la console ARMS, vous pouvez afficher les informations de base, telles que le nom de l'application (par exemple,
elastic-search-8), le nom de l'opération (par exemple,schedule), le type de span (INTERNAL) et la durée. Dans l'onglet Attributes, vous pouvez consulter les attributs OpenTelemetry, tels queotel.scope.name=manual-sdketotel.scope.version=1.0.0, ainsi que les attributs métier personnalisés, tels queschedule.success=true, ce qui confirme que l'instrumentation fonctionne correctement. -
Résultats de l'instrumentation des étapes 2.x et 3.x :
Les spans générés par le SDK OpenTelemetry apparaissent dans la même trace que les spans Tomcat générés par l'agent. De plus, les attributs associés aux spans générés par le SDK sont définis comme prévu.
Dans les détails de la trace, le nom de l'opération du span généré par l'instrumentation de l'agent Tomcat est
/opentelemetry/parent. Les spans générés par le SDK OpenTelemetry sont nommésparentet son span enfantchild. Dans les attributs du span,http.methodvautGET,http.urivaut/parentet l'attribut personnaliséotel.scope.namevautmanual-sdk.
v3.x et versions antérieures
-
Résultat de l'instrumentation de l'étape 1 :
Sur la page des détails de la trace dans la console ARMS, vous pouvez afficher les données de trace collectées par l'instrumentation. Le diagramme en cascade à gauche montre les relations d'appel entre les spans. Par exemple, la méthode
schedulede l'applicationelastic-search-9est capturée sous forme de span avec un type de composantuser_methodet un temps de réponse total de 567 ms. Le panneau Span Details à droite affiche les informations de base telles que le nom de l'application, le nom du span, l'adresse IP, l'ID de span et le code d'état. La section Attributes ci-dessous affiche des attributs supplémentaires regroupés, notamment les informations HTTP (http.path,http.status_code), les informations RPC (rpc.type) et les informations intégrées (component.name=user_method,slow=1). -
Résultats de l'instrumentation des étapes 2.x et 3.x :
Le span
childs'affiche dans la pile de méthodes du spanparent. De plus, les attributs des spans générés par le SDK sont définis comme prévu.Dans la vue method stack, la hiérarchie des traces montre l'OpenTelemetry Entry Span appelant le span parent, qui appelle à son tour le span child. Chacun de ces trois appels imbriqués prend environ 1,01 seconde. Les attributs de la méthode child incluent
line=-1etrpc.type=98.
Documents connexes
La corrélation des informations d'ID de trace avec les journaux métier de votre application vous permet de trouver rapidement les journaux associés pour le dépannage en cas de problème. Pour plus d'informations, consultez la rubrique Associer les ID de trace aux journaux métier pour les applications Java.