OpenTelemetry OpenTelemetry

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.

12 min Intermedio

“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_PROTOCOL debe coincidir con el puerto: grpc va al 4317, http/protobuf va 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_ENDPOINT es una URL base; el SDK añade /v1/traces. Las variables específicas de señal como OTEL_EXPORTER_OTLP_TRACES_ENDPOINT se usan tal cual, así que deben incluir la ruta completa.
  • localhost dentro de un contenedor. El localhost de 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. Busca OTEL_SDK_DISABLED=true u OTEL_TRACES_EXPORTER=none.
  • Sin service.name. Los datos se aceptan pero aparecen como unknown_service, lo que parece datos ausentes. Define OTEL_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. Define endpoint: 0.0.0.0:4317 explícitamente.
  • El Service de Kubernetes puede no exponer el puerto, o falta el containerPort del 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, no otlp).
  • El tipo de señal coincide: un pipeline traces no 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étricasSignificado
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 _capacityProfundidad 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 refused o deadline exceeded: endpoint o puerto incorrectos, o un bloqueo de red.
  • certificate signed by unknown authority: añade tls.ca_file, o corrige el endpoint para que use el nombre de host correcto.
  • 401 o 403: 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.
  • 415 o errores de análisis: discrepancia de protocolo, como otlp (gRPC) apuntando a un puerto HTTP.
  • 404 en 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íntomaPrimera comprobación
Nada en los logs del CollectorEndpoint, protocolo y puerto del SDK; localhost en contenedores
El Collector recibe datos, el backend noExporter en el pipeline; endpoint; autenticación; protocolo
El Collector no arrancaSalida de validate; componente ausente de la imagen
Los datos aparecen como unknown_serviceDefine OTEL_SERVICE_NAME
Crecimiento de memoria o reiniciosmemory_limiter primero, tamaños de cola, límites de recursos
Trazas parciales tras el muestreoUna traza debe llegar a un solo Collector (nivel de balanceo de carga)
Faltan datos de forma intermitenteCola 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