Cuando una API presenta latencias variables o errores intermitentes y no existen métricas, logs correlacionados ni trazas distribuidas, encontrar el origen del problema puede llevar mucho tiempo.

OpenTelemetry Collector funciona como una capa intermedia: recibe telemetría desde las aplicaciones, la procesa y la envía hacia uno o varios backends. Así, la instrumentación no queda acoplada directamente a un proveedor.

Sin embargo, es importante separar las señales:

  • Prometheus almacena métricas.
  • Las trazas requieren un backend de trazas.
  • Los logs requieren un backend de logs.
  • Grafana consulta estos backends mediante fuentes de datos.

La implementación principal de esta guía cubre el pipeline de métricas:

API → OTLP → OpenTelemetry Collector → Prometheus → Grafana → Alertas

Recibir OTLP en el Collector no implica que todas las señales queden almacenadas. Cada señal necesita un pipeline y un exporter compatibles.

¿Cuándo conviene implementarlo?

Esta arquitectura resulta útil cuando:

  • La API presenta picos de latencia o carga.
  • Se necesita medir solicitudes, errores y tiempos de respuesta.
  • Varios servicios deben utilizar una recolección estandarizada.
  • El entorno ya utiliza Prometheus y Grafana.
  • Se busca portabilidad entre proveedores de observabilidad.
  • Se necesita procesar, filtrar o enriquecer telemetría antes de almacenarla.

Arquitectura de referencia

El Collector separa recepción, procesamiento y exportación:

  1. La API genera métricas mediante el SDK de OpenTelemetry.
  2. El SDK envía OTLP/HTTP o OTLP/gRPC al Collector.
  3. El Collector limita memoria y agrupa los datos.
  4. El exporter Prometheus expone /metrics.
  5. Prometheus consulta ese endpoint periódicamente.
  6. Grafana consulta Prometheus y evalúa paneles o alertas.
Ver la Imagen 1: arquitectura diferenciada para métricas, trazas y logs.

Alcance de la implementación

La configuración principal habilitará únicamente métricas. Para evitar envíos sin destino, la aplicación no debería exportar trazas o logs hasta que existan pipelines y backends para esas señales.

Una arquitectura completa podría añadir:

  • Trazas → backend compatible con OTLP, como Tempo o Jaeger.
  • Logs → backend de logs, como Loki u otra plataforma.
  • Correlación → inclusión de trace_id y span_id en los logs.

Prometheus no debe configurarse como destino de trazas ni logs.

Requisitos previos

Antes de comenzar, verifica que dispones de:

  • Una API instrumentada con un SDK de OpenTelemetry.
  • Una distribución del Collector que incluya receiver OTLP, procesadores y exporter Prometheus.
  • OpenTelemetry Collector ejecutándose como binario o contenedor.
  • Prometheus.
  • Grafana.
  • Conectividad privada entre los componentes.
  • Límites de memoria definidos para el Collector en producción.

Los nombres exactos de componentes disponibles dependen de la distribución. Puedes consultarlos con:

otelcol components

Si utilizas la distribución contrib:

otelcol-contrib components

Paso 1. Configurar la aplicación

Para enviar métricas mediante OTLP/HTTP con Protobuf:

export OTEL_SERVICE_NAME=api-pagos
export OTEL_RESOURCE_ATTRIBUTES="deployment.environment.name=production,service.version=1.0.0"

export OTEL_METRICS_EXPORTER=otlp
export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318

export OTEL_TRACES_EXPORTER=none
export OTEL_LOGS_EXPORTER=none

El soporte exacto de estas variables debe verificarse para el lenguaje y SDK utilizados.

Al definir el endpoint OTLP general con HTTP, el SDK construye las rutas específicas, como /v1/metrics. El protocolo debe declararse porque su valor predeterminado puede variar entre SDK y versiones. Configuración oficial del exporter OTLP.

El hostname también depende del entorno:

  • Docker Compose: nombre del servicio, por ejemplo otel-collector.
  • Aplicación y Collector en el mismo host: normalmente localhost.
  • Kubernetes: nombre DNS del Service.
  • Máquinas diferentes: nombre privado o dirección accesible con TLS.

No utilices otel-collector como hostname si ese nombre no puede resolverse desde la aplicación.

