Diagramme d'architecture d'observabilité : logs, métriques et traces avec OpenTelemetry

Comment schématiser un pipeline d'observabilité : SDK OpenTelemetry, Collectors en agent et en gateway, tail sampling et destination des logs, métriques et traces.

· Fondateur et développeur

Publié le

Diagramme d'architecture d'observabilité : logs, métriques et traces avec OpenTelemetry

La plupart des diagrammes d'architecture s'arrêtent aux services. Le chemin de la télémétrie est dessiné plus tard, pendant un incident, par la personne qui essaie de comprendre pourquoi la moitié des traces manque ou pourquoi la facture de logs a doublé. À ce moment-là, la réponse dépend de détails que personne n'a écrits : quel composant échantillonne, lequel ajoute le nom du pod, et ce qui se passe quand un backend ralentit.

Un diagramme d'architecture d'observabilité montre comment les logs, les métriques et les traces quittent chaque service, où ils sont enrichis, échantillonnés et filtrés, et où ils aboutissent. Cet article en construit un autour d'OpenTelemetry sur Kubernetes, explique les modèles agent et gateway qui le sous-tendent et liste ce qu'il faut étiqueter pour que le diagramme serve encore lors de la prochaine panne.

Trois signaux, trois questions

Signal Question à laquelle il répond Source typique Destination habituelle
Métriques Y a-t-il un problème, et de quelle ampleur ? Compteurs et histogrammes du SDK, statistiques du kubelet et des nœuds Une base de séries temporelles, par exemple un stockage compatible Prometheus
Traces Où, dans le chemin de la requête, se situe le problème ? Spans du SDK ou de l'auto-instrumentation Un stockage de traces, comme Jaeger ou Tempo
Logs Que s'est-il passé exactement ? stdout et stderr, fichiers de logs, enregistrements de logs du SDK Un stockage de logs, comme Loki ou OpenSearch

Les trois ne sont utiles ensemble que s'ils partagent leur contexte. Un trace ID dans la ligne de log, et les mêmes service.name et nom de pod sur chaque signal, vous permettent de passer d'une alerte au span lent, puis à la ligne de log qui l'explique. L'architecture doit préserver ce contexte.

Les briques de base

OTLP est le protocole OpenTelemetry pour les trois signaux. La spécification fixe les ports par défaut : 4317 pour OTLP sur gRPC et 4318 pour OTLP sur HTTP.

Les SDK et l'auto-instrumentation s'exécutent dans chaque service et exportent de l'OTLP. Faites-les pointer vers un Collector local plutôt que vers un fournisseur, pour qu'un changement de routage ne demande pas de redéploiement.

Le Collector est un binaire unique avec des pipelines par signal : les receivers reçoivent les données, les processors les modifient, les exporters les envoient plus loin. La documentation de déploiement décrit deux grandes façons de l'exécuter :

  • Agent. Un Collector tourne à côté de l'application, en sidecar ou en DaemonSet avec un pod par nœud. Sur Kubernetes, l'agent est aussi l'endroit où travaillent les composants Kubernetes : le Kubernetes Attributes Processor ajoute les noms de pod, de namespace et de deployment, le Filelog Receiver suit les sorties stdout et stderr des conteneurs, et le Kubeletstats Receiver récupère les métriques des nœuds et des pods.
  • Gateway. Un ou plusieurs Collectors tournent comme un service autonome, en général un point de terminaison par cluster, centre de données ou région. La gateway est l'endroit des décisions que vous voulez prendre une seule fois : l'échantillonnage, le filtrage des attributs sensibles, la détention des identifiants des backends et l'envoi vers plusieurs backends.

Head sampling ou tail sampling

Les traces sont le signal coûteux, donc la plupart des équipes les échantillonnent. Le head sampling décide au début de la trace, par exemple d'en garder 10 %. Il est peu coûteux, mais il ne peut pas garder une trace parce qu'elle a échoué ensuite. Le tail sampling décide après avoir vu tout ou partie des spans d'une trace ; il peut donc garder chaque erreur et chaque requête lente.

