Exemple d'instrumentation Python

Ce document explique comment instrumenter une application Python pour collecter des données de trace et de métrique à l'aide du SDK OpenTelemetry et d'un collecteur OpenTelemetry. Il explique également comment écrire des journaux JSON structurés dans la sortie standard. Pour tester l'instrumentation, téléchargez et exécutez l'application exemple. Cette application utilise le framework Web Flask et génère des données de journaux, de métriques et de trace.

Lorsque vous utilisez un collecteur OpenTelemetry, vous instrumentez votre application avec le SDK et l'exportateur OTLP intégré au SDK. Cette instrumentation est indépendante du fournisseur. Vous déployez également un collecteur OpenTelemetry qui reçoit les données de télémétrie de l'exportateur intégré, puis les exporte vers votre projet Google Cloud . Pour en savoir plus sur les collecteurs, consultez Collecteur OpenTelemetry conçu par Google.

Nous vous recommandons d'utiliser un collecteur OpenTelemetry pour exporter vos données de télémétrie lorsque votre environnement est compatible avec l'utilisation d'un collecteur. Pour certains environnements, vous devez utiliser un exportateur intégré qui envoie directement les données à votre projetGoogle Cloud . Pour en savoir plus sur l'instrumentation intégrée, consultez Migrer de l'exportateur de trace vers le point de terminaison OTLP.

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

À propos de l'instrumentation manuelle et sans code

Pour ce langage, OpenTelemetry définit l'instrumentation sans code 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 sans code. Pour en savoir plus à ce sujet, consultez Instrumentation Python sans code.

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

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud . Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $de crédits sans frais pour exécuter, tester et déployer des charges de travail.
  2. Installez la Google Cloud CLI.

  3. Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

  4. Pour initialiser la gcloud CLI, exécutez la commande suivante :

    gcloud init
  5. Créez ou sélectionnez un projet Google Cloud .

    Rôles requis pour sélectionner ou créer un projet

    • Sélectionnez un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique. Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
    • Créer un projet : pour créer un projet, vous devez disposer du rôle Créateur de projet (roles/resourcemanager.projectCreator), qui contient l'autorisation resourcemanager.projects.create. Découvrez comment attribuer des rôles.
    • Créez un projet Google Cloud  :

      gcloud projects create PROJECT_ID

      Remplacez PROJECT_ID par le nom du projet Google Cloud que vous créez.

    • Sélectionnez le projet Google Cloud que vous avez créé :

      gcloud config set project PROJECT_ID

      Remplacez PROJECT_ID par le nom de votre projet Google Cloud .

  6. Vérifiez que la facturation est activée pour votre projet Google Cloud .

  7. Activez les API Cloud Logging, Cloud Monitoring, Cloud Trace et Télémétrie :

    Rôles requis pour activer les API

    Pour activer les API, vous avez besoin du rôle IAM Administrateur Service Usage (roles/serviceusage.serviceUsageAdmin), qui contient l'autorisation serviceusage.services.enable. Découvrez comment attribuer des rôles.

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com telemetry.googleapis.com
  8. Installez la Google Cloud CLI.

  9. Si vous utilisez un fournisseur d'identité (IdP) externe, vous devez d'abord vous connecter à la gcloud CLI avec votre identité fédérée.

  10. Pour initialiser la gcloud CLI, exécutez la commande suivante :

    gcloud init
  11. Créez ou sélectionnez un projet Google Cloud .

    Rôles requis pour sélectionner ou créer un projet

    • Sélectionnez un projet : la sélection d'un projet ne nécessite pas de rôle IAM spécifique. Vous pouvez sélectionner n'importe quel projet pour lequel un rôle vous a été attribué.
    • Créer un projet : pour créer un projet, vous devez disposer du rôle Créateur de projet (roles/resourcemanager.projectCreator), qui contient l'autorisation resourcemanager.projects.create. Découvrez comment attribuer des rôles.
    • Créez un projet Google Cloud  :

      gcloud projects create PROJECT_ID

      Remplacez PROJECT_ID par le nom du projet Google Cloud que vous créez.

    • Sélectionnez le projet Google Cloud que vous avez créé :

      gcloud config set project PROJECT_ID

      Remplacez PROJECT_ID par le nom de votre projet Google Cloud .

  12. Vérifiez que la facturation est activée pour votre projet Google Cloud .

  13. Activez les API Cloud Logging, Cloud Monitoring, Cloud Trace et Télémétrie :

    Rôles requis pour activer les API

    Pour activer les API, vous avez besoin du rôle IAM Administrateur Service Usage (roles/serviceusage.serviceUsageAdmin), qui contient l'autorisation serviceusage.services.enable. Découvrez comment attribuer des rôles.

    gcloud services enable logging.googleapis.com monitoring.googleapis.com cloudtrace.googleapis.com telemetry.googleapis.com
  14. Si vous exécutez l'exemple dans Cloud Shell, sur des ressources Google Cloudou dans un environnement de développement local, les autorisations listées dans cette section sont suffisantes. Pour les applications de production, un compte de service fournit généralement les identifiants permettant d'écrire des données de journaux, de métriques et de trace.

    Pour obtenir les autorisations nécessaires pour que l'application exemple écrive des données de journaux, de métriques et de trace, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

    Pour obtenir les autorisations nécessaires pour afficher vos données de journaux, de métriques et de traces, demandez à votre administrateur de vous accorder les rôles IAM suivants sur votre projet :

    Pour en savoir plus sur l'attribution de rôles, consultez Gérer l'accès aux projets, aux dossiers et aux organisations.

    Vous pouvez également obtenir les autorisations requises avec des rôles personnalisés ou d'autres rôles prédéfinis.

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.

