Soluciona problemas del Collector y los SDK
Una lista de comprobación sistemática para cuando la telemetría no llega: exporter debug, health checks, métricas internas y errores comunes.
“No veo mis datos” es el problema más común de OpenTelemetry, y la causa casi siempre es una de una breve lista de errores de configuración. Trabaja desde la aplicación hacia fuera, un salto cada vez, y demuestra cada salto antes de pasar al siguiente.
SDK de la app ──▶ Receiver del Collector ──▶ processors ──▶ exporter ──▶ Backend
1 2 3 4 5
Paso 0: valida la configuración
otelcol-contrib validate --config=config.yaml
Esto detecta errores de YAML, nombres de componentes desconocidos, nombres de opciones incorrectos y pipelines que referencian componentes no definidos. Usa el nombre de binario que coincida con tu distribución (otelcol, otelcol-contrib, otelcol-k8s). En un contenedor, ejecútalo con la misma imagen y la misma configuración montada que tu despliegue.
Paso 1: ¿está enviando el SDK?
Habilita el diagnóstico del SDK y un exporter de consola para separar “la aplicación no produjo nada” de “la aplicación lo produjo pero no llegó”:
export OTEL_LOG_LEVEL=debug
export OTEL_TRACES_EXPORTER=console # o "logging", según el lenguaje
Comprueba las causas habituales:
- El endpoint y el protocolo no coinciden.
OTEL_EXPORTER_OTLP_PROTOCOLdebe coincidir con el puerto:grpcva al 4317,http/protobufva al 4318. Enviar HTTP al puerto gRPC, o al revés, falla con errores que parecen problemas de conexión o de análisis. - Ruta incorrecta con HTTP.
OTEL_EXPORTER_OTLP_ENDPOINTes una URL base; el SDK añade/v1/traces. Las variables específicas de señal comoOTEL_EXPORTER_OTLP_TRACES_ENDPOINTse usan tal cual, así que deben incluir la ruta completa. localhostdentro de un contenedor. Ellocalhostde la aplicación es la propia aplicación. Usa el Service o el nombre de contenedor del Collector.- El SDK está desactivado o el exporter es
none. BuscaOTEL_SDK_DISABLED=trueuOTEL_TRACES_EXPORTER=none. - Sin
service.name. Los datos se aceptan pero aparecen comounknown_service, lo que parece datos ausentes. DefineOTEL_SERVICE_NAME. - Los procesos de corta duración terminan antes de la exportación. Los exporters por lotes envían periódicamente, así que llama al shutdown o flush del SDK antes de salir.
Paso 2: ¿es accesible el receiver?
curl -i http://collector:4318/v1/traces \
-H 'Content-Type: application/json' -d '{}'
Una respuesta HTTP 200 (un cuerpo JSON vacío está bien) muestra que el receiver HTTP es accesible. Para gRPC, una herramienta como grpcurl o una comprobación TCP (nc -zv collector 4317) demuestra que el puerto está abierto. Si no lo está:
- El receiver puede estar enlazado a
localhost. Defineendpoint: 0.0.0.0:4317explícitamente. - El Service de Kubernetes puede no exponer el puerto, o falta el
containerPortdel pod. - Una NetworkPolicy, un firewall o un service mesh pueden bloquear el tráfico.
Paso 3: ¿está conectado el pipeline?
Este es el error más común del Collector: un componente definido pero no usado. Definir exporters.otlp/tempo no hace nada hasta que aparece en service.pipelines.<señal>.exporters. Lo mismo ocurre con receivers, processors, extensions y connectors.
Comprueba:
- El nombre del componente en el pipeline coincide exactamente con su definición, incluido cualquier sufijo (
otlp/tempo, nootlp). - El tipo de señal coincide: un pipeline
tracesno puede usar un receiver o exporter que no soporte trazas. - La extensión está listada bajo
service.extensions. - En los valores de Helm, recuerda que las listas se reemplazan, así que un pipeline que redefiniste parcialmente puede haber perdido los componentes predeterminados.
Paso 4: ve los datos dentro del Collector
Añade el exporter debug al pipeline:
exporters:
debug:
verbosity: detailed
service:
pipelines:
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [debug, otlp/tempo]
Lee los logs del Collector. Ver spans allí demuestra que los receivers y processors funcionan, así que el problema está más adelante. No ver nada significa que los datos nunca llegaron al pipeline o que un processor los descartó (un processor filter o el tail sampler son los sospechosos habituales). Elimina debug o reduce su verbosidad al terminar, porque registra cada elemento.
Paso 5: usa las propias señales del Collector
Health check:
extensions:
health_check:
endpoint: 0.0.0.0:13133
service:
extensions: [health_check]
curl http://collector:13133/ devuelve un estado. Úsalo para las probes de liveness y readiness de Kubernetes.
Las métricas internas se sirven en el puerto 8888 por defecto (consulta service.telemetry.metrics para tu versión):
curl -s http://collector:8888/metrics | grep -E 'otelcol_(receiver|processor|exporter)_'
Léelas como un embudo:
| Familia de métricas | Significado |
|---|---|
otelcol_receiver_accepted_* | Elementos recibidos con éxito |
otelcol_receiver_refused_* | Rechazados, a menudo por memory_limiter |
otelcol_processor_dropped_* | Descartados por un processor |
otelcol_exporter_sent_* | Entregados al backend |
otelcol_exporter_send_failed_* | El backend los rechazó o es inaccesible |
otelcol_exporter_queue_size y _capacity | Profundidad de la cola frente a su límite |
Los recuentos de aceptados subiendo con los de enviados planos te dicen que el problema está en el exporter. Los recuentos de rechazados apuntan a los límites de memoria. Los nombres de las métricas se han ajustado entre releases, así que consulta la documentación de telemetría interna del Collector para la tuya.
zPages da una vista en vivo de los pipelines y las trazas recientes:
extensions:
zpages:
endpoint: localhost:55679
Navega a /debug/tracez y /debug/pipelinez (mediante kubectl port-forward en un clúster). Mantenlo enlazado a localhost.
Paso 6: ¿acepta el backend los datos?
Mira los errores del exporter en los logs del Collector:
connection refusedodeadline exceeded: endpoint o puerto incorrectos, o un bloqueo de red.certificate signed by unknown authority: añadetls.ca_file, o corrige el endpoint para que use el nombre de host correcto.401o403: falta el token o el encabezado, o es incorrecto. Confirma que la variable de entorno está definida en el pod (kubectl exec ... -- env), porque un${env:VAR}sin definir se convierte en un valor vacío.415o errores de análisis: discrepancia de protocolo, comootlp(gRPC) apuntando a un puerto HTTP.404en HTTP: comprueba la ruta base que espera el backend (Loki usa/otlp, Prometheus/api/v1/otlp).- Prometheus rechaza OTLP: su feature flag de receiver OTLP no está habilitado.
Comprobaciones de auto-instrumentación
Para la inyección basada en el Operator, confirma que el Instrumentation existía antes de que arrancara el pod, que la anotación está en la plantilla del pod y que el pod de la aplicación tiene el init container opentelemetry-auto-instrumentation. Reinicia la carga de trabajo tras crear o cambiar el recurso. Para las configuraciones basadas en agente, confirma que el flag del agente o la variable de entorno realmente se aplica (-javaagent:, opentelemetry-instrument, --require).
Referencia rápida
| Síntoma | Primera comprobación |
|---|---|
| Nada en los logs del Collector | Endpoint, protocolo y puerto del SDK; localhost en contenedores |
| El Collector recibe datos, el backend no | Exporter en el pipeline; endpoint; autenticación; protocolo |
| El Collector no arranca | Salida de validate; componente ausente de la imagen |
Los datos aparecen como unknown_service | Define OTEL_SERVICE_NAME |
| Crecimiento de memoria o reinicios | memory_limiter primero, tamaños de cola, límites de recursos |
| Trazas parciales tras el muestreo | Una traza debe llegar a un solo Collector (nivel de balanceo de carga) |
| Faltan datos de forma intermitente | Cola llena o límite de reintentos alcanzado; revisa las métricas de send_failed y de cola |
Arregla un salto cada vez, ten a mano el exporter debug mientras trabajas y pon las métricas internas del Collector en un dashboard para que el próximo incidente empiece con evidencia.
Guías populares
-
OpenTelemetry explicado: SDK, OTLP y el Collector Entiende las piezas móviles y los tres lugares donde vive la configuración antes de escribir nada de YAML. -
El modelo de configuración del Collector: componentes, pipelines y providers Aprende las reglas del YAML del Collector: nombres, pipelines, connectors, fusión de archivos y variables de entorno. -
Configura los SDK con variables de entorno OTEL_* Define el nombre del servicio, los exporters, el muestreo y los límites para cualquier lenguaje usando variables estándar. -
Instrumenta aplicaciones sin cambios de código: Java, Python y Node.js Adjunta agentes de OpenTelemetry solo con variables de entorno y flags de línea de comandos. -
Prepara el Collector para producción: límites de memoria, batching y reintentos Configura processors, colas y almacenamiento persistente para que la telemetría sobreviva a sobrecargas e interrupciones. -
Despliega el Collector en Kubernetes con Helm Instala el chart oficial, usa presets para logs y métricas y sobrescribe la configuración mediante archivos de valores.