Skip to content

Tracing

TracingMiddleware reports spans to OpenTelemetry. It needs the otel extra:

uv add "potik[otel]"

Pass one instance to the runtime and one to each producer. Put it first in middleware=, so its spans cover the other middleware and the retries:

import potik
from potik import Producer
from potik.middleware.tracing import TracingMiddleware


async def main() -> None:
    async with Producer("broker:9092", middleware=[TracingMiddleware()]) as producer:
        await potik.build_runtime(config, [router], context=producer, middleware=[TracingMiddleware()]).run()

It creates a span for each handler call, each output, each transaction, and each send. Record headers carry the trace context, so one trace follows a request through every service. The API reference lists every span.

Attributes

Spans follow the OpenTelemetry semantic conventions for Kafka, and always have the attributes that the conventions require. The optional_attributes argument picks the optional ones. Record keys are off by default, because keys often identify people. To add them:

tracing = TracingMiddleware(optional_attributes=TracingMiddleware.DEFAULT_OPTIONAL_ATTRIBUTES | {"messaging.kafka.message.key"})

To add attributes of your own, or to rename a span, change the current span. In a handler, the current span is the record's process span:

from opentelemetry import trace


@router.handler(orders)
async def place(order: Order) -> None:
    trace.get_current_span().set_attribute("shop.tenant", order.tenant)

Sampling

The tracer provider's sampler decides which records' traces to keep. To keep every failed trace and a share of the rest, sample on the outcome with the tail_sampling processor of the OpenTelemetry Collector.

Each transaction's span starts a trace of its own. transaction_sample_ratio gives that share of the transactions a span, plus every failed one. The tracer provider's sampler still decides whether to keep each span:

tracing = TracingMiddleware(transaction_sample_ratio=0.1)

The tracing example runs three services with Jaeger.