Observer l'observateur : la télémétrie interne de l'OpenTelemetry Collector
Logs, métriques et traces que le Collector émet sur lui-même : toutes les options de service::telemetry, stdout ou OTLP pour les logs, Prometheus ou OTLP pour les métriques, et comment tout configurer.
Le Collector est souvent la pièce la plus critique de votre chaîne d’observabilité : tout transite par lui. S’il ralentit, sature sa file ou laisse tomber des données, c’est tout votre pipeline qui est aveugle — et vous avec. D’où la question : qui observe l’observateur ?
Bonne nouvelle, le Collector est lui-même instrumenté. Il émet ses propres
logs, métriques et traces, et tout se configure au même endroit :
la section service::telemetry. Cet article fait le tour des options, signal
par signal, avec des exemples concrets — notamment le choix stdout ou OTLP
pour les logs et Prometheus ou OTLP pour les métriques.
Le contexte de versions : depuis la v0.123 du Collector, la configuration de la télémétrie interne s’appuie sur la config déclarative du SDK OpenTelemetry (
readers,processors,exporters). C’est ce schéma moderne que nous décrivons ici. L’ancien champservice::telemetry::metrics::addressest déprécié au profit dereaders.
La carte générale : service::telemetry
Toute la télémétrie interne se déclare sous service::telemetry, avec quatre
sous-sections :
service:
telemetry:
resource: {} # attributs de ressource communs aux 3 signaux
logs: {} # journalisation du Collector
metrics: {} # métriques sur le Collector lui-même
traces: {} # traces internes (expérimental)
flowchart LR
C[OpenTelemetry Collector] --> T[service::telemetry]
T --> L[Logs<br/>stderr · fichier · OTLP]
T --> M[Métriques<br/>Prometheus :8888 · OTLP]
T --> Tr[Traces<br/>OTLP · expérimental]
Chaque signal peut rester local (stderr, endpoint Prometheus) ou être exporté vers un backend via OTLP. On peut même combiner les deux.
Les logs : du stderr lisible au push OTLP
Par défaut, le Collector écrit ses logs sur stderr, au format console
(lisible par un humain), au niveau info. Voici l’ensemble des options :
service:
telemetry:
logs:
level: info # debug | info | warn | error (défaut: info)
encoding: console # console (lisible) | json (machine)
development: false # mode dev de zap (stacktraces verbeuses)
disable_caller: false # n'annote plus chaque ligne avec fichier:ligne
disable_stacktrace: false # désactive la capture auto des stacktraces
output_paths: [stderr] # destinations des logs (stderr, stdout, /var/log/otelcol.log…)
error_output_paths: [stderr]# où zap écrit ses propres erreurs internes
initial_fields: # champs ajoutés à CHAQUE entrée de log
service: edge-collector
sampling: # limite le volume en cas de logs répétitifs
enabled: true
tick: 10s # fenêtre d'échantillonnage
initial: 10 # nb de logs identiques laissés passer par fenêtre
thereafter: 100 # ensuite, 1 sur N (thereafter: 0 = tout couper)
En production : passez en JSON
Pour une ingestion par une stack de logs (Loki, Elastic, un autre Collector…),
le format json est quasi obligatoire — il rend chaque champ structuré et
requêtable :
service:
telemetry:
logs:
level: info
encoding: json # permet de définit l'encodage en json
initial_fields:
cluster: prod-eu-west-1
Exporter les logs en OTLP
Au-delà de stdout/stderr, vous pouvez émettre les logs du Collector en
OTLP vers un backend, grâce à la sous-section processors (le même mécanisme
de log record processors que dans le SDK OpenTelemetry) :
service:
telemetry:
logs:
level: info
encoding: json # les logs locaux restent aussi sur stderr
processors:
- batch: # batch (recommandé) ou simple (sync, pour debug)
exporter:
otlp:
protocol: http/protobuf # ou grpc
endpoint: https://otlp.example.com:4318
headers:
- name: Authorization
value: "Bearer ${env:OTLP_TOKEN}"
Utilisez
consolecomme exporter deprocessorssi vous voulez voir les logs au format OTLP sur la sortie standard (utile en debug). Et préférezbatchàsimpleen production :simpleexporte de façon synchrone à chaque log et peut devenir un goulot d’étranglement.
Les métriques : Prometheus, OTLP, ou les deux
Le Collector expose par défaut ses métriques internes sur un endpoint
Prometheus : http://127.0.0.1:8888/metrics. Deux leviers principaux : le
niveau de détail (level) et les lecteurs (readers).
Le niveau de verbosité
service:
telemetry:
metrics:
level: normal # none | basic | normal | detailed
| Niveau | Ce qu’il produit |
|---|---|
none |
Aucune métrique interne (désactive complètement). |
basic |
Le strict essentiel : compteurs d’accept/refus, débits. |
normal |
Défaut. basic + tailles de file, batchs, etc. |
detailed |
Tout, y compris les métriques RPC/HTTP par appel — forte cardinalité, à réserver au diagnostic. |
Quelques métriques que vous surveillerez en priorité (préfixe otelcol_) :
otelcol_receiver_accepted_spans/otelcol_receiver_refused_spansotelcol_exporter_sent_spans/otelcol_exporter_send_failed_spansotelcol_exporter_queue_size/otelcol_exporter_queue_capacity(saturation !)otelcol_processor_batch_batch_send_sizeotelcol_process_uptime,otelcol_process_memory_rss,otelcol_process_runtime_heap_alloc_bytes
Ces métriques ne sont pas réservées aux composants natifs : vos propres
composants peuvent émettre les leurs au même endroit. C’est précisément le
rôle du TelemetryBuilder généré par mdatagen — vous déclarez vos compteurs
dans metadata.yaml, et ils ressortent ici, préfixés otelcol_, exactement
comme les métriques natives. Le mécanisme (section metadata.yaml + mdatagen)
est détaillé dans
Développer son propre receiver OpenTelemetry.
Option A — endpoint Prometheus (pull)
Pour qu’un Prometheus puisse scraper le Collector dans un cluster, il faut
souvent écouter sur 0.0.0.0 (le défaut 127.0.0.1 n’est joignable que
localement) :
service:
telemetry:
metrics:
level: normal
readers:
- pull:
exporter:
prometheus:
host: 0.0.0.0
port: 8888
without_type_suffix: true # supprime les suffixes _total, etc.
without_units: true # supprime les suffixes d'unité
Option B — push OTLP (periodic)
Pour pousser les métriques vers un backend OTLP à intervalle régulier :
service:
telemetry:
metrics:
level: normal
readers:
- periodic:
interval: 30s
exporter:
otlp:
protocol: grpc
endpoint: https://otlp.example.com:4317
Option C — les deux à la fois
readers est une liste : rien n’empêche d’exposer Prometheus et de
pousser en OTLP en parallèle.
service:
telemetry:
metrics:
level: detailed
readers:
- pull:
exporter:
prometheus: { host: 0.0.0.0, port: 8888 }
- periodic:
interval: 60s
exporter:
otlp: { protocol: http/protobuf, endpoint: https://otlp.example.com:4318 }
Vous pouvez aussi affiner les métriques produites avec des
views(renommage, agrégation, filtrage parinstrument_name) — utile pour maîtriser la cardinalité d’un niveaudetailed.
Les traces internes (expérimental)
Le Collector peut tracer son propre fonctionnement (le cheminement interne
d’un batch à travers les composants). Ces traces ne sont pas émises par
défaut : il faut déclarer des processors avec un exporter OTLP.
service:
telemetry:
traces:
processors:
- batch:
exporter:
otlp:
protocol: http/protobuf
endpoint: https://otlp.example.com:4318
# propagators: [tracecontext, b3] # propagateurs de contexte (optionnel)
⚠️ La télémétrie de traces interne est expérimentale : la documentation ne garantit ni la stabilité des spans ni leur compatibilité d’une version à l’autre. Pratique pour diagnostiquer un Collector, à manier avec prudence en production.
Les attributs de ressource
resource ajoute des attributs communs aux trois signaux — typiquement de
quoi identifier l’instance dans une flotte de Collectors :
service:
telemetry:
resource:
service.name: edge-collector
service.version: 1.4.2
deployment.environment: production
service.instance.id: null # mettre à null DÉSACTIVE l'attribut auto-généré
Le Collector renseigne automatiquement service.name, service.version et un
service.instance.id aléatoire ; vous pouvez les surcharger ou les neutraliser
en les fixant à null.
Pièges et bonnes pratiques
- Évitez la boucle de rétroaction. Si vous exportez la télémétrie interne en OTLP vers un pipeline du même Collector, le moindre incident s’auto- amplifie. Pointez vers un backend externe ou un Collector dédié au monitoring. Le plus simple et le plus robuste reste d’exposer l’endpoint Prometheus et de le faire scraper par un Prometheus local : le pull est découplé du Collector, donc une panne ne se propage pas — et vous gardez les métriques jusqu’à la dernière seconde avant le crash.
detailedcoûte cher. La forte cardinalité des métriques RPC/HTTP peut surcharger votre TSDB. Réservez ce niveau au diagnostic ponctuel, et taillez avec desviewssi besoin.- Attention au binding réseau. L’endpoint Prometheus écoute sur
127.0.0.1par défaut (choix de sécurité). En conteneur/K8s, passez à0.0.0.0pour le scrape — mais ne l’exposez pas publiquement. - Secrets via variables d’environnement. Utilisez
${env:VAR}pour les tokens et endpoints plutôt que de les écrire en clair dans la config. - JSON en prod, console en local.
encoding: consolepour lire en développement,encoding: jsondès que les logs sont collectés par une stack.
Côté composants, rappelez-vous que vos propres composants alimentent ces
mêmes métriques : un receiver maison déclare sa télémétrie via metadata.yaml
et mdatagen, et ses compteurs otelcol_* apparaissent ici aux côtés des
composants natifs (voir
Développer son propre receiver OpenTelemetry).
Et tout cela se déploie dans la distribution que vous assemblez avec
OCB.
Conclusion
La télémétrie interne du Collector n’est pas un détail : c’est ce qui transforme
une boîte noire au cœur de votre infrastructure en un composant observable et
diagnosticable. Quelques lignes sous service::telemetry suffisent pour
choisir où vont vos logs (stderr, fichier, OTLP), comment vos métriques sont
exposées (Prometheus, OTLP, les deux) et, au besoin, tracer le Collector
lui-même.
La règle d’or : traitez votre Collector comme n’importe quel service de production — il mérite ses propres dashboards et ses propres alertes.
Si vous souhaitez mettre en place le monitoring de votre plateforme d’observabilité ou auditer votre configuration du Collector, parlons-en.
Frequently asked questions
Où se configure la télémétrie interne de l'OpenTelemetry Collector ?
Tout se déclare sous service::telemetry, avec quatre sous-sections : resource (attributs communs), logs, metrics et traces. Chaque signal peut rester local (stderr, endpoint Prometheus) ou être exporté vers un backend en OTLP — et les deux peuvent se combiner.
Sur quel port le Collector expose-t-il ses métriques internes ?
Par défaut sur l’endpoint Prometheus http://127.0.0.1:8888/metrics. Pour qu’un Prometheus distant puisse le scraper dans un cluster, il faut écouter sur 0.0.0.0 via un reader de type pull (host: 0.0.0.0, port: 8888).
Vaut-il mieux exposer les métriques en Prometheus ou les pousser en OTLP ?
Les deux fonctionnent et sont combinables, car readers est une liste. Le plus robuste reste d’exposer l’endpoint Prometheus et de le faire scraper par un Prometheus local : le pull est découplé du Collector, donc une panne ne se propage pas. Pousser la télémétrie interne en OTLP vers un pipeline du même Collector risque une boucle de rétroaction qui auto-amplifie le moindre incident.
À quoi sert le niveau (`level`) des métriques internes du Collector ?
Il règle le détail des métriques : none, basic, normal (défaut) ou detailed. Le niveau detailed ajoute les métriques RPC/HTTP par appel, à très forte cardinalité — à réserver au diagnostic ponctuel, car il peut surcharger votre TSDB.