Tracing¶
Export OTLP spans to OpenGrade and annotate them.
Use the methods of your Opengrade instance: og.trace, og.span, og.set_user, … They take
the same arguments as the module-level functions documented below, and always go to that
instance. The module-level functions go to the instance activated with og.activate().
trace ¶
Trace a function in this instance's project: @og.trace or @og.trace(...).
Same options as opengrade.trace (name, kind, metrics, redact,
...). Unlike it, the call is routed to this instance without activate(), and
tracing starts by itself (init_tracing() defaults) if it was not initialized.
span ¶
span(name: str, kind: str = 'CHAIN', *, input: object = None, attributes: dict[str, object] | None = None, live: bool | None = None) -> span
Trace a block as a span of this instance (with or async with).
init_tracing ¶
init_tracing(*, project_id: str | None = None, project_slug: str | None = None, endpoint: str | None = None, service_name: str | None = None, instrument: Literal['auto', False] | Sequence[str] = 'auto', force: bool = False, live: bool | None = None, live_sample_rate: float | None = None, trace_sample_rate: float | None = None, max_capture_bytes: int | None = None, metrics_workers: int | None = None, version: str | None = None, environment: str | None = None, **kwargs: Any) -> None
Configure OTLP export for this instance via the shared TracerProvider.
flush ¶
Flush spans, then production metrics, then queued trace scores.
timeout_millis is the total budget: each stage gets what the previous left.
Metrics are drained before scores are flushed because they produce scores.
trace ¶
trace(name: str | None = None, *, kind: str = 'CHAIN', capture_input: bool = True, capture_output: bool = True, live: bool | None = None, metrics: Sequence[LocalMetric | Callable[..., Any]] | None = None, metrics_sample_rate: float = 1.0, redact: Callable[[str, Any], Any] | None = None, redact_output: Callable[[Any], Any] | None = None, join_chunks: Callable[[Any, Any], Any] | None = None) -> Callable[[Callable[P, R]], Callable[P, R]]
trace(name: str | Callable[P, R] | None = None, *, kind: str = 'CHAIN', capture_input: bool = True, capture_output: bool = True, live: bool | None = None, metrics: Sequence[LocalMetric | Callable[..., Any]] | None = None, metrics_sample_rate: float = 1.0, redact: Callable[[str, Any], Any] | None = None, redact_output: Callable[[Any], Any] | None = None, join_chunks: Callable[[Any, Any], Any] | None = None) -> Any
Trace a function as an OpenInference span.
Dispatches on function kind: sync, async def, generator, or async generator.
For generator and async-generator functions the span is current only during each
advance (next() / __anext__); between yields it is not the active context.
Streamed chunks are accumulated into output.value: plain strings and common
LLM delta shapes are joined as text by default. Pass join_chunks(chunk, acc)
to replace that reducer (acc starts as None); join errors are stored as
"<join error>". Plain sync/async functions ignore join_chunks.
metrics=[...] scores each sampled production call after it returns (off the
request path) and stores the results as trace scores; metrics_sample_rate is
the fraction of traces scored, deterministic per trace. Skipped inside experiments.
Metrics are not supported on generator / async-generator functions.
span ¶
span(name: str, kind: str = 'CHAIN', *, input: object = None, attributes: dict[str, object] | None = None, live: bool | None = None)
Trace a block of code as a child span (sync with or async with).
::
with opengrade.span("rerank", kind="RERANKER", input=query) as s:
ranked = reranker.rank(query, docs)
s.set_output([d.id for d in ranked])
s.set_attribute("rerank.top_k", 5)
kind is an OpenInference span kind (CHAIN, LLM, RETRIEVER,
RERANKER, EMBEDDING, TOOL, AGENT, GUARDRAIL, ...). An exception
raised in the block marks the span ERROR and propagates. Like @opengrade.trace,
the outermost span outside an experiment becomes a live interaction when
init(live=True); pass live=False to opt out.
SpanHandle ¶
current_trace_id ¶
Return the current OTLP trace id as 32-char hex, or None if inactive.
set_input ¶
Set OpenInference input.value on the current span (and production metrics' input).
set_output ¶
Set OpenInference output.value on the current span (and production metrics' output).
set_error ¶
Mark the current span as ERROR (optionally attach an exception).
set_attribute ¶
Set one attribute on the current opengrade span (no-op if none is active).
set_attributes ¶
Set multiple attributes on the current opengrade span.
set_user ¶
Set the end user (user.id) of the current trace.
Call it inside a traced call (@opengrade.trace or opengrade.span); the
platform lifts it to the trace, so any span of the trace works. No-op otherwise.
set_session ¶
Set the session / conversation (session.id) of the current trace.
set_tags ¶
Add tags (tag.tags) to the current trace; repeated calls accumulate.
set_metadata ¶
Merge key/value metadata (metadata) into the current trace.
Values should be scalars (str, int, float, bool); anything else is stored as
JSON text. Keys starting with _ are reserved and ignored. Traces can be
filtered by key:value in the UI and API.
using_attributes ¶
using_attributes(*, user_id: str | None = None, session_id: str | None = None, tags: Iterable[str] | None = None, metadata: Mapping[str, object] | None = None) -> Iterator[None]
Attach user / session / tags / metadata to every span opened in this block.
Blocks nest: inner ids win, tags and metadata accumulate. Useful in a request middleware, where the user is known before any traced call starts::
with opengrade.using_attributes(user_id=user.id, session_id=chat_id, tags=["beta"]):
answer(question)