Dudas Comunes
Quiero hacer un paralelo aprovechando un poco más de OTel y aclarar algunas dudas.
Hablando de métricas, sin logs ni traces
Cuando tenemos un cluster kubernetes, un servidor e infraestructura de hardware en general es normal querer monitorizar y tener un panel bonito en Grafana para monitorizar la salud del cluster y de los servidores. Para esto usamos Node Exporter que es una herramienta más enfocada y específica, desarrollada especialmente para exportar métricas del sistema operativo Linux/Unix a Prometheus. Recolecta:
- Métricas del sistema: CPU, memoria, disco, red
- Métricas del kernel: interrupciones, contextos
- Métricas de hardware: temperatura, energía
- Otras métricas específicas del sistema operativo
Pero no es la herramienta indicada para monitorizar una aplicación.
¿Podríamos hacer esto con OpenTelemetry? Sí, pero Node Exporter es más recomendado para monitorización del cluster por algunas razones:
Eficiencia: Es más ligero y específico para esta función y fue optimizado para recolectar métricas del sistema con menor sobrecarga en los nodos.Simplicidad: Es más simple de configurar y mantener y no requiere instrumentación o código adicional.Integración: Es una herramienta con integración nativa con PrometheusCobertura de métricas: Node Exporter tiene métricas predefinidas que cubren prácticamente todo lo que necesitas monitorizar a nivel de sistema.
Lo ideal es usar ambos de forma complementaria:
Node Exporter: para métricas del cluster y de los servidores (CPU, memoria, disco, etc)
OpenTelemetry: Para métricas de las aplicaciones, traces y logs
Existe el OpenTelemetry Collector que puede recolectar métricas del sistema operativo usando el receptor "hostmetrics". Sin embargo, hay algunas consideraciones importantes:
-
El receptor
hostmetricsde OpenTelemetry recolecta métricas similares al Node Exporter (CPU, memoria, disco, red, etc), pero necesita ser configurado explícitamente.-
receivers:
hostmetrics:
collection_interval: 30s
scrapers:
cpu:
memory:
disk:
filesystem:
network:
load:
process:
-
Sin embargo, la mayoría de las personas aún prefieren Node Exporter aunque tengan un collector por nodo en el cluster porque:
- Es más maduro y probado en producción.
- Tiene una comunidad mayor y más dashboards listos en Grafana.
- Es más ligero y específico para esta función.
- Integra nativamente con el ecosistema Prometheus.
Si quieres experimentar, puedes usar el OpenTelemetry Collector con hostmetrics, pero ten en cuenta que:
- Tendrás que hacer más configuraciones.
- Puedes tener menos métricas disponibles comparado con Node Exporter.
- Encontrarás menos recursos y ejemplos en la comunidad.
Ahora hablando de aplicaciones y no del sistema operativo, OpenTelemetry también recolecta métricas, además de logs y traces.
El mismo Prometheus (que solo sirve para métricas) puede buscar tanto las métricas del Node Exporter como las de OpenTelemetry. Recordando que Prometheus es una base de datos de series temporales y no tiene nada que ver con logs y traces.
Prometheus:
- Prometheus hace SCRAPE (raspado) de las métricas a través de endpoints /metrics.
- Hace pull (extrae) las métricas, no recibe (push)
- Tanto Node Exporter como OpenTelemetry exponen endpoints que Prometheus raspea.
Node Exporter expone /metrics ←-- Prometheus hace scrape
↓
OpenTelemetry expone /metrics ←-- Prometheus hace scrape
OpenTelemetry encamina los diferentes tipos de datos (señales) a los lugares correctos.
El OpenTelemetry Collector es la pieza clave que maneja el enrutamiento de los datos:
Para métricas en Prometheus:
- El Collector expone un endpoint /metrics en formato Prometheus
- Prometheus hace scrape de este endpoint
- El Collector convierte los datos del formato OpenTelemetry al formato Prometheus.
Para logs en Loki por ejemplo:
- El Collector envía (push) activamente los logs a Loki
- Usa el protocolo de Loki para envío de logs
- Puede hacer transformaciones y filtros en los logs antes de enviar
Para traces en Jaeger o GrafanaTempo:
- El Collector envía (push) los traces vía gRPC o HTTP
- Soporta diferentes protocolos de traces (OTLP, Jaeger, Zipkin)
- Puede hacer muestreo y procesamiento de los traces
Ejemplo de configuración del Collector:
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
loki:
endpoint: "http://loki:3100/loki/api/v1/push"
jaeger:
endpoint: "jaeger:14250"
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheus]
logs:
receivers: [otlp]
processors: [batch]
exporters: [loki]
traces:
receivers: [otlp]
processors: [batch]
exporters: [jaeger]
Tu aplicación envía todos los datos (métricas, logs, traces) al Collector usando el protocolo OTLP, y el Collector se encarga de distribuir a los servicios correctos usando los protocolos apropiados.
Si estás usando el OpenTelemetry Exporter directamente en la aplicación sin el Collector, necesitas configurar cada exporter separadamente en tu aplicación:
Para métricas en Prometheus necesitas configurar el PrometheusExporter en la aplicación que va a exponer un endpoint /metrics para que Prometheus haga scrape.
Para logs en Loki necesitas configurar un LokiExporter que va a hacer push directo a Loki (Necesitas configurar la URL y autenticación de Loki)
Para traces en Jaeger tienes que configurar el JaegerExporter que envía traces directamente a Jaeger siendo necesario apuntar al endpoint de Jaeger.
Solo una ilustración aquí en Python de cómo sería una configuración rápida.
from opentelemetry.exporter.prometheus import PrometheusMetricReader
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.exporter.jaeger.thrift import JaegerExporter
from opentelemetry.sdk.trace import TracerProvider
# Configurando métricas para Prometheus
metric_reader = PrometheusMetricReader()
provider = MeterProvider(metric_readers=[metric_reader])
# Configurando traces para Jaeger
jaeger_exporter = JaegerExporter(
agent_host_name="localhost",
agent_port=6831,
)
trace_provider = TracerProvider()
trace_provider.add_span_processor(jaeger_exporter)
La principal desventaja de no usar el Collector es necesitar configurar cada exporter en la aplicación trayendo más complejidad en el código, menos flexibilidad de cambios en esos servicios y más conexiones directas entre las aplicaciones y los diferentes servicios de backend de esas otras herramientas.
Por eso el Collector es recomendado en ambientes de producción, pues centraliza esa complejidad.