Le tail sampling a un coût structurel : tous les spans d'une trace doivent atteindre le même Collector. Derrière un répartiteur de charge en round-robin, ce n'est pas le cas. Le modèle gateway résout cela avec deux étages : le premier exécute le load-balancing exporter avec le trace ID comme clé de routage, le second exécute le tail sampling processor. Cela fait deux boîtes sur le diagramme, et il vaut la peine de montrer les deux.

L'exemple : une boutique sur Kubernetes

La boutique fait tourner trois Deployments dans un namespace shop : web, checkout-api et payments-worker, chacun avec le SDK OpenTelemetry. Le namespace observability contient le pipeline : un DaemonSet otel-agent, un Deployment otel-lb qui route les spans par trace ID et un Deployment otel-sampler qui applique la politique de tail sampling. Les métriques, les traces et les logs vont chacun vers leur propre stockage, et des règles d'alerte s'exécutent sur les métriques.

Trois Deployments du namespace shop envoient l'OTLP sur le port 4317 au DaemonSet otel-agent, qui lit aussi les logs stdout. L'agent envoie les traces à un étage de répartition, puis de tail sampling et au stockage ; métriques et logs vont à leur stockage. Les alertes lisent les métriques.

13 composants · 10 connexions

Ouvrir dans Archboard
Contenu du diagramme
  • shop
  • web
  • checkout-api
  • payments-worker
  • observability
  • otel-agent
  • otel-lb
  • otel-sampler
  • Trace store
  • Metrics store
  • Log store
  • Alerting
  • OTLP/gRPC 4317
  • stdout logs (filelog)
  • traces
  • by trace ID
  • kept traces
  • metrics
  • logs
  • alert rules
Un pipeline d'observabilité sur Kubernetes : les services envoient l'OTLP à un agent Collector sur chaque nœud, qui ajoute les métadonnées Kubernetes et lit les logs des conteneurs ; une gateway à deux étages fait le tail sampling et chaque signal va à son backend.

Comment le lire :

  • À gauche, les services. Chaque Deployment exporte traces, métriques et logs en OTLP/gRPC sur le port 4317 vers l'agent de son nœud. Le lien pointillé représente le stdout des conteneurs, que l'agent lit sur le nœud au lieu de le recevoir par le réseau.
  • Au milieu, l'agent. L'agent ajoute les métadonnées Kubernetes à tout, puis envoie métriques et logs directement à leurs stockages, et les traces à la gateway.
  • Au milieu, la gateway. otel-lb route chaque span par trace ID, si bien que tous les spans d'une trace atteignent le même pod otel-sampler, qui garde les erreurs et les traces lentes et échantillonne le reste.
  • À droite, stockage et alertes. Chaque signal a son propre backend. Les règles d'alerte lisent les métriques et appellent la personne d'astreinte.
  • Le bloc Markdown énonce la politique d'échantillonnage et la règle que suit chaque pipeline : le memory limiter en premier.

Ce qu'il faut étiqueter

  • Le protocole et le port sur chaque saut. OTLP/gRPC 4317 ou OTLP/HTTP 4318, et le format d'export vers chaque backend.
  • Les signaux qui passent sur chaque lien. Un même pipeline transporte rarement les trois de la même façon.
  • Où se fait l'échantillonnage, et selon quelle politique. Écrivez les chiffres ; un simple « échantillonné » invite aux mauvaises hypothèses.
  • Où les données sont enrichies ou masquées. Les métadonnées Kubernetes dans l'agent, la suppression des jetons et des données personnelles dans la gateway.
  • La rétention par backend. Elle explique le coût et ce qu'une investigation peut encore retrouver.
  • Le comportement en cas de panne. Files d'attente, nouvelles tentatives, et ce qui est perdu quand un backend tombe.

