Spans
A span represents a single operation within a trace - like an LLM call, tool execution, or retrieval step.Span Structure
Every span contains:| Property | Description |
|---|---|
spanId | Unique identifier |
traceId | Parent trace identifier |
parentSpanId | Parent span (for nesting) |
spanKind | Type of operation |
name | Operation name (e.g., model name, tool name) |
startTime | When operation began |
endTime | When operation completed |
durationMs | Duration in milliseconds |
input | Input data |
output | Output data |
status | ’completed’ or ‘error’ |
tokens | Token usage (for LLM spans) |
error | Error message (if failed) |
Span Types
Foil supports several span types to categorize different operations:LLM Span
For language model API calls:Tool Span
For function/tool executions:Agent Span
For high-level agent orchestration:Retriever Span
For RAG retrieval operations:Embedding Span
For embedding generation:Chain Span
For pipeline/chain steps:Custom Span
For any other operation:Span Nesting
Spans automatically form a hierarchy:Recording Data
Input
Record what goes into the operation:Output
Record what comes out:Tokens
For LLM spans, always record token usage:Timing
Record timing metrics:Errors
Record failures:Custom Properties
Add metadata for filtering and analysis:Best Practices
Use appropriate span types
Use appropriate span types
Choose the span type that best represents the operation. This enables better filtering and analytics.
Always record tokens for LLM spans
Always record tokens for LLM spans
Token counts are essential for cost tracking and optimization.
Include meaningful inputs/outputs
Include meaningful inputs/outputs
Record enough context to debug issues, but be mindful of data size.
End spans properly
End spans properly
Always call
span.end() even on errors. Use try/finally or wrapInSpan for automatic handling.Keep span names consistent
Keep span names consistent
Use consistent naming (model names, tool names) to enable aggregation.