Paso 2. Configurar el receiver OTLP

Crea otel-collector.yaml:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

Los endpoints se declaran explícitamente porque el Collector utiliza configuraciones restrictivas por defecto. Dentro de un contenedor, escuchar únicamente en localhost impediría que otros contenedores se conectaran.

Usar 0.0.0.0 no significa que los puertos deban publicarse en Internet. Limita su exposición mediante redes privadas, firewall o políticas de red.

Paso 3. Proteger la memoria y agrupar datos

Añade:

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 400
    spike_limit_mib: 100

  batch:
    timeout: 5s
    send_batch_size: 1024
    send_batch_max_size: 2048

memory_limiter reduce el riesgo de que el Collector agote la memoria disponible. Debe aparecer antes que otros procesadores en el pipeline.

Los valores del ejemplo suponen que el contenedor dispone de más de 400 MiB. Ajusta los límites de acuerdo con la memoria asignada, el volumen de telemetría y las pruebas de carga.

batch agrupa datos para reducir operaciones pequeñas. send_batch_size actúa como disparador y send_batch_max_size limita el tamaño máximo de cada lote.

Paso 4. Exponer las métricas para Prometheus

Añade el exporter:

exporters:
  prometheus:
    endpoint: 0.0.0.0:9464

El exporter publica las métricas en:

http://otel-collector:9464/metrics

Por defecto, los atributos de recurso no se copian todos como etiquetas en cada métrica. Se exponen mediante información del target. Es posible activar resource_to_telemetry_conversion, pero debe hacerse después de auditar la cardinalidad, porque convertir todos los atributos puede multiplicar las series.

El exporter normaliza nombres y atributos para adaptarlos al modelo de Prometheus; por ello, el nombre final de una métrica puede diferir del nombre OTLP original. Referencia oficial del Prometheus exporter.

Paso 5. Crear el pipeline de métricas

Completa la configuración:

receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
      http:
        endpoint: 0.0.0.0:4318

processors:
  memory_limiter:
    check_interval: 1s
    limit_mib: 400
    spike_limit_mib: 100

  batch:
    timeout: 5s
    send_batch_size: 1024
    send_batch_max_size: 2048

exporters:
  prometheus:
    endpoint: 0.0.0.0:9464

service:
  pipelines:
    metrics:
      receivers:
        - otlp
      processors:
        - memory_limiter
        - batch
      exporters:
        - prometheus

Definir un receiver o exporter no lo habilita automáticamente. Todos los componentes deben incluirse en service.pipelines. Documentación oficial del Collector.

Ver la Imagen 2: pipeline de métricas y puntos de validación.

Paso 6. Validar antes de iniciar el Collector

Utiliza el binario correspondiente a tu distribución:

otelcol validate --config=otel-collector.yaml

O bien:

otelcol-contrib validate --config=otel-collector.yaml

La validación detecta errores de sintaxis, componentes ausentes y referencias a pipelines inexistentes.

Después inicia el Collector:

otelcol --config=otel-collector.yaml

No reemplaces una instancia de producción hasta que la configuración haya pasado la validación y una prueba en staging.

Paso 7. Generar tráfico y comprobar el exporter

Realiza algunas solicitudes contra la API para que el SDK genere métricas. Luego consulta el endpoint desde una ubicación con acceso a la red del Collector:

curl -fsS http://otel-collector:9464/metrics | head

Si el puerto está publicado en el host:

curl -fsS http://localhost:9464/metrics | head

Una respuesta HTTP correcta confirma que el exporter está escuchando, pero no que la API esté enviando telemetría útil. Busca métricas de la aplicación y revisa sus etiquetas.

Paso 8. Configurar Prometheus

Añade un trabajo de scraping a prometheus.yml:

scrape_configs:
  - job_name: otel-api
    scrape_interval: 15s
    static_configs:
      - targets:
          - otel-collector:9464

El hostname debe resolverse desde Prometheus. Si Prometheus se ejecuta en otro contenedor, ambos servicios deben compartir una red.

Valida la configuración:

promtool check config prometheus.yml

Aplica la recarga mediante el mecanismo soportado por tu despliegue. No reinicies Prometheus con un archivo que no haya pasado promtool.

En la interfaz de Prometheus, abre Status → Targets y verifica:

otel-api    UP