Erreurs courantes

  • Des SDK qui exportent directement vers un fournisseur. Chaque changement de routage ou d'identifiants devient un redéploiement, et il n'existe aucun endroit pour filtrer les données avant qu'elles sortent.
  • Le tail sampling derrière un simple répartiteur de charge. Les spans d'une même trace atterrissent sur des Collectors différents, et les décisions d'échantillonnage portent sur des fragments.
  • Pas de memory limiter. La documentation de configuration inclut un processor memory_limiter ; placez-le en premier dans chaque pipeline pour qu'en cas de pic le Collector refuse des données au lieu de manquer de mémoire.
  • Des labels de métriques à forte cardinalité. Un ID d'utilisateur ou de requête en label de métrique multiplie les séries temporelles. Mettez-le plutôt sur les spans et les logs.
  • Un pipeline non surveillé. Le Collector expose ses propres métriques, par défaut sur le port 8888, comme le décrit sa documentation de télémétrie interne. Créez des alertes sur les exports en échec, sinon vous découvrirez la perte de données pendant l'incident qui en avait besoin.

Pour le cluster lui-même, le diagramme d'architecture Kubernetes couvre le plan de contrôle, les nœuds et les charges de travail, et le diagramme d'architecture microservices couvre les services que ce pipeline observe.

Le construire dans Archboard

  1. Connectez-vous avec Google ou GitHub et créez un diagramme.
  2. Depuis le pack Kubernetes, ajoutez deux cadres Namespace, shop et observability. Placez un Deployment pour chaque service dans shop.
  3. Dans observability, ajoutez un DaemonSet pour l'agent et deux nœuds Deployment pour les étages de répartition et d'échantillonnage.
  4. Depuis le pack DevOps, ajoutez des nœuds Métriques, Traçage et Journaux pour les backends, et un nœud Alerte pour l'alerting.
  5. Reliez-les et étiquetez chaque lien avec les signaux et le protocole, par exemple « OTLP/gRPC 4317 ». Dessinez le lien des logs de conteneurs en pointillé.
  6. Ajoutez un bloc Markdown du pack Base avec la politique d'échantillonnage.

L'exemple utilise 13 nœuds de diagramme et reste dans les limites de l'offre Free. Si vos services tournent déjà sur Kubernetes, l'outil Kubernetes YAML vers diagramme transforme les manifestes en une première version de la moitié gauche.

FAQ

Ai-je besoin d'un Collector en gateway, ou les agents suffisent-ils ? Les agents seuls conviennent aux petites installations. Ajoutez une gateway quand vous avez besoin de tail sampling, d'un seul endroit pour les identifiants et le filtrage, ou de plusieurs backends ; l'agent lui transmet alors les données.

Les logs doivent-ils aussi passer par le Collector ? Ils le peuvent. Le Filelog Receiver de l'agent lit les logs des conteneurs, ajoute les mêmes métadonnées Kubernetes que pour les traces et les métriques, et vous permet de filtrer avant le stockage. Beaucoup d'équipes font passer les logs par le Collector en dernier, après les traces et les métriques.

Le head sampling suffit-il parfois ? Oui, quand le trafic est faible ou que toutes les traces se ressemblent. Si vous devez garder chaque erreur et chaque requête lente, utilisez le tail sampling et dessinez les deux étages de gateway qu'il exige.

Où placer les tableaux de bord et les alertes sur le diagramme ? À côté du stockage qu'ils interrogent. Les règles d'alerte sur les métriques font partie de l'architecture : ce sont elles qui décident qui est réveillé.

Comment garder ce diagramme à jour ? Modifiez-le dans la même pull request que la configuration du Collector, et ajoutez-y un lien depuis le runbook. Voir des diagrammes d'architecture qui ne se périment pas.

Commencez gratuitement — un siège, sans carte bancaire.

Articles associés

← Retour au blog

Ouvrez un canevas en une minute

Connectez-vous avec Google ou GitHub. Gratuit pour un siège. Passez à un forfait supérieur quand l’équipe vous rejoint.