Custom Spans
The tracing module exposes typed factory functions for every built-in span
kind (agent, function, generation, response, handoff, guardrail) plus
custom_span() for application-authored instrumentation.
The tracer registry
Tracing is opt-in. Until an application calls set_tracer(...), every span
factory returns a NoOpSpan β zero cost on the hot path.
from augments.adk.tracing import set_tracer, get_tracer
class MyBackendTracer:
def agent_span(self, data): ...
def function_span(self, data): ...
# ... one method per span kind
def custom_span(self, data): ...
set_tracer(MyBackendTracer())The installed tracer implements the Tracer protocol (seven factory
methods, one per span kind) and is fetched lazily via get_tracer() inside
every factory, so swapping tracers at runtime is a single call.
custom_span(name, *, data=None, span_id=None, disabled=False)
The only tracing factory the ADK exposes for application code.
from augments.adk.tracing import custom_span
with custom_span("rank_search_results", data={"n": len(results)}) as span:
ranked = rank(results)
span.data.data["elapsed_ms"] = elapsednameβ short human-readable span namedataβ arbitrary JSON-safe payload (merged into the span'sCustomSpanData)span_idβ optional caller-assigned identifierdisabledβ return aNoOpSpanregardless of the installed tracer
The span is a context manager: start() runs on entry, finish() on exit,
and any exception is recorded via set_error() before re-raising.
Typed span-data classes
Each built-in span kind has a frozen dataclass payload in
augments.adk.types.tracing.span_data. This is the "G4" layer β typed
observability instead of untyped dict attributes:
| Factory | Data class | Fields |
|---|---|---|
agent_span | AgentSpanData | name, handoffs, tools, output_type, metadata |
function_span | FunctionSpanData | name, input, output, mcp_data |
generation_span | GenerationSpanData | input, output, model, model_config, usage |
response_span | ResponseSpanData | response_id, input |
handoff_span | HandoffSpanData | from_agent, to_agent |
guardrail_span | GuardrailSpanData | name, triggered |
custom_span | CustomSpanData | name, data |
AgentSpanData.metadata is the home for arbitrary per-run tags passed
via RunConfig.tracing_metadata β see docs/tracing/tracing.md.
All seven classes subclass SpanData and are frozen dataclasses β safe to
pass across the tracer boundary without defensive copying.
Recording errors without raising
with custom_span("risky_step") as span:
try:
do_work()
except RecoverableError as e:
span.set_error(str(e), data={"type": type(e).__name__})
return fallback()set_error() populates the span's error dict; the context manager's
__exit__ only records a fresh error if one hasn't already been set (via
the captured exc_val).
See also
src/augments/adk/tracing/tracer.pyβTracerprotocol + registrysrc/augments/adk/tracing/spans.pyβSpan,NoOpSpan, factory functionssrc/augments/adk/types/tracing/span_data.pyβ typed payload dataclassesexamples/tracing/custom_span_example.pyβ runnable exampletests/unit/tracing/β tracer, span, and span-data tests