L'export équivalent vers Cloud Monitoring et Cloud Trace, puis le nettoyage
L'assistant d'Ondine part en production sur Cloud Run. L'équipe, quatre personnes, ne veut pas opérer Prometheus, Tempo et Loki en plus du reste : sauvegardes, rétention, montées de version, disques pleins. Elle veut les mêmes signaux dans Cloud Monitoring, Cloud Trace et Cloud Logging, sans réécrire l'instrumentation des leçons 2 et 3. C'est le bénéfice concret du collecteur : seule sa configuration change.
Le mécanisme : la même application, un autre collecteur
flowchart LR APP["Service Cloud Run<br/>(code inchangé, OTLP)"] -->|"localhost:4318"| COL["Collecteur en sidecar<br/>collector-gcp.yaml"] COL -->|"OTLP/HTTP + googleclientauth"| API["API Telemetry<br/>telemetry.googleapis.com"] API --> TR["Cloud Trace"] API --> MON["Cloud Monitoring<br/>(PromQL possible)"] COL -->|"OTLP gRPC"| LOG["Cloud Logging"]
Google Cloud accepte désormais OTLP directement via l'API Telemetry (telemetry.googleapis.com) ; sa documentation de migration décrit le passage des anciens exportateurs propres à Google (googlecloud, googlemanagedprometheus) à ces exportateurs OTLP standard. L'extension googleclientauth signe les requêtes avec les identifiants par défaut de l'environnement (le compte de service du service Cloud Run).
| Lab (cette formation) | Google Cloud | Ce qui change pour l'équipe |
|---|---|---|
| Prometheus | Cloud Monitoring (métriques OTLP, requêtes PromQL acceptées) | plus de disque ni de rétention à gérer ; facturation à l'ingestion |
| Tempo | Cloud Trace | même modèle de spans ; recherche par attribut dans la console |
| Loki | Cloud Logging | journaux corrélés aux traces par trace_id dans la console |
| Grafana provisionné | tableaux de bord Cloud Monitoring (définis en JSON ou Terraform), ou Grafana branché sur Cloud Monitoring | les requêtes PromQL du générateur restent réutilisables |
| Règles Grafana | règles d'alerte Cloud Monitoring en PromQL | mêmes seuils, mêmes for |
La mise en œuvre
1. La configuration du collecteur pour Google Cloud
extensions:
googleclientauth: # identifiants par défaut (ADC) : compte de service sur Cloud Run / GKE
project: ${env:GOOGLE_CLOUD_PROJECT}
quota_project: ${env:GOOGLE_CLOUD_PROJECT}
processors:
resourcedetection: # ajoute la plateforme (cloud.platform, région, instance) si détectée
detectors: [env, gcp]
resource/gcp_project_id: # obligatoire : l'API Telemetry range les données par projet
attributes:
- { key: gcp.project_id, value: "${env:GOOGLE_CLOUD_PROJECT}", action: insert }
exporters:
otlphttp/gcp:
endpoint: https://telemetry.googleapis.com
encoding: proto
auth: { authenticator: googleclientauth }
otlp_grpc/logs:
endpoint: telemetry.googleapis.com:443
balancer_name: pick_first
auth: { authenticator: googleclientauth }Les pipelines reprennent ceux du lab : memory_limiter en tête, la suppression des contenus de prompt sur les traces, batch en fin. Seuls les exportateurs et les deux processeurs de ressource changent.
2. Valider sans rien envoyer
make valider-gcpLa cible lance otelcol-contrib validate dans l'image épinglée : le binaire charge la configuration, vérifie chaque composant et chaque clé, sans démarrer de pipeline ni contacter Google Cloud.
3. Ce qu'il faudrait pour déployer (non exécuté ici)
Ce projet ne crée aucune ressource Google Cloud (make cloud-up l'annonce). Les étapes, à adapter, sont :
gcloud services enable telemetry.googleapis.com --project=<projet>- Un compte de service dédié au service, avec
roles/telemetry.writer(écriture des traces, métriques et journaux) etroles/serviceusage.serviceUsageConsumer(consommation du quota du projet). - Un déploiement Cloud Run multi-conteneurs : l'application en conteneur principal, le collecteur en sidecar qui monte
collector-gcp.yaml, avecOTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318côté application. - Les mêmes requêtes PromQL que
generer_tableau.pypour les tableaux de bord et les alertes Cloud Monitoring.
Le coût dépend du volume ingéré (échantillons de métriques, spans, Gio de journaux) ; consultez la grille de Google Cloud Observability avant d'activer les traces sur 100 % des requêtes. À fort trafic, échantillonnez les traces (par exemple 10 % des requêtes réussies, 100 % des erreurs) ; les métriques, agrégées, restent exactes.
Résultat obtenu
Le 2026-10-16 :
$ make valider-gcp
collector-gcp.yaml valideLa validation détecte bien les erreurs : avec balancer_nam au lieu de balancer_name, la même commande échoue avec 'otlpexporter.Config' has invalid keys: balancer_nam.
Puis l'arrêt de la pile du lab, vérifié :
$ make down
Volume lab-otel_grafana_data Removed
Volume lab-otel_tempo_data Removed
Volume lab-otel_prometheus_data Removed
Volume lab-otel_loki_data Removed
Network lab-otel_default Removed
Pile et volumes lab-otel supprimés.
$ docker ps -a --filter name=lab-otel -q | wc -l ; docker volume ls --filter name=lab-otel -q | wc -l
0
0Ce qui casse en production
| Symptôme | Cause | Parade |
|---|---|---|
| Rien n'arrive dans Cloud Trace, l'application ne voit aucune erreur | compte de service sans roles/telemetry.writer : le collecteur reçoit des 403 et jette les données | lire les journaux du collecteur au premier déploiement ; alerte sur les métriques d'envoi en échec du collecteur |
| Données refusées avec une erreur de projet | gcp.project_id absent des ressources | processeur resource/gcp_project_id, GOOGLE_CLOUD_PROJECT défini |
| Dernières traces perdues, exports en retard sur Cloud Run | CPU alloué seulement pendant les requêtes : le sidecar ne peut pas vider ses lots entre deux requêtes | CPU toujours alloué pour le service, ou lots plus petits et délai d'arrêt suffisant |
| Facture d'observabilité supérieure à celle du modèle | 100 % des traces, labels à forte cardinalité, journaux en DEBUG | échantillonnage des traces, labels bornés (leçon 2), niveau INFO |
| Deux versions des métriques pendant la migration | collecteur local et collecteur Google Cloud actifs en parallèle, noms traduits différemment | une période de double écriture courte et datée, tableaux de bord comparés avant d'éteindre l'ancien |
La règle de décision
Restez sur la pile ouverte si l'équipe l'opère déjà, doit rester hors cloud, ou garde les données sur ses propres disques pour une raison réglementaire. Passez aux services gérés de Google Cloud quand l'application y tourne déjà et que personne ne veut opérer trois bases de données de télémétrie : vous gardez OpenTelemetry, les conventions gen_ai et vos requêtes PromQL, vous changez un fichier. Dans les deux cas, gardez l'application ignorante de la destination : elle parle OTLP à un collecteur, rien d'autre.
Pratique
Après la mise en production sur Cloud Run, Cloud Trace reste vide. L'application répond normalement et ses journaux ne montrent aucune erreur. Que regardez-vous en premier ?
L'application exporte vers le collecteur local, qui accepte les données ; c'est l'envoi du collecteur vers Google Cloud qui échoue. Le code d'instrumentation n'a pas changé depuis le lab, où il fonctionnait. La latence de Gemini n'a aucun lien avec l'export.
Le trafic passe à 2 millions de requêtes par jour. Le coût d'ingestion des traces devient significatif. Quelle stratégie retenez-vous ?
Les métriques, agrégées, restent exactes et bon marché ; ce sont elles qui alimentent alertes et tableaux de bord. Les traces servent au diagnostic : un échantillon suffit, à condition de garder les cas intéressants (erreurs, lenteurs). Sans traces, plus de diagnostic ; exporter les métriques une fois par heure rendrait les alertes inutiles.
Exercice. Ajoutez à collector-gcp.yaml un échantillonnage qui garde 10 % des traces réussies et 100 % des traces en erreur, puis validez la configuration.
Voir la solution
Le processeur tail_sampling décide une fois la trace complète, ce qui permet de garder toutes les erreurs :
processors:
tail_sampling:
decision_wait: 10s
policies:
- { name: erreurs, type: status_code, status_code: { status_codes: [ERROR] } }
- { name: lentes, type: latency, latency: { threshold_ms: 8000 } }
- { name: echantillon, type: probabilistic, probabilistic: { sampling_percentage: 10 } }Ajoutez tail_sampling dans le pipeline traces, après memory_limiter et avant batch, puis make valider-gcp (configuration ainsi complétée validée le 2026-10-16). Deux limites : toutes les spans d'une trace doivent atteindre le même collecteur (vrai avec un sidecar par instance tant qu'une trace ne traverse qu'un service), et le collecteur garde les traces en mémoire pendant decision_wait, ce qui se dimensionne avec memory_limiter.
- Je sais passer de la pile ouverte à Google Cloud en ne changeant que la configuration du collecteur.
- Je sais valider une configuration de collecteur sans rien envoyer.
- Je sais quels rôles IAM et quels attributs de ressource l'API Telemetry exige.
- Je sais arrêter la pile du lab et vérifier qu'il ne reste ni conteneur ni volume.