La corrección está integrada en el TP (Ver los recuadros verdes)
Lo que vas a aprender en este TP
- Crear spans con el SDK
- Señalar errores, eventos y enlaces
- Consultar con TraceQL y muestrear
Introducción #
Lo que vas a aprender en esta sección
- Crear spans con el SDK
- Señalar errores, eventos y enlaces
- Consultar con TraceQL y muestrear
Contexto. El servicio de pedidos no tiene ninguna biblioteca auto-instrumentada para su lógica de negocio. Lo instrumentas a mano para ver las etapas de un pedido, sus errores de pago y sus procesos por lotes.
Requisitos previos: Docker y Python 3.10 o superior; la pila grafana/otel-lgtm (Collector, Tempo, Loki, Prometheus, Pyroscope y Grafana en un solo contenedor) · Duración estimada: 50 min
Puesta en práctica #
Pasos guiados, con su corrección.
1. Arrancar la pila de observabilidad
¿Por qué? Una sola imagen proporciona un Collector OTLP y todos los backends: nos centramos en la señal.
Lanzagrafana/otel-lgtm, crea un entorno Python y apunta los exportadores al puerto OTLP/HTTP 4318.Ver la corrección
docker run -d --name lgtm -p 3000:3000 -p 4317:4317 -p 4318:4318 -p 4040:4040 grafana/otel-lgtm python3 -m venv .venv && . .venv/bin/activate export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf # Grafana : http://localhost:3000 (admin / admin)2. Inicializar el SDK
¿Por qué? El TracerProvider lleva el recurso y el exportador; el BatchSpanProcessor envía por lotes.
Instala el SDK y el exportador OTLP/HTTP y escribeotel_setup.py, que configura el recurso (service.name,service.version,deployment.environment.name) y la exportación.Ver la corrección
pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http cat > otel_setup.py <<'EOF' from opentelemetry import trace from opentelemetry.sdk.resources import Resource from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter resource = Resource.create({"service.name": "commandes", "service.version": "1.0.0", "deployment.environment.name": "tp"}) provider = TracerProvider(resource=resource) # l'échantillonneur est lu dans OTEL_TRACES_SAMPLER provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter())) trace.set_tracer_provider(provider) EOF3. Crear una traza de negocio
¿Por qué? Spans con el nombre de cada etapa, con SpanKind y atributos conformes a las convenciones, hacen la traza legible por todas las herramientas.
Escribecommande.py: un span raíztraiter commandey tres hijos (stock como CLIENT con atributos de base de datos, cálculo, pago), un evento y un error de pago una vez de cada tres conrecord_exceptiony estado ERROR.Ver la corrección
cat > commande.py <<'EOF' import random, time from otel_setup import provider from opentelemetry import trace from opentelemetry.trace import SpanKind, Status, StatusCode tracer = trace.get_tracer("tp.commandes", "1.0.0") class PaiementRefuse(Exception): pass def traiter(numero): with tracer.start_as_current_span("traiter commande", kind=SpanKind.SERVER) as span: span.set_attribute("shop.order.id", numero) with tracer.start_as_current_span("SELECT stock", kind=SpanKind.CLIENT) as db: db.set_attribute("db.system.name", "postgresql") db.set_attribute("db.collection.name", "stock") db.set_attribute("db.operation.name", "SELECT") time.sleep(random.uniform(0.01, 0.05)) with tracer.start_as_current_span("calculer total"): time.sleep(random.uniform(0.005, 0.02)) with tracer.start_as_current_span("payer", kind=SpanKind.CLIENT) as pay: pay.add_event("fraude.verifiee", {"shop.fraud.score": round(random.random(), 2)}) time.sleep(random.uniform(0.05, 0.3)) try: if numero % 3 == 0: raise PaiementRefuse("carte refusée") except PaiementRefuse as exc: pay.record_exception(exc) pay.set_status(Status(StatusCode.ERROR, str(exc))) span.set_status(Status(StatusCode.ERROR, "paiement refusé")) span.set_attribute("error.type", "PaiementRefuse") for n in range(1, 31): traiter(n) provider.shutdown() # vide le dernier lot EOF python commande.py4. Explorar y consultar con TraceQL
¿Por qué? TraceQL filtra por la estructura y los atributos de los spans: una consulta encuentra las trazas importantes.
En Grafana, abre Explore > Tempo. Ejecuta las consultas siguientes, abre una traza con error y encuentra el evento y la excepción del spanpayer.Ver la corrección
{ resource.service.name = "commandes" && status = error } { name = "payer" && duration > 200ms } { span.db.system.name = "postgresql" } { name = "traiter commande" } >> { name = "payer" && status = error }5. Vincular un proceso por lotes con enlaces
¿Por qué? Un lote que procesa elementos de varias trazas no puede tener varios padres: se usan enlaces.
Escribelot.py: tres trazas «recepción» independientes y luego un spanfacturer lotenlazado a las tres. Encuentra los enlaces en el detalle del span.Ver la corrección
cat > lot.py <<'EOF' from otel_setup import provider from opentelemetry import trace from opentelemetry.trace import Link tracer = trace.get_tracer("tp.lots") contextes = [] for i in range(3): with tracer.start_as_current_span("recevoir message") as span: span.set_attribute("messaging.message.id", f"msg-{i}") contextes.append(span.get_span_context()) with tracer.start_as_current_span("facturer lot", links=[Link(c) for c in contextes]) as lot: lot.set_attribute("messaging.batch.message_count", len(contextes)) provider.shutdown() EOF python lot.py6. Muestrear
¿Por qué? El muestreo por ratio reduce el volumen; parentbased garantiza que una traza se conserve o se descarte entera.
Vuelve a lanzarcommande.pycon un muestreo del 20 % y compara el número de trazas recibidas; comprueba que ninguna traza está incompleta. Explica por qué el tail sampling del Collector sería preferible para conservar todos los errores.Ver la corrección
OTEL_TRACES_SAMPLER=parentbased_traceidratio OTEL_TRACES_SAMPLER_ARG=0.2 python commande.py # Grafana : { resource.service.name = "commandes" } sur les 5 dernières minutes : ~6 nouvelles traces au lieu de 30 # le head sampling jette aussi ~80 % des traces en erreur : le tail sampling (politique status_code) les garderait toutes
Nivel de dificultad : ●●●○○ (3/5)
Mi seguimiento
Inicia sesión para seguir tu progreso y tomar notas. Iniciar sesión
Artículos recomendados
Les traces OpenTelemetry en profondeur : spans, statuts, événements, liens et échantillonnage
Maîtriser le signal trace : anatomie d'une trace distribuée, span et SpanKind, attributs, statut ...
Tracing distribué : la propagation du contexte (W3C Trace Context et baggage)
Comprendre et mettre en œuvre la propagation de contexte OpenTelemetry : en-tête traceparent, tra...
Grafana Alloy: Perfilado Continuo con Pyroscope
Descubra cómo configurar el perfilado continuo (Continuous Profiling) en sus entornos utilizando ...