Skip to content

otel compatible distributed tracing#496

Open
Andrew Kent (realark) wants to merge 1 commit into
mainfrom
ark/distributed-tracing
Open

otel compatible distributed tracing#496
Andrew Kent (realark) wants to merge 1 commit into
mainfrom
ark/distributed-tracing

Conversation

@realark

@realark Andrew Kent (realark) commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

OLD WAY: https://www.braintrust.dev/docs/instrument/advanced-tracing#trace-distributed-systems

from braintrust import current_span, init_logger, start_span, traced

logger = init_logger(project="my-project")

# Client: Export the span
@traced
def process_request(request):
    return requests.post(
        "/api/process",
        json=request,
        headers={"X-Trace-ID": current_span().export()},
    )

# Server: Resume the trace
def handle_request(req):
    trace_id = req.headers.get("X-Trace-ID")

    with start_span(parent=trace_id) as span:
        result = process_data(req.body)
        span.log(input=req.body, output=result)
        return result

NOTE: the "old way" is still supported and backwards-compatible. Native SDKs can continue to link to each other in the manner, even if one is upgraded and the other is not. However if users with to link to otel sdks, they will have to change their code to use the new apis.

NEW WAY:

from braintrust import current_span, init_logger, start_span, traced

logger = init_logger(project="my-project")

# Client: Export the span
@traced
def process_request(request):
    return requests.post(
        "/api/process",
        json=request,
        headers=current_span().inject({}), # <--- new inject api
    )

# Server: Resume the trace
def handle_request(req):
    with start_span(parent=extract_trace_context(req.headers) as span: # <--- new extract api
        result = process_data(req.body)
        span.log(input=req.body, output=result)
        return result

Other notes

  • confusing naming: this has the unfortunate effect of the root_span_id field essentially becoming the trace id rather than the id of the root span (i.e. root_span_id != rootSpan.id). This sucks, but it's already the case for otel sdks and py otel compat mode. So at least we're consistent.
  • legacy id flag: the sdk currently maintains two paths for id generation. it defaults to UUIDs and does hex IDs when we're in in otel compat mode. This changes the default to use hex IDs and has a flag to revert to the old behavior. We could just rip out the old uuid logic entirely, but this approach seems like the least risky
  • to support passing through tracestate and flags, an additional field was added to SpanImpl (propagated_state)

Examples

@realark Andrew Kent (realark) force-pushed the ark/distributed-tracing branch 14 times, most recently from 84c5773 to 915ea54 Compare June 9, 2026 00:08
@realark Andrew Kent (realark) marked this pull request as ready for review June 9, 2026 00:11
implements the `distributed-tracing` sdk spec

- default span/trace id gen to use otel-friendly 16/8 byte hex IDs
- new inject/extract tools for w3c headers
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant