Qu’est-ce que le suivi distribué et la corrélation de télémétrie ?

Remarque

La documentation suivante s’appuie sur l’API classique d’Application Insights. Le plan à long terme pour Application Insights est de collecter des données en utilisant OpenTelemetry. Pour plus d’informations, consultez la section Activer Azure Monitor OpenTelemetry pour les applications .NET, Node.js, Python et Java.

Le cloud moderne et les architectures de microservices ont donné naissance à des services simples qui peuvent être déployés de façon indépendante et qui réduisent les coûts, tout en améliorant la disponibilité et le débit. Toutefois, ils ont également rendu les systèmes globaux plus difficiles à analyser et à déboguer. Le suivi distribué résout ce problème en fournissant un profileur de performances qui fonctionne comme des piles d’appels pour les architectures cloud et microservices.

Azure Monitor fournit deux expériences pour la consommation de données de trace distribuées : la vue Diagnostics de transaction pour une seule transaction/demande et la vue Mise en correspondance d’applications pour montrer comment les systèmes interagissent.

Application Insights peut superviser chaque composant séparément et détecter quel composant est responsable des défaillances ou de la dégradation des performances à l’aide de la corrélation de télémétrie distribuée. Cet article explique le modèle de données, les techniques de propagation du contexte, les protocoles et l’implémentation des tactiques de corrélation dans différents langages et sur les différentes plateformes utilisés par Application Insights.

Activer le suivi distribué

Pour activer le suivi distribué pour une application, ajoutez l’agent, le kit de développement logiciel (SDK) ou la bibliothèque appropriés à chaque service en fonction de son langage de programmation.

Activer au moyen d’Application Insights par le biais de l’instrumentation automatique ou de kit de développement logiciel (SDK)

Les agents et kits SDK Application Insights pour .NET, .NET Core, Java, Node.js et JavaScript prennent tous en charge le suivi distribué en mode natif. Les instructions permettant d’installer et de configurer chaque kit SDK Application Insights sont disponibles pour :

Lorsque le SDK Application Insights adéquat est installé et configuré, les collecteurs automatiques des dépendances des SDK recueillent les informations de traçage automatiquement pour les infrastructures, les bibliothèques et les technologies populaires. La liste complète des technologies prises en charge est disponible dans la documentation sur la collecte automatique des dépendances.

Toute technologie peut également être suivie manuellement par un appel à TrackDependency sur TelemetryClient.

Activer via OpenTelemetry

Application Insights prend désormais en charge le traçage distribué via OpenTelemetry. OpenTelemetry fournit une instrumentation indépendante du fournisseur pour envoyer des traces, des métriques et des journaux à Application Insights. Initialement, la communauté OpenTelemetry s’est occupée du suivi distribué. Des métriques et journaux sont toujours en cours.

Une histoire complète d’observabilité comprend les trois piliers. Vérifiez l’état de nos offres Azure Monitor basées sur OpenTelemetry pour connaître l’état le plus récent de ce qui est inclus, les offres qui sont en disponibilité générale et les options de support.

Les pages suivantes contiennent une aide, langage par langage, pour activer et configurer les offres de Microsoft basées sur OpenTelemetry. Il est important de noter que nous partageons les fonctionnalités disponibles et les limites de chaque offre afin que vous puissiez déterminer si OpenTelemetry convient à votre projet.

Activation via OpenCensus

Outre les SDK, Application Insights prend également en charge le traçage distribué via OpenCensus. OpenCensus est une distribution unique de bibliothèques (Open Source et indépendante des fournisseurs) offrant la collecte de métriques et le suivi distribué pour les services. Cet outil permet également à la communauté Open Source d’activer le suivi distribué avec des technologies populaires comme Redis, Memcached ou MongoDB. Microsoft collabore sur OpenCensus avec plusieurs partenaires de surveillance et de cloud.

Pour plus d’informations sur OpenCensus pour Python, consultez Configurer Azure Monitor pour votre application Python.

Le site web OpenCensus fournit de la documentation de référence sur l’API pour Python, Go et divers guides sur l’utilisation d’OpenCensus.

Modèle de données pour la corrélation de télémétrie

Application Insights définit le modèle de données pour la corrélation de télémétrie distribuée. Pour associer la télémétrie à une opération logique, chaque élément de télémétrie comporte un champ de contexte appelé operation_Id. Cet élément de télémétrie dans la trace distribuée partage cet identifiant. Ainsi, même si vous perdez la télémétrie d’une seule couche, vous pouvez toujours associer la télémétrie communiquée par d’autres composants.

