🟡 Intermediate

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