El OpenTelemetry Collector es el componente sobre el que descansa todo tu pipeline de telemetría. Recibe trazas de tus aplicaciones, las procesa, las enruta y las envía a los backends. Es la pieza que conecta la instrumentación con la observabilidad. Y hay un 23% de equipos que lo tienen en producción sin monitorizarlo en absoluto.
El dato viene de la encuesta de usuarios del Collector publicada por OpenTelemetry en enero de 2026. Un equipo de cada cuatro despliega este componente central y luego no mira qué hace, si está sano, si está perdiendo datos o si lleva horas al borde del colapso. No es negligencia: es que nadie les explicó que el Collector expone su propia telemetría, que lo hace por defecto, y que basta con saber dónde mirar para tener visibilidad completa sobre él.
Esta es la paradoja del stack de observabilidad: el componente diseñado para que no pierdas visibilidad de nada es, con frecuencia, el único punto ciego del sistema.
Lo que el Collector ya está emitiendo, lo uses o no
Por defecto, sin tocar ninguna configuración, el Collector expone métricas internas en formato Prometheus en el puerto 8888. Solo con añadir ese endpoint al fichero de scrape de tu Prometheus (o de tu Grafana Alloy), empiezas a ver qué está pasando dentro.
yaml
# prometheus.yml
scrape_configs:
- job_name: 'otelcol'
static_configs:
- targets: ['otelcol-host:8888']
Lo que scrapes por defecto corresponde al nivel normal de verbosidad. El Collector tiene cuatro niveles: none (desactivado), basic (métricas esenciales del proceso), normal (el predeterminado, añade indicadores estándar del pipeline) y detailed (el más verboso, con dimensiones adicionales y vistas). Para la mayoría de los casos, normal es suficiente y razonable.
Si en cambio quieres que el Collector empuje sus métricas internas a un backend OTLP en lugar de exponerlas para scraping, la configuración es la siguiente:
yaml
service:
telemetry:
metrics:
level: normal
readers:
- periodic:
exporter:
otlp:
protocol: http/protobuf
endpoint: https://tu-backend:4318
Dos advertencias antes de continuar. Primera: el esquema de configuración de telemetría interna usa el formato declarativo del SDK de OpenTelemetry, que todavía está en desarrollo y puede tener cambios de ruptura en versiones futuras. La documentación oficial lo avisa explícitamente. Segunda: a partir de la versión v0.123.0, la opción service::telemetry::metrics::address quedó obsoleta y ya no funciona; la manera correcta de exponer el endpoint Prometheus es a través de readers, como en el ejemplo de arriba.
Además de métricas, el Collector escribe logs internos en stderr por defecto. Para activar trazas internas, hay que configurarlas explícitamente; no se emiten de serie porque es una funcionalidad experimental sin garantías de estabilidad en los nombres de spans ni atributos.
El vocabulario otelcol_*: qué métricas miran los que saben lo que buscan
Las métricas generadas por componentes del Collector llevan el prefijo otelcol_. Esto aplica desde la versión v0.106.1; en versiones anteriores el prefijo se aplicaba también a métricas de librerías de instrumentación subyacentes. Si trabajas con el exporter de Prometheus, los contadores llevan además el sufijo _total añadido automáticamente: otelcol_exporter_send_failed_spans_total en lugar de otelcol_exporter_send_failed_spans.
Las métricas que importan se agrupan en tres familias según dónde ocurre el problema.
En los receivers, lo que quieres saber es si estás rechazando datos entrantes. Hay dos métricas clave: otelcol_receiver_accepted_spans cuenta los spans que el Collector acepta sin problemas; otelcol_receiver_refused_spans cuenta los que rechaza. Si ves refused_spans subiendo, el Collector está recibiendo más de lo que puede procesar y está aplicando contrapresión hacia tus aplicaciones. En ese punto, o escalas el Collector o reduces el volumen de entrada.
En los processors, la señal más importante viene del memory_limiter. Este procesador limita cuánta memoria puede consumir el Collector; cuando se alcanza el límite, empieza a rechazar datos y lo registra en otelcol_processor_refused_spans. Ver esa métrica por encima de cero es una señal de que el Collector está al límite de memoria. No es un error silencioso: es un aviso de que estás perdiendo datos.
En los exporters es donde vive la información más crítica. Hay cuatro métricas que forman el cuadro completo:
otelcol_exporter_queue_size: cuántos elementos hay ahora mismo en la cola del exporterotelcol_exporter_queue_capacity: cuál es el tamaño máximo de esa colaotelcol_exporter_enqueue_failed_spans: elementos rechazados porque la cola estaba llena (pérdida de datos)otelcol_exporter_send_failed_spans: elementos que el exporter intentó enviar pero el backend rechazó o no respondió
La relación entre queue_size y queue_capacity es el termómetro más inmediato del estado del Collector. Una cola que oscila entre el 20% y el 50% de su capacidad es un sistema saludable con margen de maniobra. Una cola sostenidamente por encima del 80% es un sistema que va a perder datos en cuanto llegue un pico de tráfico o el backend tarde un poco más de lo habitual.
Tres patrones de fallo y cómo detectarlos antes de que importen
El Collector falla de tres maneras distintas, cada una con una firma de métricas diferente.
El backend desaparece. El backend de destino deja de responder: mantenimiento, caída, límite de tasa alcanzado. El Collector empieza a acumular datos en cola mientras reintenta. Verás otelcol_exporter_queue_size subir de forma sostenida y otelcol_exporter_send_failed_spans incrementarse. Si el backend tarda demasiado en volver, la cola llega a su capacidad máxima y empieza otelcol_exporter_enqueue_failed_spans: datos perdidos irrecuperablemente. La alerta que detiene el sangrado antes de llegar a ese punto:
yaml
- alert: ColectorColaAlta
expr: |
(otelcol_exporter_queue_size / otelcol_exporter_queue_capacity) > 0.80
for: 5m
labels:
severity: warning
annotations:
summary: "Cola del exporter al {{ $value | humanizePercentage }}"
description: "El Collector {{ $labels.pod }} acumula datos. Backend lento o caído."
El Collector se queda sin memoria. El volumen de datos supera lo que el Collector puede gestionar con la memoria asignada. El memory_limiter activa la contrapresión y empieza a rechazar datos en entrada. Verás otelcol_processor_refused_spans subir y, correlativamente, otelcol_receiver_refused_spans también, porque el processor devuelve la contrapresión al receiver. La alerta correspondiente:
yaml
- alert: ColectorRechazandoDatos
expr: |
rate(otelcol_processor_refused_spans_total[5m]) > 0
for: 2m
labels:
severity: critical
annotations:
summary: "El Collector está rechazando spans"
description: "Límite de memoria alcanzado. Se están perdiendo datos."
El Collector deja de enviar en silencio. Este es el más peligroso: el Collector sigue vivo, el proceso responde, pero otelcol_exporter_sent_spans cae a cero mientras no aparece ningún error obvio. Es un patrón documentado en el repositorio del proyecto, con instancias reportadas en producción: uno de varios pods de Collector se queda atascado, la cola llega a su límite sin que los logs muestren nada antes del error, y los datos desaparecen. La alerta que lo detecta antes de que sea un problema:
yaml
- alert: ColectorSinEnvíos
expr: |
rate(otelcol_exporter_sent_spans_total[10m]) == 0
and on(pod) rate(otelcol_receiver_accepted_spans_total[10m]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Collector recibiendo pero sin exportar"
description: "El pod {{ $labels.pod }} acepta datos pero no los envía al backend."
ZPages: el panel de control para cuando el backend está caído
Hay una extensión que viene en la distribución contrib del Collector y que merece atención particular: zpages. Expone un conjunto de endpoints HTTP con información en tiempo real sobre el estado del Collector, sin necesidad de ningún backend externo. Cuando tu backend de observabilidad está caído y necesitas saber qué está haciendo el Collector, zpages es todo lo que tienes.
yaml
extensions:
zpages:
endpoint: "localhost:55679"
service:
extensions: [zpages]
Los endpoints disponibles son /debug/servicez (estado general, versión, uptime), /debug/pipelinez (estado de cada pipeline: receivers, processors y exporters activos, si los datos están siendo mutados) y /debug/extensionz (extensiones activas). En producción, conviene exponerlo solo en localhost o protegerlo: muestra información interna que no debe ser pública. Combinado con health_check (en el puerto 13133) y pprof (para profiling en situaciones extremas), forma el conjunto básico de extensiones de diagnóstico que cualquier despliegue de producción debería tener configurado desde el primer día.
La trampa de los nombres: queries que funcionaban y dejan de funcionar
Si trabajas con el Collector desde hace tiempo, habrás notado inconsistencias en los nombres de las métricas entre versiones. Hay tres cambios de comportamiento que rompen queries sin avisar explícitamente.
El primero es el prefijo. Desde v0.106.1, solo los componentes del Collector usan el prefijo otelcol_. Las métricas de librerías de instrumentación subyacentes (Go runtime, por ejemplo) ya no lo llevan. Si tienes dashboards que filtraban por otelcol_* asumiendo que ese prefijo cubría todo, puede que estés perdiendo métricas de proceso.
El segundo es el sufijo _total. El exporter de Prometheus añade este sufijo a los contadores siguiendo convenciones de Prometheus. Si en algún momento configuras el reader manualmente, necesitas asegurarte de que el comportamiento coincide con lo que esperan tus dashboards. La misma métrica puede llamarse otelcol_exporter_sent_spans en OTLP y otelcol_exporter_sent_spans_total en el endpoint de Prometheus.
El tercero es la eliminación de service::telemetry::metrics::address en v0.123.0. Si tienes configuraciones antiguas que usaban ese campo para exponer el endpoint en una interfaz específica, simplemente se ignora sin error en versiones recientes. El resultado es que el endpoint queda expuesto solo en localhost, lo cual puede provocar que tu Prometheus no llegue a scrapearlo.
Autotelemetría: el Collector observándose a sí mismo a través de sus propios pipelines
Hay una configuración que cierra el círculo completamente: hacer que el Collector envíe sus propias métricas internas a través de uno de sus propios pipelines OTLP. Técnicamente funciona: configuras el exporter OTLP interno para que apunte al receiver OTLP del mismo Collector, y los datos pasan por el pipeline configurado como cualquier otra señal. Es útil cuando quieres que las métricas del Collector pasen por el mismo procesamiento (enriquecimiento de atributos, filtrado) que el resto de tu telemetría.
La documentación oficial lo menciona explícitamente como opción válida. El único riesgo es de configuración circular: si el pipeline que procesa las métricas internas falla, pierdes también las métricas que te avisarían de ese fallo. En la práctica, se recomienda mantener un endpoint de Prometheus externo como backup, independientemente de si también se empuja a un backend OTLP.
Lo que deberías tener configurado desde el primer día
Resumiendo lo anterior en términos operacionales: si despliegas el Collector en producción, hay un conjunto mínimo que debería estar siempre presente.
El endpoint Prometheus en el puerto 8888 expuesto al scraping, con nivel normal. Las tres alertas descritas arriba: cola por encima del 80%, datos rechazados por el procesador, y el patrón de Collector silencioso. La extensión zpages en localhost:55679 para diagnóstico manual. Y health_check como endpoint para los probes de Kubernetes; sin él, un Collector en estado zombie puede permanecer en el cluster recibiendo tráfico aunque no esté procesando nada.
El resto, como trazas internas (experimentales) o niveles de verbosidad detailed, son herramientas para investigar problemas específicos, no para el estado base de producción.
El Collector es observable. Lo ha sido desde el principio. El 23% de equipos que no lo monitoriza no está tomando una decisión técnica: está dejando un punto ciego en el único componente cuya caída apaga todo lo demás.
Para seguir aprendiendo
Internal telemetry — Documentación oficial de OpenTelemetry Collector — Referencia completa sobre configuración de telemetría interna, niveles de verbosidad, lista de métricas por nivel y opciones de exportación.
Scaling the Collector — Documentación oficial de OpenTelemetry — Explica en detalle cómo usar las métricas internas para decidir cuándo y cómo escalar, con atención especial al memory_limiter y sus métricas de rechazo.
OpenTelemetry Collector Follow-up Survey 2025 — El análisis del estado real de adopción del Collector en producción, con datos sobre patrones de monitorización, componentes más usados y evolución respecto a 2024.
Observability Engineering de Charity Majors, Liz Fong-Jones y George Miranda (O’Reilly) — Para entender el marco conceptual en el que encaja la observabilidad del propio pipeline de telemetría, más allá de las métricas concretas.