Langfuse.Span (Langfuse v0.2.0)

View Source

A span represents a unit of work with duration within a trace.

Spans track operations like data retrieval, preprocessing, postprocessing, or any logical step in your LLM pipeline. They have a start time and an end time, enabling duration analysis in the Langfuse dashboard.

Creating Spans

Spans are created as children of traces or other spans:

trace = Langfuse.trace(name: "rag-pipeline")

span = Langfuse.Span.new(trace, name: "document-retrieval")

Nesting Spans

Spans can be nested to represent hierarchical operations:

trace = Langfuse.trace(name: "pipeline")
outer_span = Langfuse.Span.new(trace, name: "retrieval")
inner_span = Langfuse.Span.new(outer_span, name: "vector-search")

Completing Spans

Always end spans to record accurate duration:

span = Langfuse.Span.new(trace, name: "process")
# ... do work ...
span = Langfuse.Span.end_span(span)

Or use update/2 to add output before ending:

span = Langfuse.Span.update(span, output: result)
span = Langfuse.Span.end_span(span)

Summary

Types

Log level for the observation.

Observation type for categorizing spans.

Valid parent types for a span: a trace or another span.

t()

A span struct containing all span attributes.

Functions

Ends the span by setting its end time to now.

Returns the span ID.

Returns the trace ID that this span belongs to.

Creates a new span and enqueues it for ingestion.

Updates an existing span and enqueues the update for ingestion.

Types

level()

@type level() :: :debug | :default | :warning | :error

Log level for the observation.

observation_type()

@type observation_type() ::
  :span
  | :agent
  | :tool
  | :chain
  | :retriever
  | :embedding
  | :evaluator
  | :guardrail

Observation type for categorizing spans.

Different types enable specialized views in the Langfuse dashboard:

  • :span - Generic unit of work (default)
  • :agent - AI agent decision spans
  • :tool - Tool/function call observations
  • :chain - Links between application steps
  • :retriever - RAG/data retrieval steps
  • :embedding - Embedding generation
  • :evaluator - Evaluation function spans
  • :guardrail - Safety/moderation checks

parent()

@type parent() :: Langfuse.Trace.t() | t()

Valid parent types for a span: a trace or another span.

t()

@type t() :: %Langfuse.Span{
  end_time: DateTime.t() | nil,
  id: String.t(),
  input: term(),
  level: level() | nil,
  metadata: map() | nil,
  name: String.t(),
  output: term(),
  parent_observation_id: String.t() | nil,
  start_time: DateTime.t(),
  status_message: String.t() | nil,
  trace_id: String.t(),
  type: observation_type(),
  version: String.t() | nil
}

A span struct containing all span attributes.

The :id is auto-generated if not provided. The :start_time defaults to the current UTC time. The :end_time is set when end_span/1 is called.

Functions

end_span(span)

@spec end_span(t()) :: t()

Ends the span by setting its end time to now.

This is equivalent to update(span, end_time: DateTime.utc_now()).

Examples

iex> trace = Langfuse.Trace.new(name: "test")
iex> span = Langfuse.Span.new(trace, name: "process")
iex> span.end_time
nil
iex> span = Langfuse.Span.end_span(span)
iex> span.end_time != nil
true

get_id(span)

@spec get_id(t()) :: String.t()

Returns the span ID.

Examples

iex> trace = Langfuse.Trace.new(name: "test")
iex> span = Langfuse.Span.new(trace, name: "process", id: "span-123")
iex> Langfuse.Span.get_id(span)
"span-123"

get_trace_id(span)

@spec get_trace_id(t()) :: String.t()

Returns the trace ID that this span belongs to.

Examples

iex> trace = Langfuse.Trace.new(name: "test", id: "trace-456")
iex> span = Langfuse.Span.new(trace, name: "process")
iex> Langfuse.Span.get_trace_id(span)
"trace-456"

new(parent, opts)

@spec new(
  parent(),
  keyword()
) :: t()

Creates a new span and enqueues it for ingestion.

The span is created as a child of the given parent (trace or span). It is immediately queued for asynchronous delivery to Langfuse.

Options

  • :name - Name of the span (required)
  • :id - Custom span ID. Uses secure random hex if not provided.
  • :type - Observation type. Defaults to :span. See observation_type/0.
  • :input - Input data for the span.
  • :output - Output data for the span.
  • :metadata - Arbitrary metadata as a map.
  • :level - Log level: :debug, :default, :warning, or :error.
  • :status_message - Status description, useful for errors.
  • :start_time - Custom start time. Defaults to DateTime.utc_now/0.
  • :end_time - End time if already known.
  • :version - Application version string.

Examples

iex> trace = Langfuse.Trace.new(name: "test", id: "trace-1")
iex> span = Langfuse.Span.new(trace, name: "retrieval")
iex> span.name
"retrieval"
iex> span.trace_id
"trace-1"

iex> trace = Langfuse.Trace.new(name: "test")
iex> span = Langfuse.Span.new(trace,
...>   name: "process",
...>   input: %{query: "test"},
...>   level: :debug
...> )
iex> span.input
%{query: "test"}
iex> span.level
:debug

update(span, opts)

@spec update(
  t(),
  keyword()
) :: t()

Updates an existing span and enqueues the update for ingestion.

Only the fields provided in opts are updated. Other fields retain their current values.

Options

  • :name - Updated span name.
  • :input - Updated input data.
  • :output - Updated output data.
  • :metadata - Updated metadata map (replaces existing).
  • :level - Updated log level.
  • :status_message - Updated status description.
  • :end_time - End time. Use end_span/1 to set automatically.
  • :version - Updated version string.

Examples

iex> trace = Langfuse.Trace.new(name: "test")
iex> span = Langfuse.Span.new(trace, name: "process")
iex> span = Langfuse.Span.update(span, output: %{result: "done"})
iex> span.output
%{result: "done"}

iex> trace = Langfuse.Trace.new(name: "test")
iex> span = Langfuse.Span.new(trace, name: "process")
iex> span = Langfuse.Span.update(span,
...>   level: :error,
...>   status_message: "Failed to process"
...> )
iex> span.level
:error