Tutoriel : Instrumentation d'un framework personnalisé Java HTTP à l'aide du SDK de traçage Instana

L'agent Instana prend en charge de nombreux frameworks Java HTTP et, dans la plupart des cas, le traçage est pris en charge dès que vous exécutez l'agent Java.

Toutefois, si vous disposez d'un serveur HTTP interne personnalisé qui n'est pas pris en charge, vous pouvez utiliser le SDK de traçage Java pour ajouter la fonctionnalité de traçage à votre framework.

Ce tutoriel explique comment procéder.

Exemple de code

Le code d'exemple du custom-http-sample tutoriel est disponible sur github.com. Il implémente le scénario suivant :

tutoriel sur le serveur HTTP personnalisé

Si vous exécutez l'exemple et ouvrez http://localhost:8080, vous obtiendrez la réponse Hello, Stan!. Cependant, si vous analysez les appels dans Instana, vous voyez que la trace est rompue.

Piste 1 : traçage de la capture d'écran 01

Piste 2 : traçage de la capture d'écran 02

Les demandes sortantes sont implémentées à l'aide du client HTTP Apache qui est pris en charge par le traçage automatique d'Instana. Le maillon manquant est la fenêtre d'entrée (appel entrant) GET /greeting au niveau du serveur d' HTTP s personnalisé.

Activation du traçage pour le serveur HTTP personnalisé

Pour les frameworks pris en charge, l'agent Instana instrumente automatiquement les applications Java. Pour le serveur HTTP personnalisé, il est nécessaire d'ajouter des annotations pour indiquer à l'agent Instana les appels de méthode qui doivent démarrer un nouveau span.

Tout d'abord, ajoutez la dépendance mvn

<dependency>
  <groupId>com.instana</groupId>
  <artifactId>instana-java-sdk</artifactId>
  <version>1.2.0</version>
</dependency>

Ensuite, ajoutez une annotation @Span à la méthode de traitement de la demande HTTP dans le serveur HTTP personnalisé.

@Span(type = Span.Type.ENTRY, value = "my-custom-http-server")
public String apply(Map<String, String> headers) {
  // ...
}

Cette annotation indique à l'agent Java de générer un span ENTRY (c'est à dire, un span serveur) chaque fois que cette méthode est appelée.

Troisièmement, ajoutez ce qui suit au fichier configuration.yaml de l'agent Instana pour lui indiquer que les classes Java dans le package com.instana.sample.* doivent être analysées pour l'annotation @Span :

com.instana.plugin.javatrace:
  instrumentation:
    sdk:
      packages:
        - 'com.instana.sample'

Maintenant, le serveur personnalisé est instrumenté, et vous voyez que l'appel sortant vers /name est déclenché depuis l'appel entrant /greeting.

traçage de la capture d'écran 03

Cependant, la trace est toujours rompue, car l'ID de trace n'est pas transmis entre l'appel entrant et l'appel sortant.

Traitement des en-être de traçage entrants

Instana utilise les en-têtes HTTP suivants pour transmettre les informations de trace d'un service à l'autre :

  • X-INSTANA-T: ID de trace
  • X-INSTANA-S : ID du span parent
  • X-INSTANA-L : le niveau 0 signifie que la trace doit être supprimée, ce qui peut être utile pour les contrôles d'intégrité

Pour corréler le contexte de trace dans le serveur HTTP client, vous devez ajouter la méthode suivante à GreetingHandler :

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);
  }
}

Notez que nous supprimons les en-têtes après les avoir évalués, en ne laissant que les en-têtes d'origine tels qu'ils seraient envoyés sans le traçage Instana.

Toutefois, vous ne pouvez simplement pas appeler correlateTracing() dans apply(), car les en-têtes doivent être évalués avant que la méthode avec l'annotation @Span soit appelée. Comme solution palliative, vous pouvez renommer la méthode apply() en doApply() et ajouter une étape comme suit:

@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) {
  // ...
}

Lorsque vous exécutez curl http://localhost:8080, vous voyez la trace complète dans Instana.

traçage de la capture d'écran 04

Ajout de balises

Jusqu'à présent, le span my-custom-http-server n'est qu'un span ENTRY générique sans annotations supplémentaires. Si vous regardez les détails, ils ont l'air plutôt vides.

étendue sans annotations

Vous pouvez appeler la méthode SpanSupport.annotate() du kit SDK dans un contexte @Span actif pour ajouter des annotations au span actuel. Instana prend en charge une partie des conventions sémantiques d' OpenTracing's, telles que décrites dans la documentation du Trace SDK d' Java. Pour ajouter des annotations d' HTTP, ajoutez les lignes suivantes au début de la doApply() méthode :

@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");
  // ...
}

Maintenant, les détails du span ENTRY du serveur HTTP personnalisé affichent les métadonnées HTTP spécifiées.

étendue avec annotations

Notez que le span iEXIT correspondant de Jetty au serveur HTTP personnalisé avait déjà des métadonnées HTTP, car le client utilise le client Apache HTTP qui est pris en charge par le traçage automatique d'Instana.

Marquage d'un span comme étant erroné

À un moment ou à un autre, vous serez amené à marquer un appel comme étant erroné. Cela peut facilement être réalisé en ajoutant la error balise, comme indiqué dans les conventions sémantiques de OpenTracing's.

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

Cet ajout fait apparaître l'appel comme erroné dans Instana.

étendue erronée

Récapitulatif et perspective

Ce tutoriel a montré l'API la plus importante API nécessaire pour instrumenter un framework HTTP personnalisé avec le traçage distribué d'Instana.

Pour une référence complète sur notre SDK, consultez le JavaDocdu SDK. Par exemple, les annotations @SpanParam et @SpanReturn facilitent grandement la capture des paramètres ou des valeurs de retour sous forme d'informations supplémentaires des spans, ce qui peut être plus pratique que d'appeler explicitement SpanSupport.annotate() dans certains scénarios.