Langfuse.OpenTelemetry.SpanProcessor (Langfuse v0.2.0)

View Source

OpenTelemetry span processor that exports spans to Langfuse.

This module implements the :otel_span_processor behaviour, intercepting OpenTelemetry spans and converting them to Langfuse observations. Spans are automatically categorized as traces, spans, or generations based on their attributes.

Setup

Add the processor to your OpenTelemetry SDK configuration:

# In config/runtime.exs
config :opentelemetry,
  processors: [
    {:otel_batch_processor, %{}},
    {Langfuse.OpenTelemetry.SpanProcessor, %{}}
  ]

Or programmatically:

:otel_batch_processor.set_exporter(:otel_exporter_otlp)
Langfuse.OpenTelemetry.SpanProcessor.start_link()

Span to Observation Mapping

OpenTelemetry spans are converted to Langfuse observations based on attributes:

  • Spans with gen_ai.* or model attributes become generations
  • Root spans (no parent) create a new trace + root span
  • Child spans become nested spans under their parent

Attribute Mapping

The processor maps OpenTelemetry attributes to Langfuse fields following the GenAI semantic conventions. See Langfuse.OpenTelemetry.AttributeMapper for the complete mapping reference.

Configuration

The processor accepts these options in its config map:

  • :enabled - Whether to process spans (default: true)
  • :filter_fn - Optional function (span) -> boolean to filter spans

Example

# Filter to only process LLM-related spans
config :opentelemetry,
  processors: [
    {Langfuse.OpenTelemetry.SpanProcessor, %{
      filter_fn: fn span ->
        attrs = elem(span, 7)
        Map.has_key?(attrs, "gen_ai.request.model")
      end
    }}
  ]

Summary

Types

Processor configuration options.

Types

config()

@type config() :: %{
  optional(:enabled) => boolean(),
  optional(:filter_fn) => (term() -> boolean())
}

Processor configuration options.