Logit::Span
Represents a traced operation with timing, attributes, and trace context.
Spans are the core building block of Logit's tracing system. Each instrumented method call creates a span that tracks:
- Start and end times (for duration calculation)
- Trace and span IDs (for distributed tracing)
- Parent span ID (for call hierarchy)
- Custom attributes (for structured data)
- Exception information (if an error occurred)
Spans are stored in a fiber-local stack, allowing safe concurrent tracing across multiple fibers without interference.
Accessing the Current Span
Inside an instrumented method, you can access the current span to add custom attributes:
class OrderService
@[Logit::Log]
def process_order(order_id : Int32) : Bool
# Add custom attributes to the current span
if span = Logit::Span.current?
span.attributes.set("order.priority", "high")
span.attributes.set("order.items_count", 5_i64)
end
# ... process the order
true
end
end
Trace Context
Nested method calls automatically share the same trace ID and form a parent-child relationship through span IDs:
class PaymentService
@[Logit::Log]
def charge(amount : Float64) : Bool
validate_amount(amount) # Child span, same trace_id
process_payment(amount) # Child span, same trace_id
true
end
@[Logit::Log]
def validate_amount(amount : Float64) : Bool
amount > 0
end
@[Logit::Log]
def process_payment(amount : Float64) : Bool
# ...
true
end
end
Constructors
Returns the current span for this fiber.
Raises an exception if no span is active. Prefer current? unless you're
certain a span exists.
Creates a new span with the given name.
Automatically inherits the trace ID from the current span (if any), or generates a new trace ID for root spans. The parent span ID is set to the current span's ID.
Class methods
Returns the current span for this fiber, or nil if none is active.
Use this to safely access the current span without raising an exception.
if span = Logit::Span.current?
span.attributes.set("custom.field", "value")
end
Optimized version that takes the span stack directly to avoid repeated Fiber.current access. Used internally by the instrumentation macros.
Pops the current span from the fiber-local span stack.
This is called automatically by the instrumentation macros. You typically don't need to call this directly.
Optimized version that takes the span stack directly to avoid repeated Fiber.current access. Used internally by the instrumentation macros.
Pushes a span onto the fiber-local span stack.
This is called automatically by the instrumentation macros. You typically don't need to call this directly.
Instance methods
Adds a span event (intermediate log within a span).
This allows logging important events during long-running operations without creating separate spans. Events are attached to this span and included when the span is converted to an Event.
Usage
@[Logit::Log]
def process_large_file(path : String) : Result
span = Logit::Span.current
span.add_event("file.opened", path: path)
results = process_chunks(path)
span.add_event("file.processed",
path: path,
chunks: results.size
)
results
end
OpenTelemetry Compatibility
Span events map directly to OpenTelemetry Span Events, allowing for rich observability without creating separate spans for every operation.
Span events that occurred during this span's lifetime.
These are intermediate logs attached to a span, similar to
OpenTelemetry's Span Events. Use add_event to add events.
Exception information if an error occurred during this span.
Span ID of the parent span, or nil if this is a root span.