Manual Tracing and Spans
Relevant source files
The following files were used as context for generating this wiki page:
Manual tracing in Logfire provides developers with explicit control over how application logic is observed and recorded. By utilizing spans and manual log entries, developers can capture the execution flow, timing, and metadata of specific code blocks, providing deep visibility beyond what automatic instrumentation offers.
At its core, manual tracing involves creating "Spans"—objects that represent a unit of work with a start and end time—and "Logs," which are point-in-time events. These elements are built on top of OpenTelemetry but simplified through the Logfire SDK to provide Python-centric insights, such as rich object display and f-string magic.
Sources: README.md:12-25, logfire/_internal/config.py:100-110
Spans and Context Management
A span represents a operation or a block of code. In Logfire, spans are typically managed using context managers, ensuring that they are properly started and ended even if exceptions occur.
Creating Spans
The logfire.span() method is the primary entry point for manual tracing. It supports f-strings for dynamic message templates, allowing attributes to be automatically extracted from the local scope.
with logfire.span('Processing {user_id}', user_id=123):
# logic here
pass
Sources: README.md:65-75, logfire/_internal/main.py:550-580
Span Hierarchy and Lifecycle
Spans can be nested to create a parent-child relationship, reflecting the call stack of the application. When a span is created, it automatically becomes a child of the currently active span in the context.
The following diagram illustrates the lifecycle of a manual span managed via a context manager:
Manual Logging within Spans
While spans track duration and hierarchy, manual log methods record specific events or states at a point in time. Logfire provides several methods corresponding to standard log levels.
| Method | Level Number | Description |
|---|---|---|
trace() | 1 | Finest-grained informational events. |
debug() | 5 | Diagnostic information for developers. |
info() | 9 | Standard highlights in application flow. |
warn() / warning() | 13 | Indications of potential issues. |
error() | 17 | Serious issues that prevented a function from completing. |
exception() | 17 | Logs an error level message along with the current exception info. |
fatal() | 21 | Severe errors causing immediate termination. |
Sources: logfire/_internal/constants.py, logfire/_internal/main.py:400-500, tests/test_configure.py:123-150
Manual Instrumentation via Decorators
In addition to context managers, Logfire provides the @logfire.instrument decorator to automatically wrap function executions in spans. This reduces boilerplate for tracing entire function calls.
@logfire.instrument('Fetching data for {customer_id}')
def get_customer_data(customer_id: str):
return db.query(customer_id)
The decorator internally uses the same span logic, capturing function arguments as span attributes and recording any unhandled exceptions before the span ends.
Sources: logfire/_internal/instrument.py:20-60, logfire/_internal/main.py:900-920
Advanced Manual Controls
Setting Attributes and Tags
Manual tracing allows for adding metadata to spans after they have started. This is useful for recording results that are only known at the end of an operation.
set_attribute(key, value): Adds a specific metadata field to the span.with_tags(*tags): Returns a Logfire instance that will apply the specified tags to all subsequent spans and logs.
Force Flushing
In environments like AWS Lambda or short-lived scripts, it is crucial to ensure all captured spans are sent to the backend before the process terminates. The logfire.force_flush() method manually triggers the export of all pending telemetry data.
Sources: logfire/_internal/config.py:1050-1065, logfire/_internal/main.py:1100-1120, tests/test_configure.py:800-820
Data Flow Architecture
The manual tracing calls interact with a proxy system that delegates to the OpenTelemetry SDK while maintaining Logfire-specific configurations (like scrubbing and f-string inspection).
Conclusion
Manual tracing and spans in Logfire provide a robust framework for capturing application behavior. By combining f-string argument inspection with OpenTelemetry's hierarchical span model, Logfire simplifies the process of creating detailed, queryable traces that accurately reflect the logic and state of Python applications.
Sources: README.md:1-10, logfire/_internal/main.py:1200-1210