También puedes ejecutar:

up{job="otel-api"}

El resultado 1 significa que Prometheus puede consultar el exporter. No significa que la API esté saludable ni que todas las métricas estén presentes.

Paso 9. Configurar Grafana

En Grafana:

  1. Abre Connections → Data sources.
  2. Añade una fuente de datos Prometheus.
  3. Configura la URL accesible desde Grafana.
  4. Ejecuta Save & test.
  5. Utiliza Explore para inspeccionar métricas antes de crear paneles.

Grafana incluye soporte integrado para Prometheus y utiliza PromQL para consultar sus series. Documentación oficial de la fuente de datos.

Paso 10. Diseñar el dashboard

Para una API, comienza por las señales RED:

  • Rate: solicitudes por segundo.
  • Errors: proporción de solicitudes fallidas.
  • Duration: percentiles de latencia.

Añade saturación solo si la aplicación o su runtime exponen métricas relacionadas, por ejemplo:

  • Uso del pool de conexiones.
  • Cantidad de workers ocupados.
  • Profundidad de colas.
  • Pausas del recolector de memoria.
  • Tiempo de espera hacia dependencias.

No asumas nombres de métricas. Inspecciona primero /metrics o Grafana Explore, porque la instrumentación y la traducción a Prometheus pueden cambiar sus nombres.

Patrones habituales de PromQL:

sum(rate(<contador_de_solicitudes>[$__rate_interval]))
sum(rate(<contador_de_errores>[$__rate_interval]))
/
sum(rate(<contador_de_solicitudes>[$__rate_interval]))
histogram_quantile(
  0.95,
  sum by (le) (
    rate(<histograma_de_latencia>_bucket[$__rate_interval])
  )
)

Sustituye los marcadores por las métricas reales. El cálculo de percentiles requiere una métrica de histograma con buckets adecuados.

Paso 11. Crear alertas útiles

Prioriza alertas basadas en síntomas:

  • El target de Prometheus permanece down.
  • La tasa de errores supera el umbral acordado.
  • La latencia p95 o p99 excede el objetivo.
  • La API deja de producir solicitudes o métricas.
  • Se agota un pool o crece una cola.
  • El Collector descarta datos o reinicia por memoria.

Las alertas pueden administrarse en Grafana o definirse como reglas de Prometheus y enviarse mediante Alertmanager. Son flujos diferentes y deben documentarse claramente. Documentación de alertas con Prometheus y Grafana.

Incluye un período de espera para evitar alertas por picos aislados, pero no lo utilices para ocultar incidentes persistentes.

Validación de extremo a extremo

Comprueba el pipeline en este orden:

  1. La API tiene la instrumentación activa.
  2. El protocolo y el endpoint OTLP coinciden.
  3. El Collector inicia sin errores.
  4. /metrics contiene series de la aplicación.
  5. El target aparece UP en Prometheus.
  6. Una consulta PromQL devuelve datos.
  7. Grafana obtiene resultados.
  8. Una alerta de prueba cambia de estado correctamente.

Esta secuencia permite localizar el salto donde deja de circular la telemetría.

Diagnóstico temporal con debug exporter

Si el Collector no parece recibir datos, puede añadirse temporalmente:

exporters:
  debug:
    verbosity: basic

Y habilitarlo junto con Prometheus:

service:
  pipelines:
    metrics:
      receivers: [otlp]
      processors: [memory_limiter, batch]
      exporters: [prometheus, debug]

El exporter debug permite confirmar que el Collector recibe y procesa telemetría. Retíralo después del diagnóstico: puede generar muchos logs y revelar atributos que no deberían conservarse. Guía oficial de diagnóstico.

Incorporar trazas y logs

Para capturar trazas se necesita:

  • Instrumentación de trazas en la API.
  • Un pipeline traces en el Collector.
  • Un exporter hacia un backend de trazas.
  • Una fuente de datos compatible en Grafana.

Para logs se necesita:

  • Emisión OTLP o un receiver compatible.
  • Un pipeline logs.
  • Procesamiento y redacción de información sensible.
  • Un backend de logs.
  • Una fuente de datos en Grafana.

No habilites OTEL_TRACES_EXPORTER=otlp o OTEL_LOGS_EXPORTER=otlp sin comprobar que existen esos pipelines y destinos.

