OpenTelemetry pre Queue Observability
Na QCon London 2026 Julian Wreford a Oli Lane z Gearset ukázali, ako distributed tracing a SLO riešia slepé miesta v observabilite asynchrónnych systémov. Kľúčový insight: prestaňte merať veľkosť fronty — merajte latenciu.
Problém: Queue je čierna diera
Väčšina tímov monitoruje fronty takto:
# Typický alert — veľkosť fronty
rabbitmq_queue_messages > 10000
Prečo je to zlé:
- Veľká fronta nemusí znamenať problém (batch processing)
- Malá fronta môže skrývať oneskorenie (pomalí consumeri)
- Neviete, ktorá správa je oneskorená
- Chýba end-to-end viditeľnosť cez celý pipeline
Riešenie: Latency-based observability
Trace propagácia cez queue
# Producer — injektujte trace context do message headers
from opentelemetry import trace, context
from opentelemetry.propagate import inject
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("publish-order") as span:
headers = {}
inject(headers) # W3C traceparent
# Pridajte enqueue timestamp
headers["x-enqueue-time"] = str(time.time_ns())
channel.basic_publish(
exchange="orders",
routing_key="process",
body=message,
properties=pika.BasicProperties(headers=headers)
)
# Consumer — extrahujte context a merajte queue time
from opentelemetry.propagate import extract
def callback(ch, method, properties, body):
ctx = extract(properties.headers)
with tracer.start_as_current_span(
"consume-order",
context=ctx,
kind=trace.SpanKind.CONSUMER
) as span:
# Vypočítajte čas strávený vo fronte
enqueue_time = int(properties.headers.get("x-enqueue-time", 0))
queue_duration_ms = (time.time_ns() - enqueue_time) / 1e6
span.set_attribute("messaging.queue.duration_ms", queue_duration_ms)
process_order(body)
Trace State pre async duration tracking
OpenTelemetry tracestate umožňuje prenášať metadata bez zmeny trace ID:
# Nastavte tracestate s timing info
span.get_span_context().trace_state = trace_state.add(
"queue_enter", str(time.time_ns())
)
Toto umožňuje merať latenciu naprieč viacerými frontami v pipeline bez straty kontextu.
SLO namiesto alertov na veľkosť fronty
Definícia SLO
# SLO: 99% správ spracovaných do 30 sekúnd
apiVersion: sloth.slok.dev/v1
kind: PrometheusServiceLevel
metadata:
name: order-processing
spec:
service: order-pipeline
labels:
team: platform
slos:
- name: queue-latency
objective: 99
description: "99% správ spracovaných do 30s"
sli:
events:
errorQuery: |
sum(rate(queue_message_duration_seconds_bucket{le="30"}[5m]))
totalQuery: |
sum(rate(queue_message_duration_seconds_count[5m]))
alerting:
pageAlert:
labels:
severity: critical
ticketAlert:
labels:
severity: warning
Dashboard metriky
| Metrika | Čo meria | Prečo |
|---|---|---|
queue_message_duration_seconds |
Čas od enqueue po dequeue | Skutočná latencia |
queue_processing_duration_seconds |
Čas spracovania správy | Consumer výkon |
queue_e2e_duration_seconds |
End-to-end latencia | Celkový SLO |
| Error budget burn rate | Rýchlosť míňania error budgetu | Predikcia SLO breach |
Wide Events pre skryté problémy
Gearset tím objavil „hidden architectural waste" pomocou wide events — spanoch s desiatkami atribútov:
span.set_attribute("order.type", order_type)
span.set_attribute("order.items_count", len(items))
span.set_attribute("queue.name", "orders")
span.set_attribute("queue.wait_ms", queue_duration_ms)
span.set_attribute("consumer.batch_size", batch_size)
span.set_attribute("db.query_count", query_count)
Analýzou wide events v nástrojoch ako Honeycomb alebo Grafana Tempo dokázali identifikovať, že určité typy objednávok trvali 10× dlhšie kvôli N+1 query problému.
Zhrnutie
- Prestaňte alertovať na veľkosť fronty — merajte latenciu
- Propagujte trace context cez message headers
- Používajte SLO namiesto statických thresholdov
- Wide events odhaľujú skryté problémy, ktoré metriky neukážu
- OpenTelemetry má natívnu podporu pre messaging — využite ju