¿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 se trata 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.
Requisitos
- 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
Se han tratado los fundamentos de OpenTelemetry con un ejemplo práctico. Para aprender 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
Tomás Pardellas. Realizado el 26 dic 2025