Une opération logique distribuée se compose généralement d’un ensemble d’opérations plus petites qui sont des requêtes traitées par un des composants. Les données de télémétrie de requête définissent ces opérations. Chaque élément de télémétrie d’une requête a son propre id, qui l’identifie de façon univoque et globale. Par ailleurs, tous les éléments de télémétrie (comme les traces et les exceptions) associés à la requête doivent définir le operation_parentId sur la valeur de l’id de la requête.

La télémétrie des dépendances représente chaque opération sortante, telle qu’un appel HTTP vers un autre composant. Elle définit également son propre id qui est globalement unique. La télémétrie des requêtes, lancée par cet appel de dépendances, utilise cet id comme operation_parentId.

Vous pouvez générer une vue de l’opération logique distribuée en utilisant operation_Id, operation_parentId et request.id avec dependency.id. Ces champs définissent également l’ordre de causalité des appels de télémétrie.

Dans un environnement de microservices, les traces des composants peuvent se diriger vers différents éléments de stockage. Chaque composant peut avoir sa propre chaîne de connexion dans Application Insights. Pour obtenir la télémétrie pour l’opération logique, Application Insights interroge les données de chaque élément de stockage.

Quand le nombre d’éléments de stockage est important, vous avez besoin d’une indication quant à l’endroit à regarder ensuite. Le modèle de données Application Insights définit deux champs pour résoudre ce problème : request.source et dependency.target. Le premier champ identifie le composant qui a lancé la demande de dépendance. Le deuxième champ identifie le composant qui a retourné la réponse de l’appel de dépendance.

Pour plus d’informations sur l’interrogation à partir de plusieurs instances disparates à l’aide de l’expression de requête app, consultez Expression app() dans une requête Azure Monitor.

Exemple

Intéressons-nous à un exemple. Une application appelée Stock Prices affiche le cours actuel sur le marché d’une action en utilisant une API externe nommée Stock. L’application Stock Prices a une page nommée Stock que le navigateur web client ouvre en utilisant GET /Home/Stock. L’application interroge l’API Stock en utilisant l’appel HTTP GET /api/stock/value.

Vous pouvez analyser la télémétrie obtenue en exécutant une requête :

(requests | union dependencies | union pageViews)
| where operation_Id == "STYz"
| project timestamp, itemType, name, id, operation_ParentId, operation_Id

Dans les résultats, tous les éléments de télémétrie partagent la racine operation_Id. Quand un appel Ajax est effectué à partir de la page, un nouvel ID unique (qJSXU) est affecté à la télémétrie des dépendances, et l’ID de la pageView est utilisé en tant que operation_ParentId. La requête de serveur utilise ensuite l’ID Ajax en tant que operation_ParentId.

itemType name id operation_ParentId operation_Id
pageView Stock page STYz STYz
dependency GET /Home/Stock qJSXU STYz STYz
requête GET Home/Stock KqKwlrSt9PA= qJSXU STYz
dependency GET /api/stock/value bBrf2L7mm2g= KqKwlrSt9PA= STYz

Quand l’appel GET /api/stock/value est effectué vers un service externe, vous devez connaître l’identité de ce serveur afin de pouvoir définir le champ dependency.target de façon appropriée. Quand le service externe ne prend pas en charge la supervision, target est défini sur le nom d’hôte du service. par exemple stock-prices-api.com. Cependant, si le service s’identifie lui-même en retournant un en-tête HTTP prédéfini, target contient l’identité du service qui permet à Application Insights de générer une trace distribuée en interrogeant la télémétrie provenant de ce service.

En-têtes de corrélation à l’aide de W3C TraceContext

Application Insights effectue la transition vers W3C Trace-Context, qui définit :

  • traceparent: représente l’ID d’opération globalement unique et l’identificateur unique de l’appel.
  • tracestate: Représente le contexte de traçage spécifique au système.

La dernière version du SDK Application Insights prend en charge le protocole Trace-Context, mais il peut être nécessaire d’y adhérer. (La compatibilité descendante avec le protocole de corrélation précédent pris en charge par le SDK Application Insights est conservée.)

Le protocole HTTP de corrélation, également appelé Request-Id est déprécié. Ce protocole définit deux en-têtes :

  • Request-Id: représente le GUID de l’appel.
  • Correlation-Context: représente la collection de paires nom-valeur des propriétés de trace distribuée.