Cardinalidad y costos

Evita atributos métricos que cambien para cada solicitud:

  • user_id
  • request_id
  • trace_id
  • session_id
  • URL completa con identificadores
  • mensajes de error completos
  • valores arbitrarios enviados por el usuario

Utiliza rutas normalizadas como /pagos/{id} en lugar de /pagos/984731. Cada combinación única de etiquetas crea una serie diferente en Prometheus; una cardinalidad elevada aumenta memoria, almacenamiento y costo de consultas.

Los identificadores únicos sí pueden ser útiles en trazas o logs controlados, pero no como etiquetas de métricas.

Consideraciones de seguridad

  • Mantén 4317, 4318 y 9464 en redes privadas.
  • Utiliza TLS o mTLS cuando la telemetría atraviese redes no confiables.
  • No almacenes tokens o contraseñas directamente en el YAML.
  • Restringe el endpoint /metrics a Prometheus.
  • Evita datos personales, credenciales y cuerpos de solicitudes.
  • Aplica redacción antes de exportar información sensible.
  • Protege Grafana y Prometheus con autenticación y controles de red.
  • Define la retención en los backends, no en el Collector.
  • Supervisa consumo de memoria, rechazos y reinicios del Collector.
  • Limita quién puede modificar dashboards, reglas y fuentes de datos.

Problemas frecuentes

El Collector no inicia

Ejecuta validate, comprueba la distribución utilizada y confirma que incluya todos los componentes declarados.

La aplicación no puede conectarse a OTLP

Revisa:

  • Resolución del hostname.
  • Protocolo configurado.
  • Puerto 4317 para gRPC o 4318 para HTTP.
  • Endpoints de escucha.
  • Firewall y redes de contenedores.
  • Configuración TLS.

/metrics responde, pero no contiene métricas de la API

Genera tráfico, revisa el exporter configurado en el SDK y confirma que OTEL_METRICS_EXPORTER=otlp. Activa temporalmente debug para comprobar la recepción.

Prometheus muestra el target como DOWN

Prometheus no puede alcanzar otel-collector:9464. Comprueba el hostname desde su propio entorno, el puerto, la red y los logs del scrape.

Las métricas no tienen el nombre esperado

El exporter normaliza nombres y puede añadir sufijos de tipo o unidad. Diseña las consultas con los nombres realmente expuestos, no solo con los nombres OTLP.

El Collector consume demasiada memoria

Revisa:

  • Límites del contenedor.
  • Configuración de memory_limiter.
  • Cardinalidad.
  • Volumen de entrada.
  • Tamaño de los lotes.
  • Velocidad de los destinos.
  • Reinicios y datos descartados.

Buenas prácticas para producción

  • Fija y documenta la versión del Collector.
  • Valida el YAML antes de cada despliegue.
  • Mantén memory_limiter antes de batch.
  • Separa configuraciones por ambiente.
  • Usa nombres de servicio consistentes.
  • Versiona Collector, Prometheus, dashboards y alertas.
  • Prueba los cambios con carga representativa.
  • Supervisa el propio Collector.
  • Define SLO antes de establecer umbrales.
  • Audita periódicamente cardinalidad y retención.
  • Añade trazas y logs únicamente con pipelines y backends definidos.

Conclusión

OpenTelemetry Collector desacopla la instrumentación de la plataforma de almacenamiento y permite procesar la telemetría de forma centralizada. En esta arquitectura, la API envía métricas por OTLP, el Collector las expone, Prometheus las almacena y Grafana las consulta.

El procedimiento recomendado es instrumentar → validar el Collector → comprobar /metrics → verificar el scrape → consultar en Grafana → probar alertas. Trazas y logs deben incorporarse como pipelines independientes, con backends diseñados para cada señal.

Diagrama de Opentelemetry

Cloud Serversby Donweb

Todo el poder de la nube a tus proyectos y aplicaciones.
Alojamiento ultra rápido, escalable y con alta disponibilidad.

  • Performance que te sorprenderá
  • Rápida escalabilidad y sin limitaciones
  • Arquitectura de alta disponibilidad
  • Soporte experto y ejecutivos de cuenta
  • Pagos en tu moneda y facturación local

Descubre la mejor solución de Cloud Hosting