Générer des traces et des métriques avec Python

Ce document explique comment modifier une application Python pour collecter des données de trace et de métrique à l'aide du framework Open Source OpenTelemetry, et comment écrire des journaux JSON structurés sur la sortie standard. Il fournit également des informations sur un exemple d'application Pyhton que vous pouvez installer et exécuter. L'application utilise le framework Web Fastify et est configurée pour générer des métriques, des traces et des journaux.

Pour en savoir plus sur l'instrumentation, consultez les documents suivants :

À propos des instrumentations manuelle et automatique

Pour ce langage, OpenTelemetry définit l'instrumentation automatique comme une pratique consistant à collecter des données de télémétrie à partir de bibliothèques et de frameworks sans modifier le code. En revanche, vous devez installer des modules et définir des variables d'environnement.

Ce document ne décrit pas l'instrumentation automatique. Pour en savoir plus à ce sujet, consultez la section Instrumentation automatique pour Python.

Pour obtenir des informations générales, consultez la section Instrumentation OpenTelemetry pour Python.

Avant de commencer

Enable the Cloud Logging, Cloud Monitoring, and Cloud Trace APIs.

Enable the APIs

Instrumenter votre application pour collecter des traces, des métriques et des journaux

Pour instrumenter votre application afin de collecter des données de trace et de métrique, et d'écrire un code JSON structuré sur la sortie standard, appliquez la procédure décrite dans les sections suivantes de ce document :

  1. Configurer OpenTelementry
  2. Configurer la journalisation structurée

Configurer OpenTelementry

Cet exemple d'application est configuré pour utiliser le SDK Python OpenTelemetry afin d'exporter des traces et des métriques à l'aide du protocole OTLP. Par défaut, le SDK Python OpenTelemetry utilise le format de contexte de trace W3C pour propager le contexte de trace, ce qui garantit que les segments disposent de la relation parent-enfant appropriée au sein d'une trace.

L'exemple de code suivant illustre un module Python permettant de configurer OpenTelemetry. Pour afficher l'exemple complet, cliquez sur  Plus, puis sélectionnez Afficher sur GitHub.

resource = Resource.create(attributes={
    # Use the PID as the service.instance.id to avoid duplicate timeseries
    # from different Gunicorn worker processes.
    SERVICE_INSTANCE_ID: f"worker-{os.getpid()}",
})

traceProvider = TracerProvider(resource=resource)
processor = BatchSpanProcessor(OTLPSpanExporter())
traceProvider.add_span_processor(processor)
trace.set_tracer_provider(traceProvider)

reader = PeriodicExportingMetricReader(
    OTLPMetricExporter()
)
meterProvider = MeterProvider(metric_readers=[reader], resource=resource)
metrics.set_meter_provider(meterProvider)

L'application Flask s'appuie sur Gunicorn pour diffuser les requêtes HTTP en suivant les recommandations du guide de déploiement en production de Flask. Gunicorn démarre plusieurs copies de votre application, exécutées dans des processus de nœud de calcul indépendants, afin d'augmenter le débit. Pour éviter des conflits entre les différentes métriques associées aux processus de nœud de calcul, nous recommandons que chaque processus de nœud de calcul définisse une valeur unique pour l'attribut de ressource service.instance.id. Pour ce faire, vous pouvez inclure l'ID de processus dans service.instance.id. Pour en savoir plus, consultez la section Conflits de séries temporelles.

Pour en savoir plus et obtenir des options de configuration, consultez la page Instrumentation OpenTelemetry pour Python.

Configurer la journalisation structurée

Pour écrire des journaux structurés associés à des traces, configurez votre application de sorte qu'elle génère des journaux au format JSON dans la sortie standard, avec des clés contenant des informations de trace. L'exemple de code suivant montre comment configurer la bibliothèque logging standard pour générer des journaux JSON structurés à l'aide de la bibliothèque python-json-logger, et comment utiliser le package opentelemetry-instrumentation-logging pour inclure des informations de trace.

LoggingInstrumentor().instrument()

logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter(
    "%(asctime)s %(levelname)s %(message)s %(otelTraceID)s %(otelSpanID)s %(otelTraceSampled)s",
    rename_fields={
        "levelname": "severity",
        "asctime": "timestamp",
        "otelTraceID": "logging.googleapis.com/trace",
        "otelSpanID": "logging.googleapis.com/spanId",
        "otelTraceSampled": "logging.googleapis.com/trace_sampled",
        },
    datefmt="%Y-%m-%dT%H:%M:%SZ",
)
logHandler.setFormatter(formatter)
logging.basicConfig(
    level=logging.INFO,
    handlers=[logHandler],
)

La configuration précédente extrait des informations sur le délai actif du message de journal, puis ajoute ces informations en tant qu'attributs au journal structuré JSON. Ces attributs peuvent ensuite être utilisés pour mettre en corrélation un journal et une trace:

  • logging.googleapis.com/trace: nom de ressource de la trace associée à l'entrée de journal.
  • logging.googleapis.com/spanId: ID de délai avec la trace associée à l'entrée de journal.
  • logging.googleapis.com/trace_sampled: la valeur de ce champ doit être true ou false.

Pour en savoir plus sur ces champs, consultez la structure LogEntry.

Exécuter un exemple d'application configuré pour collecter les données de télémétrie

L'exemple d'application utilise des formats indépendants du fournisseur, y compris JSON pour les journaux et OTLP pour les métriques et les traces. Les données de télémétrie issues de l'application sont acheminées vers Google Cloud à l'aide du Collector OpenTelemetry configuré avec les exportateurs Google. Il utilise Flask pour diffuser les requêtes HTTP, et la bibliothèque de requêtes pour lancer ces requêtes HTTP. Pour générer des métriques et des traces pour le client et le serveur HTTP, l'exemple d'application installe les bibliothèques d'instrumentation opentelemetry-instrumentation-flask et opentelemetry-instrumentation-requests.

logger = logging.getLogger(__name__)

app = Flask(__name__)
FlaskInstrumentor().instrument_app(app)
RequestsInstrumentor().instrument()

L'application possède deux points de terminaison:

  • Le point de terminaison /multi est géré par la fonction multi. Le générateur de charge de l'application envoie des requêtes au point de terminaison /multi. Lorsque ce point de terminaison reçoit une requête, il envoie entre trois et sept requêtes au point de terminaison /single sur le serveur local.

    @app.route('/multi')
    def multi():
        """Handle an http request by making 3-7 http requests to the /single endpoint."""
        subRequests = randint(3, 7)
        logger.info("handle /multi request", extra={'subRequests': subRequests})
        for _ in range(subRequests):
            requests.get(url_for('single', _external=True))
        return 'ok'
  • Le point de terminaison /single est géré par la fonction single. Lorsque ce point de terminaison reçoit une requête, il reste en veille pendant un court délai, puis répond par une chaîne.

    @app.route('/single')
    def single():
        """Handle an http request by sleeping for 100-200 ms, and write the number of seconds slept as the response."""
        duration = uniform(0.1, 0.2)
        time.sleep(duration)
        return f'slept {duration} seconds'

Télécharger et déployer l'application

Pour exécuter l'exemple , procédez comme suit :

  1. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

    At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.

  2. Clonez le dépôt :

    git clone https://github.com/GoogleCloudPlatform/opentelemetry-operations-python
    
  3. Accédez au répertoire de l'exemple :

    cd opentelemetry-operations-python/samples/instrumentation-quickstart
    
  4. Compilez et exécutez l'exemple.

    docker compose up --abort-on-container-exit
    

    Si vous n'exécutez pas sur Cloud Shell, exécutez l'application avec la variable d'environnement GOOGLE_APPLICATION_CREDENTIALS pointant vers un fichier d'identifiants. Les identifiants par défaut de l'application fournissent un fichier d'identifiants à l'adresse $HOME/.config/gcloud/application_default_credentials.json.

    # Set environment variables
    export GOOGLE_CLOUD_PROJECT="PROJECT_ID"
    export GOOGLE_APPLICATION_CREDENTIALS="$HOME/.config/gcloud/application_default_credentials.json"
    export USERID="$(id -u)"
    
    # Run
    docker compose -f docker-compose.yaml -f docker-compose.creds.yaml up --abort-on-container-exit
    

Afficher vos métriques

L'instrumentation OpenTelementry dans l'exemple d'application génère des métriques Prometheus que vous pouvez afficher à l'aide de l'explorateur de métriques:

  • Prometheus/http_server_duration_milliseconds/histogram enregistre la durée des requêtes du serveur et stocke les résultats dans un histogramme.

  • Prometheus/http_client_duration_milliseconds/histogram enregistre la durée des requêtes des clients et stocke les résultats dans un histogramme.

Pour afficher les métriques générées par l'exemple d'application, procédez comme suit :
  1. Dans la console Google Cloud, accédez à la page  Explorateur de métriques :

    Accéder à l'explorateur de métriques

    Si vous utilisez la barre de recherche pour trouver cette page, sélectionnez le résultat dont le sous-titre est Monitoring.

  2. Dans l'élément Métrique, développez le menu Sélectionner une métrique, saisissez http_server dans la barre de filtre, puis utilisez les sous-menus pour sélectionner un type de ressource et des métriques spécifiques :
    1. Dans le menu Ressources actives, sélectionnez Cible Prometheus.
    2. Dans le menu Catégories de métriques actives, sélectionnez Http.
    3. Dans le menu Métriques actives, sélectionnez une métrique.
    4. Cliquez sur Appliquer.
  3. Configurez le mode d'affichage des données.

    Lorsque les mesures d'une métrique sont cumulatives, l'explorateur de métriques normalise automatiquement les données mesurées par période d'alignement, ce qui permet d'afficher un taux dans le graphique. Pour en savoir plus, consultez la section Genres, types et conversions.

    Lorsque des valeurs entières ou doubles sont mesurées, par exemple avec les deux métriques counter, l'explorateur de métriques additionne automatiquement toutes les séries temporelles. Pour afficher les données des routes HTTP /multi et /single, définissez le premier menu de l'entrée Agrégation sur Aucun.

    Pour plus d'informations sur la configuration d'un graphique, consultez la page Sélectionner des métriques lors de l'utilisation de l'explorateur de métriques.

Afficher vos traces

Pour afficher vos données de trace, procédez comme suit:

  1. Dans la console Google Cloud, accédez à la page Explorateur Trace.

    Accéder à Explorateur Trace

    Vous pouvez également accéder à cette page à l'aide de la barre de recherche.

  2. Dans le graphique à nuage de points, sélectionnez une trace avec l'URI /multi.
  3. Dans le graphique de Gantt du panneau Détails des traces, sélectionnez le délai intitulé /multi.

    Un panneau contenant des informations sur la requête HTTP s'affiche. Ces informations incluent la méthode, le code d'état, le nombre d'octets et le user-agent de l'appelant.

  4. Pour afficher les journaux associés à cette trace, sélectionnez l'onglet Logs & Events (Journaux et événements).

    Cet onglet affiche les journaux individuels. Pour afficher les détails de l'entrée de journal, développez-la. Vous pouvez également cliquer sur Afficher les journaux et afficher le journal à l'aide de l'explorateur de journaux.

Pour en savoir plus sur l'utilisation de l'explorateur Cloud Trace, consultez la page Rechercher et explorer des traces.

Afficher les journaux

L'explorateur de journaux vous permet d'inspecter vos journaux et d'afficher les traces associées, lorsqu'elles existent.

  1. Dans la console Google Cloud, accédez à la page Explorateur de journaux :

    Accéder à l'explorateur de journaux

    Si vous utilisez la barre de recherche pour trouver cette page, sélectionnez le résultat dont le sous-titre est Logging.

  2. Recherchez un journal avec la description suivante : handle /multi request.

    Pour afficher les détails du journal, développez l'entrée de journal.

  3. Cliquez sur Traces sur une entrée de journal contenant le message "handle /multi request", puis sélectionnez Afficher les détails des traces.

    Un panneau Trace details (Informations sur la trace) s'ouvre et affiche la trace sélectionnée.

Pour en savoir plus sur l'utilisation de l'explorateur de journaux, consultez la page Afficher les journaux à l'aide de l'explorateur de journaux.

Étapes suivantes