Application Insights définit également l’extension pour le protocole HTTP de corrélation. Il utilise des paires nom-valeur Request-Context pour propager la collection de propriétés utilisée par l’appelant ou l’appelé. Le SDK Application Insights utilise cet en-tête pour définir les champs dependency.target et request.source.

Les modèles de données W3C Trace-Context et Application Insights correspondent de la façon suivante :

Application Insights W3C TraceContext
Id de Request et Dependency parent-id
Operation_Id trace-id
Operation_ParentId parent-id de l’étendue parente de cette étendue. Ce champ doit être vide s’il s’agit d’une étendue racine.

Pour plus d’informations, consultez le Modèle de données de télémétrie d’Application Insights.

Activer la prise en charge du suivi distribué W3C pour les applications .NET

Le suivi distribué basé sur W3C TraceContext est activé par défaut dans tous les kits de développement logiciel (SDK) .NET Framework/.NET Core récents, ainsi que la compatibilité descendante avec le protocole request-id hérité.

Activer la prise en charge du traçage distribué W3C pour les applications Java

Agent Java 3.0

L’agent Java 3.0 prend en charge W3C prêt à l’emploi et aucune configuration supplémentaire n’est requise.

Kit de développement logiciel (SDK) Java

  • Configuration d’entrée

    Pour les applications Java EE, ajoutez le code suivant à la balise <TelemetryModules> dans le fichier ApplicationInsights.xml :

    <Add type="com.microsoft.applicationinsights.web.extensibility.modules.WebRequestTrackingTelemetryModule>
       <Param name = "W3CEnabled" value ="true"/>
       <Param name ="enableW3CBackCompat" value = "true" />
    </Add>
    

    Pour les applications Spring Boot, ajoutez ces propriétés :

    • azure.application-insights.web.enable-W3C=true
    • azure.application-insights.web.enable-W3C-backcompat-mode=true
  • Configuration de sortie

    Ajoutez le code suivant au fichier AI-Agent.xml :

    <Instrumentation>
      <BuiltIn enabled="true">
        <HTTP enabled="true" W3C="true" enableW3CBackCompat="true"/>
      </BuiltIn>
    </Instrumentation>
    

    Notes

    Le mode de compatibilité descendante est activé par défaut et le paramètre enableW3CBackCompat est facultatif. Utilisez-le uniquement quand vous souhaitez désactiver la compatibilité descendante.

    Dans l’idéal, vous désactiverez ce mode quand tous vos services auront été mis à jour vers des versions plus récentes des SDK prenant en charge le protocole W3C. Nous vous recommandons vivement de déplacer ces SDK plus récents dès que possible.

Il est important de vérifier que les configurations entrante et sortante sont rigoureusement identiques.

Activer la prise en charge du suivi distribué W3C pour les applications web

Cette fonctionnalité est activée par défaut pour JavaScript et les en-têtes sont automatiquement inclus lorsque le domaine de la page d'hébergement est le même que le domaine auquel les requêtes sont envoyées (par exemple, la page d'hébergement est example.com et les requêtes Ajax sont envoyées example.com). Pour modifier le mode de suivi distribué, utilisez le distributedTracingModechamp de configuration. AI_AND_W3C est fourni par défaut à des fins de compatibilité descendante avec tous les services instrumentés hérités par Application Insights.

Si les requêtes XMLHttpRequest ou Fetch Ajax sont envoyées à un autre hôte de domaine, notamment des sous-domaines, les en-têtes de corrélation ne sont pas inclus par défaut. Si vous souhaitez activer cette fonctionnalité, définissez le enableCorsCorrelation champ de configuration sur true. Si vous définissez enableCorsCorrelation sur true, toutes les requêtes XMLHttpRequest et Fetch Ajax incluent les en-têtes de corrélation. Par conséquent, si l’application sur le serveur appelé ne prend pas en charge l’en-tête traceparent, il est possible que la requête échoue, selon que le navigateur/la version peut valider la requête en fonction des en-têtes acceptés par le serveur. Vous pouvez utiliser le champ de configuration correlationHeaderExcludedDomains pour exclure le domaine du serveur de l’injection d’en-tête de corrélation entre composants. Par exemple, vous pouvez utiliser correlationHeaderExcludedDomains: ['*.auth0.com'] pour exclure les en-têtes de corrélation des demandes envoyées au fournisseur d’identité Auth0.

Important

