Skip to main content
A Span represents a single operation within an agent execution. Spans form a parent-child hierarchy within a trace, allowing you to understand the execution flow.

Span Attributes

AttributeTypeDefaultDescription
span_idstrRequiredUnique span identifier
trace_idstrRequiredParent trace ID (groups related spans)
parent_span_idOptional[str]NoneParent span ID (None for root spans)
namestrRequiredOperation name (e.g., OpenAIChat.invoke, get_weather)
status_codestrRequiredStatus: OK, ERROR, or UNSET
status_messageOptional[str]NoneStatus message (typically error details)
duration_msintRequiredExecution time in milliseconds
start_timedatetimeRequiredWhen the span started
end_timedatetimeRequiredWhen the span completed
attributesOptional[dict]NoneOpenTelemetry attributes (tokens, params, etc.)
eventsOptional[list]NoneSpan events
kindOptional[str]NoneSpan kind (e.g., INTERNAL, CLIENT)

Common Span Names

Spans are automatically created for various operations:
Span Name PatternDescription
{AgentName}.runAgent execution
{TeamName}.runTeam execution
{ModelName}.invokeLLM model call
{tool_name}Tool execution

Attributes by Operation Type

The attributes field contains OpenTelemetry semantic attributes that vary by operation:

LLM Spans

AttributeDescription
llm.token_count.promptInput token count
llm.token_count.completionOutput token count
llm.model_nameModel identifier
llm.providerModel provider name

Tool Spans

AttributeDescription
tool.nameTool function name
tool.parametersTool input parameters (JSON)

Methods

to_dict()

Convert the span to a dictionary.
span_dict = span.to_dict()
Returns: dict

from_dict()

Create a span from a dictionary.
span = Span.from_dict(data)
Parameters:
  • data (dict): Dictionary containing span data
Returns: Span

Usage

from agno.db.sqlite import SqliteDb

db = SqliteDb(db_file="tmp/traces.db")

# Get all spans for a trace
spans = db.get_spans(trace_id=trace.trace_id)

for span in spans:
    print(f"Span: {span.name}")
    print(f"  Duration: {span.duration_ms}ms")
    print(f"  Status: {span.status_code}")
    
    # Check for token usage (LLM spans)
    if span.attributes:
        tokens = span.attributes.get("llm.token_count.completion")
        if tokens:
            print(f"  Tokens: {tokens}")

Building a Span Tree

def print_span_tree(spans, parent_id=None, indent=0):
    """Recursively print spans as a tree."""
    for span in spans:
        if span.parent_span_id == parent_id:
            prefix = "  " * indent + ("└─ " if indent > 0 else "")
            print(f"{prefix}{span.name} ({span.duration_ms}ms)")
            print_span_tree(spans, span.span_id, indent + 1)

# Get spans and print tree
spans = db.get_spans(trace_id=trace.trace_id)
print_span_tree(spans)

See Also