Aprende observabilidad con un ejemplo práctico paso a paso
¿Qué es OpenTelemetry?
OpenTelemetry es un estándar open-source para instrumentar aplicaciones y recopilar telemetría (traces, métricas y logs). En lugar de estar atado a un proveedor específico de observabilidad, OpenTelemetry te permite generar datos de telemetría de forma neutral y enviarlos a múltiples backends como Jaeger, Grafana, Datadog, New Relic, etc.
En este mini-tutorial verás cómo instrumentar una aplicación Flask para generar traces distribuidos que puedes visualizar en Jaeger, todo corriendo en una VM Ubuntu Server con VirtualBox.
¿Qué necesitas?
- VirtualBox con Ubuntu Server instalado
- Configuración de red en NAT con port forwarding
- Docker y Python 3 instalados en la VM
- Conexión SSH desde tu máquina host
Port Forwarding en VirtualBox
Configura el reenvío de puertos en VirtualBox (Configuración → Red → Avanzadas → Reenvío de puertos):
- Puerto 2222 → 22 (SSH)
- Puerto 5000 → 5000 (Flask)
- Puerto 16686 → 16686 (Jaeger UI)
Paso 1: Preparar el entorno
Conéctate por SSH a tu VM Ubuntu y prepara el sistema:
ssh usuario@localhost -p 2222
Instala Docker, Docker Compose y Python:
sudo apt update && sudo apt upgrade -y
sudo apt install -y docker.io docker-compose
sudo usermod -aG docker $USER
sudo apt install -y python3 python3-pip python3-venv
Importante: Sal de la sesión SSH y vuelve a entrar para que los cambios del grupo docker se apliquen.
Paso 2: Crear estructura del proyecto
mkdir ~/opentelemetry-tutorial
cd ~/opentelemetry-tutorial
python3 -m venv venv
source venv/bin/activate
Paso 3: Archivos del proyecto
Puedes descargar todos los archivos desde GitHub:
O créalos manualmente siguiendo las siguientes secciones.
docker-compose.yml
Este archivo levanta Jaeger con soporte para OTLP:
version: '3'
services:
jaeger:
image: jaegertracing/all-in-one:latest
container_name: jaeger
ports:
- "16686:16686" # Jaeger UI
- "4318:4318" # OTLP HTTP receiver
environment:
- COLLECTOR_OTLP_ENABLED=true
restart: unless-stopped
requirements.txt
Flask==3.0.0
opentelemetry-api==1.21.0
opentelemetry-sdk==1.21.0
opentelemetry-instrumentation-flask==0.42b0
opentelemetry-exporter-otlp==1.21.0
app.py – Aplicación instrumentada
Este archivo contiene una aplicación Flask completamente instrumentada con OpenTelemetry.
Conceptos clave:
- TracerProvider: Es el punto de entrada para crear traces. Define el servicio y su configuración.
- OTLPSpanExporter: Envía los traces a Jaeger usando el protocolo OTLP (OpenTelemetry Protocol).
- FlaskInstrumentor: Instrumenta automáticamente Flask para capturar todas las peticiones HTTP como traces.
- Spans manuales: Usando
tracer.start_as_current_span()puedes crear spans personalizados para trackear partes específicas de tu lógica de negocio.
Endpoints de demostración:
/– Endpoint simple para verificar que funciona/lento– Simula una operación lenta (2-3 segundos)/rapido– Operación rápida para comparar tiempos/cadena– Múltiples operaciones en secuencia/manual– Ejemplo de instrumentación manual con spans personalizados/error– Simula un error para ver cómo se visualiza en Jaeger
El código completo está disponible en el repositorio GitHub.
Paso 4: Instalar dependencias
cd ~/opentelemetry-tutorial
source venv/bin/activate
pip install -r requirements.txt
Paso 5: Levantar Jaeger
docker-compose up -d
docker ps
Verifica que Jaeger está corriendo abriendo en tu navegador:
http://localhost:16686
Deberías ver la interfaz de Jaeger (todavía sin traces).

Paso 6: Ejecutar la aplicación
python app.py
La aplicación quedará corriendo y escuchando en el puerto 5000.
Paso 7: Generar traces
Desde otra terminal (PowerShell o CMD en Windows), ejecuta peticiones:
curl http://localhost:5000/
curl http://localhost:5000/lento
curl http://localhost:5000/rapido
curl http://localhost:5000/cadena
curl http://localhost:5000/manual
curl http://localhost:5000/error
Paso 8: Visualizar traces en Jaeger
Abre Jaeger UI en tu navegador:
http://localhost:16686
- En el dropdown «Service» selecciona: flask-tutorial-otel
- Haz clic en «Find Traces»
- Verás una lista de todos los traces generados
- Haz clic en cualquier trace para ver los detalles

¿Qué verás en Jaeger?
Cada trace muestra:
- Duración total: Cuánto tardó la petición completa
- Spans anidados: Visualización jerárquica de las operaciones
- Tags automáticos: Método HTTP, ruta, código de respuesta, etc.
- Atributos personalizados: Los que añadiste manualmente (usuario.id, precio.base, etc.)
- Errores: Stack traces completos cuando algo falla

El endpoint /manual es especialmente interesante porque muestra múltiples spans personalizados con atributos custom, simulando una operación real de negocio.

Conceptos importantes
Instrumentación automática vs manual
Automática: OpenTelemetry detecta cuando usas Flask, requests, SQLAlchemy, Redis, etc. y automáticamente genera traces sin que toques tu código. Solo con FlaskInstrumentor().instrument_app(app) ya tienes traces de todas las peticiones HTTP.
Manual: Tú decides qué partes de tu lógica de negocio quieres instrumentar. Usas with tracer.start_as_current_span() para crear spans personalizados con atributos específicos de tu dominio.
¿Qué es Jaeger?
Jaeger es un sistema de tracing distribuido open-source. OpenTelemetry genera los datos (traces), y Jaeger los visualiza en una interfaz gráfica. Jaeger es solo una de las opciones; también podrías usar Zipkin, Grafana Tempo, o servicios cloud como Datadog, New Relic, etc.
¿Por qué esto es útil?
En aplicaciones reales, especialmente microservicios, una petición puede pasar por múltiples servicios. OpenTelemetry permite:
- Ver el recorrido completo de una petición a través de todos los servicios
- Identificar cuellos de botella (qué operación tarda más)
- Detectar errores y su origen
- Analizar el comportamiento en producción sin necesidad de logs manuales
En resumen
Has aprendido los fundamentos de OpenTelemetry con un ejemplo práctico. Ahora sabes cómo instrumentar aplicaciones, generar traces automáticos y manuales, y visualizarlos en Jaeger. Este conocimiento es directamente aplicable a entornos de producción y microservicios reales.
Próximos pasos:
- Añade métricas con OpenTelemetry Metrics
- Experimenta con múltiples servicios comunicándose entre sí
- Conecta con bases de datos y ve cómo se capturan las queries automáticamente
- Exporta traces a otros backends (Grafana Tempo, Datadog, etc.)
Recursos
- 📦 Código completo en GitHub
- 📚 Documentación oficial de OpenTelemetry
- 🔍 OpenTelemetry Python
- 📊 Jaeger Documentation
¡Happy tracing!
¿Te ha resultado útil este tutorial? Compártelo y déjanos tus comentarios.