Pour afficher toutes les configurations requises pour activer la corrélation, consultez la documentation relative à la corrélation JavaScript.

Corrélation de télémétrie dans OpenCensus Python

OpenCensus Python prend en charge W3 Trace-Context sans nécessiter de configuration supplémentaire.

Pour obtenir une référence, vous trouverez le modèle de données OpenCensus sur cette page GitHub.

Corrélation de requêtes entrantes

OpenCensus Python met en corrélation les en-têtes Trace-Context W3C des requêtes entrantes avec les intervalles générés à partir des requêtes elles-mêmes. OpenCensus effectue une corrélation automatiquement en s’intégrant à ces infrastructures d’application web populaires : Flask, Django et Pyramid. Vous devez seulement renseigner les en-têtes Trace-Context de W3C avec le format correct, puis les envoyer avec la requête.

Explorez cet exemple d’application Flask. Installez Flask, OpenCensus et les extensions pour Flask et Azure.


pip install flask opencensus opencensus-ext-flask opencensus-ext-azure

Vous devez ajouter votre chaîne de connexion Application Insights à la variable d’environnement.

APPLICATIONINSIGHTS_CONNECTION_STRING=<appinsights-connection-string>

Exemple d’application Flask

from flask import Flask
from opencensus.ext.azure.trace_exporter import AzureExporter
from opencensus.ext.flask.flask_middleware import FlaskMiddleware
from opencensus.trace.samplers import ProbabilitySampler

app = Flask(__name__)
middleware = FlaskMiddleware(
    app,
    exporter=AzureExporter(
        connection_string='<appinsights-connection-string>', # or set environment variable APPLICATION_INSIGHTS_CONNECTION_STRING
    ), 
    sampler=ProbabilitySampler(rate=1.0),
)

@app.route('/')
def hello():
    return 'Hello World!'

if __name__ == '__main__':
    app.run(host='localhost', port=8080, threaded=True)

Ce code exécute un exemple d’application Flask sur votre machine locale, en écoutant le port 8080. Pour corréler le contexte de trace, vous envoyez une requête au point de terminaison. Dans cet exemple, vous pouvez utiliser une commande curl :

curl --header "traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01" localhost:8080

En examinant le format de l’en-tête Trace-Context, vous pouvez déduire les informations suivantes :

version: 00

trace-id: 4bf92f3577b34da6a3ce929d0e0e4736

parent-id/span-id: 00f067aa0ba902b7

trace-flags: 01

Si vous examinez l’entrée de la requête envoyée à Azure Monitor, vous pouvez voir des champs renseignés avec les informations d’en-tête de trace. Vous trouverez les données sous Journaux (Analytics) dans la ressource Azure Monitor Application Insights.

Screenshot that shows Request telemetry in Logs (Analytics).

Le champ id est au format <trace-id>.<span-id>, où trace-id provient de l’en-tête de trace passé dans la requête, et où span-id est un tableau de 8 octets généré pour cette étendue.

Le champ operation_ParentId est au format <trace-id>.<parent-id>, où trace-id et parent-id sont extraits de l’en-tête de trace passé dans la requête.

Corrélation des journaux

OpenCensus Python vous permet de mettre en corrélation des journaux en ajoutant un ID de trace, un ID d’étendue et un indicateur d’échantillonnage aux enregistrements de journal. Vous ajoutez ces attributs en installant l’intégration de la journalisation d’OpenCensus. Les attributs suivants seront ajoutés aux objets LogRecord Python : traceId, spanId et traceSampled (applicable uniquement aux enregistreurs d’événements créés après l’intégration).

Installez l’intégration de la journalisation OpenCensus :

python -m pip install opencensus-ext-logging

Exemple d’application

import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(['logging'])
logging.basicConfig(format='%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s')
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning('Before the span')
with tracer.span(name='hello'):
    logger.warning('In the span')
logger.warning('After the span')

Quand ce code s’exécute, voici ce qui s’affiche dans la console :

2019-10-17 11:25:59,382 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 Before the span
2019-10-17 11:25:59,384 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=70da28f5a4831014 In the span
2019-10-17 11:25:59,385 traceId=c54cb1d4bbbec5864bf0917c64aeacdc spanId=0000000000000000 After the span

Notez qu’un spanId est présent pour le message du journal qui se trouve dans l’étendue. Il s’agit du même spanId que celui qui appartient à l’étendue nommée hello.

