发布

  • [OPIK-6770] [SDK] [DOCS] fix: link in-process OpenTelemetry spans to the active @opik.track trace (#7006)

    frostbyte_neo 发布于 2026-06-10 14:14:16 +00:00

    • [OPIK-6770] [SDK] fix: auto-link in-process OTel spans to the active @opik.track trace

    OpikSpanProcessor only propagated Opik IDs that were already present on a
    parent OTel span (via attach_to_parent) or in W3C baggage. Spans emitted by
    libraries that produce their own OTel spans (e.g. logfire/PydanticAI) inside an
    @opik.track function had no such parent, so they landed in a separate synthetic
    trace instead of nesting under the tracked span.

    Add an in-process fallback: when neither the parent span nor baggage carry Opik
    IDs, the processor reads the active @opik.track context and stamps
    opik.trace_id / opik.parent_span_id / opik.span_id on the subtree root.
    Descendants then chain via the existing parent-attribute path. Distributed
    flows (parent attrs, baggage) keep precedence, so cross-process tracing is
    unchanged.

    Tests: processor unit coverage for the main flows (generic multi-tracer,
    nested track, baggage precedence, worker-thread boundary, async), an
    opentelemetry e2e for native+OTel composition, and a pydantic_ai+logfire e2e
    reproducing the ticket. Wire the pydantic_ai suite into CI.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • docs(otel): document in-process @track + OTel auto-linking

    OpikSpanProcessor now also links OTel spans to the active @opik.track context
    in the same process. Update the OpenTelemetry Python SDK and distributed-traces
    pages (the previous "only attached subtrees" wording was inaccurate) and add a
    "Combining with @track" section to the PydanticAI integration pages (v1 + v2).

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • fix(otel): address code review — error-path semantics, docs, test hardening
    • processor: on invalid (non-UUIDv7) baggage, leave the span standalone instead
      of falling back to the local @track context — a broken upstream distributed
      context should not be silently absorbed into an unrelated local trace
    • test: lock that behavior; assert the PydanticAI OTel root span is named
      "agent run" (not parentage alone); move the bespoke multi-tracer provider to a
      yield fixture so teardown runs on failure; drop redundant parens
    • docs: make the @track PydanticAI snippets runnable (sync + invoked), modernize
      result.data -> result.output on both pages, add trailing newline

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • fix(otel): only fall back to @track context when no Opik signal exists

    Address PR review: the in-process @opik.track fallback previously fired whenever
    baggage had no opik.trace_id, even if a partial/broken Opik payload was present
    (e.g. opik.span_id without opik.trace_id in the parent span or baggage). That
    could silently reattach a span carrying a broken distributed context to an
    unrelated local trace. The fallback now runs only when there is no Opik signal
    at all; any partial payload leaves the span standalone (with a warning).

    Add unit coverage for the partial-baggage case, and an e2e test exercising two
    sequential PydanticAI agent calls under one @track entrypoint — both 'agent run'
    subtrees nest as siblings with their own model span and no cross-linking.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • test(otel): use verify_span helpers in the two-agent-call e2e assertions

    Address PR review: replace the hand-rolled by_id/roots span-structure checks in
    the two-agent-call test with tests.e2e.verifiers.verify_span for the entrypoint,
    each 'agent run', and each model span. search_spans is kept only to discover the
    backend-minted span ids and assert the 5-span completeness/one-child invariant.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • test(otel): e2e for cross-origin parent-child nesting (nested @track + OTel)

    Add an integration test interleaving native @opik.track spans with logfire/
    PydanticAI OTel spans at different depths: a nested inner_step under an outer
    entrypoint, each making an agent call. Asserts each OTel 'agent run' attaches to
    the innermost active native span (one under inner_step, one under outer), so
    parent-child links are preserved across origins within one trace. Deterministic
    (TestModel), polls to a fixed 6-span count — no sleeps.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

    • fix(sdk): stop global time.sleep patch hanging the unit suite; add pytest timeout

    The Python 3.10 unit job hung for 20 min at the rate-limit retry tests. Root
    cause: the search/rate-limit tests patched the GLOBAL time.sleep
    (rest_helpers.time.sleep). A leaked QueueConsumer daemon thread paces its loop
    with time.sleep, so a no-op global sleep turned it into a busy loop that
    starved the interpreter under 3.10's GIL scheduling.

    Fix #1: route the rate-limit retry delay through rest_helpers._sleep and patch
    that narrow indirection in the tests, leaving the global time.sleep (and
    background-thread pacing) untouched.

    Fix #3: add pytest-timeout and run the unit job with
    --timeout=120 --timeout-method=thread, so a future hang fails fast with all
    thread stacks dumped instead of a silent 20-min cancel.

    Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com


    Co-authored-by: Claude Opus 4.8 (1M context) noreply@anthropic.com

    下载附件