def setup_opentelemetry() -> None:
    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()}",
        }
    )
    # Set up OpenTelemetry Python SDK
    tracer_provider = TracerProvider(resource=resource)
    tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
    trace.set_tracer_provider(tracer_provider)

    logger_provider = LoggerProvider(resource=resource)
    logger_provider.add_log_record_processor(BatchLogRecordProcessor(OTLPLogExporter()))
    logs.set_logger_provider(logger_provider)

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

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.

class JsonFormatter(jsonlogger.JsonFormatter):
    def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None):
        # Format the timestamp as RFC 3339 with microsecond precision
        isoformat = datetime.fromtimestamp(record.created).isoformat()
        return f"{isoformat}Z"


def setup_structured_logging() -> None:
    LoggingInstrumentor().instrument()

    log_handler = logging.StreamHandler()
    formatter = 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",
        },
    )
    log_handler.setFormatter(formatter)
    logging.basicConfig(
        level=logging.INFO,
        handlers=[log_handler],
    )

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'instrumentation de l'application exemple utilise des formats neutres du point de vue du fournisseur, comme JSON pour les données de journaux et OTLP pour les données de métriques et de traces. L'application exemple utilise également Flask pour diffuser les requêtes HTTP, et la bibliothèque de requêtes pour lancer ces requêtes HTTP. L'Collector OpenTelemetry envoie des données de journaux et de métriques à votre projet à l'aide d'exportateurs Google. Il envoie vos données de trace à votre projet à l'aide de l'API Telemetry, qui utilise OTLP.

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__)

# Initialize OpenTelemetry Python SDK and structured logging
setup_opentelemetry()
setup_structured_logging()

app = Flask(__name__)

# Add instrumentation
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."""
        sub_requests = randint(3, 7)
        logger.info("handle /multi request", extra={"subRequests": sub_requests})
        for _ in range(sub_requests):
            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)
        logger.info("handle /single request", extra={"duration": duration})
        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. Dans la console Google Cloud , activez Cloud Shell.

    Activer Cloud Shell

    En bas de la console Google Cloud , une session Cloud Shell démarre et affiche une invite de ligne de commande. Cloud Shell est un environnement shell dans lequel Google Cloud CLI est déjà installé, et dans lequel des valeurs sont déjà définies pour votre projet actuel. L'initialisation de la session peut prendre quelques secondes.

  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 la barre d'outils de la console Google Cloud , sélectionnez votre projet Google Cloud . Pour les configurations App Hub, sélectionnez le projet hôte App Hub ou le projet de gestion du dossier compatible avec les applications.
  3. 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.
  4. Pour ajouter des filtres qui suppriment des séries temporelles des résultats de la requête, utilisez l'élément Filtre.

  5. 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

L'affichage de vos données de trace peut prendre plusieurs minutes. Par exemple, lorsque des données de trace sont reçues par votre projet, Google Cloud Observability peut avoir besoin de créer une base de données pour les stocker. La création de la base de données peut prendre quelques minutes. Pendant cette période, aucune donnée de trace n'est disponible.

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 la section du tableau de la page, sélectionnez une ligne avec le nom de portée /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 pageExplorateur 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.

    Vos données de journaux peuvent être disponibles plusieurs minutes avant vos données de trace. Si vous rencontrez une erreur lors de l'affichage des données de trace, que ce soit en recherchant une trace par ID ou en suivant les étapes de cette tâche, attendez une ou deux minutes, puis réessayez.

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

Étapes suivantes