Vous pouvez exporter les données du journal avec AzureLogHandler. Pour plus d’informations, consultez Configurer Azure Monitor pour votre application Python.

Nous pouvons également transmettre des informations de trace d’un composant à un autre pour une corrélation correcte. Par exemple, envisagez un scénario avec deux composants, module1 et module2. Le module 1 appelle des fonctions dans le module 2. Pour obtenir des journaux à partir de module1 et de module2 dans une trace unique, vous pouvez utiliser l’approche suivante :

# module1.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer
from module_2 import function_1

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
tracer = Tracer(sampler=AlwaysOnSampler())

logger = logging.getLogger(__name__)
logger.warning("Before the span")

with tracer.span(name="hello"):
    logger.warning("In the span")
    function_1(logger, tracer)
logger.warning("After the span")
# module_2.py
import logging

from opencensus.trace import config_integration
from opencensus.trace.samplers import AlwaysOnSampler
from opencensus.trace.tracer import Tracer

config_integration.trace_integrations(["logging"])
logging.basicConfig(
    format="%(asctime)s traceId=%(traceId)s spanId=%(spanId)s %(message)s"
)
logger = logging.getLogger(__name__)
tracer = Tracer(sampler=AlwaysOnSampler())


def function_1(logger=logger, parent_tracer=None):
    if parent_tracer is not None:
        tracer = Tracer(
            span_context=parent_tracer.span_context,
            sampler=AlwaysOnSampler(),
        )
    else:
        tracer = Tracer(sampler=AlwaysOnSampler())

    with tracer.span("function_1"):
        logger.info("In function_1")

Corrélation de télémétrie dans .NET

La corrélation est gérée par défaut lors de l’intégration d’une application. Aucune action spéciale n’est nécessaire.

Le runtime .NET prend en charge la distribution avec l’aide de Activity et de DiagnosticSource

Le kit de développement logiciel (SDK) .NET d’Application Insights utilise DiagnosticSource et Activity pour collecter et mettre en corrélation les données de télémétrie.

Corrélation de télémétrie dans Java

L’agent Java prend en charge la corrélation automatique des données de télémétrie. Il renseigne automatiquement operation_id pour toutes les données de télémétrie (comme les traces, les exceptions et les événements personnalisés) émises dans l’étendue d’une requête. Il propage aussi les en-têtes de corrélation qui ont été décrits plus haut pour les appels entre les services via le protocole HTTP si l’agent du SDK Java est configuré.

Notes

L’agent Java Application Insights collecte automatiquement les demandes et les dépendances pour JMS, Kafka, Netty/Webflux et bien plus. Pour le SDK Java, seuls les appels effectués via Apache HttpClient sont pris en charge pour la fonctionnalité de corrélation. La propagation automatique de contexte entre les technologies de messagerie comme Kafka, RabbitMQ et Azure Service Bus n’est pas prise en charge dans le SDK.

Pour collecter des données de télémétrie personnalisées, vous devez instrumenter l’application à l’aide du SDK Java 2.6.

Nom des rôles

Vous pouvez personnaliser la façon dont les noms des composants sont affichés dans Cartographie d’application. Pour cela, vous pouvez définir manuellement cloud_RoleName en effectuant une des opérations suivantes :

  • Pour Application Insights Java, définissez le nom du rôle cloud comme suit :

    {
      "role": {
        "name": "my cloud role name"
      }
    }
    

    Vous pouvez également définir le nom de rôle cloud à l’aide de la variable d’environnement APPLICATIONINSIGHTS_ROLE_NAME.

  • Avec Application Insights Java SDK 2.5.0 et ultérieur, vous pouvez spécifier cloud_RoleName en ajoutant <RoleName> à votre fichier ApplicationInsights.xml :

    Screenshot that shows Application Insights overview and connection string.

    <?xml version="1.0" encoding="utf-8"?>
    <ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings" schemaVersion="2014-05-30">
       <ConnectionString>InstrumentationKey=00000000-0000-0000-0000-000000000000</ConnectionString>
       <RoleName>** Your role name **</RoleName>
       ...
    </ApplicationInsights>
    
  • Si vous utilisez Spring Boot avec Application Insights Spring Boot Starter, définissez votre nom personnalisé pour l’application dans le fichier application.properties :

    spring.application.name=<name-of-app>

Vous pouvez également définir le nom de rôle cloud via la variable d’environnement ou la propriété système. Pour plus d’informations, consultez Configuration du nom de rôle cloud.

Étapes suivantes