Trazas / hora
1,247
↑ 12% vs. última hora
Latencia P95 global
2.31s
POST /api/plans/generate
Trazas con error
3.4%
42 trazas en la última hora
Servicios instrumentados
4 / 4
OpenTelemetry SDK activo
TRAZA REPRESENTATIVA · POST /api/plans/generate
Trace ID: 4bf92f3577b34da6a3ce929d0e0e4736
Servicio · Operación
Timeline (0 → 2847ms)
api-gateway · HTTP POST /api/plans/generate
auth_middleware (JWT validate)
rate_limit_check (Redis)
patient-service · GET /internal/patients/:id
db.query — SELECT patients (PostgreSQL)
db.query — SELECT nutrition_history
nutrition-service · POST /internal/plans/generate
validate_plan_input
cache.get — Redis (MISS)
ai_model_inference · NutriGPT v2.1 (CPU)
db.query — INSERT nutrition_plans
notification-service · POST /internal/notify (email)
serialize_response (JSON)
0
284ms
569ms
853ms
1.14s
1.42s
1.71s
1.99s
2.28s
2.56s
2.85s
Servicios Instrumentados
api-gateway
108ms
P99 · 1,247 req/h
nutrition-service
5.8s
P99 · 1,247 req/h
patient-service
312ms
P99 · 1,247 req/h
notification-service
198ms
P99 · 1,247 req/h
Estrategia de Muestreo (jaeger-sampling.json)
nutrition-service
probabilistic · ruta crítica IA
100%
api-gateway
probabilistic
50%
patient-service
probabilistic (default)
10%
notification-service
probabilistic (default)
10%
GET /health, /ready
operation override
0.1%
Distribución de latencia — última hora
INSTRUMENTACION · nutrition-service/tracing.py
OpenTelemetry SDK · Python 3.11 · Exporter: OTLP gRPC → Jaeger :4317
# nutrition-service/tracing.py — NutriFlow
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.resources import Resource
from opentelemetry.instrumentation.flask import FlaskInstrumentor
from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
from opentelemetry.instrumentation.redis import RedisInstrumentor
def init_tracing(service_name: str):
resource = Resource.create({
"service.name": service_name,
"service.version": "2.1.0",
"deployment.environment": "staging",
"team": "nutriflow-backend",
})
provider = TracerProvider(resource=resource)
exporter = OTLPSpanExporter(endpoint="http://jaeger:4317", insecure=True)
provider.add_span_processor(BatchSpanProcessor(exporter))
trace.set_tracer_provider(provider)
FlaskInstrumentor().instrument()
SQLAlchemyInstrumentor().instrument()
RedisInstrumentor().instrument()
return trace.get_tracer(service_name)
# app.py — span personalizado para la inferencia IA
tracer = init_tracing("nutrition-service")
@app.route("/internal/plans/generate", methods=["POST"])
def generate_plan():
with tracer.start_as_current_span("ai_model_inference") as span:
span.set_attribute("model.name", "NutriGPT-v2.1")
span.set_attribute("model.device", "cpu") # ← candidato a GPU
span.set_attribute("patient.goal", data["goal"])
span.set_attribute("plan.days", 7)
result = nutrigpt_model.generate(data) # P99: 5.8s en CPU
span.set_attribute("plan.tokens_generated", result["tokens"])
return result, 200