class

Logit::Span

Inherits Reference / Object

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

current

Returns the current span for this fiber.

Raises an exception if no span is active. Prefer current? unless you're certain a span exists.

Source
new(name : String, span_id : String = Utils::IDGenerator.span_id, parent_span_id : Nil | String = nil)

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.

Source

Class methods

current?

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
Source
pop(fiber_stack : Array(Span)) : Span | Nil

Optimized version that takes the span stack directly to avoid repeated Fiber.current access. Used internally by the instrumentation macros.

Source
pop

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.

Source
push(span : Span, fiber_stack : Array(Span)) : Nil

Optimized version that takes the span stack directly to avoid repeated Fiber.current access. Used internally by the instrumentation macros.

Source
push(span : Span) : Nil

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.

Source

Instance methods

add_event(name : String, **attributes) : Nil

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.

Source
attributes

Structured attributes attached to this span.

Source
attributes=(attributes : Event::Attributes)

Structured attributes attached to this span.

Source
end_time

When this span ended (set when the span completes).

Source
end_time=(end_time : Time | Nil)

When this span ended (set when the span completes).

Source
events

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.

Source
exception

Exception information if an error occurred during this span.

Source
exception=(exception : ExceptionInfo | Nil)

Exception information if an error occurred during this span.

Source
name

Name of this span (typically the method name).

Source
name=(name : String)

Name of this span (typically the method name).

Source
parent_span_id

Span ID of the parent span, or nil if this is a root span.

Source
parent_span_id=(parent_span_id : String | Nil)

Span ID of the parent span, or nil if this is a root span.

Source
span_id

Unique identifier for this span (64-bit hex string).

Source
span_id=(span_id : String)

Unique identifier for this span (64-bit hex string).

Source
start_time

When this span started.

Source
start_time=(start_time : Time)

When this span started.

Source
to_event(trace_id : String, level : LogLevel, code_file : String, code_line : Int32, method_name : String, class_name : String) : Event

Converts this span to an Event for logging.

Called automatically when a span completes. You typically don't need to call this directly.

Source
trace_id

W3C trace ID (128-bit hex string) shared across all spans in a trace.

Source
trace_id=(trace_id : String)

W3C trace ID (128-bit hex string) shared across all spans in a trace.

Source