Module: Langfuse
- Defined in:
- lib/langfuse.rb,
lib/langfuse.rb,
lib/langfuse/types.rb,
lib/langfuse/client.rb,
lib/langfuse/config.rb,
lib/langfuse/masking.rb,
lib/langfuse/version.rb,
lib/langfuse/read_api.rb,
lib/langfuse/sampling.rb,
lib/langfuse/trace_id.rb,
lib/langfuse/exit_hook.rb,
lib/langfuse/api_client.rb,
lib/langfuse/evaluation.rb,
lib/langfuse/otel_setup.rb,
lib/langfuse/fork_safety.rb,
lib/langfuse/item_result.rb,
lib/langfuse/propagation.rb,
lib/langfuse/score_value.rb,
lib/langfuse/span_filter.rb,
lib/langfuse/cache_warmer.rb,
lib/langfuse/observations.rb,
lib/langfuse/prompt_cache.rb,
lib/langfuse/score_client.rb,
lib/langfuse/dataset_client.rb,
lib/langfuse/span_processor.rb,
lib/langfuse/cache_constants.rb,
lib/langfuse/experiment_item.rb,
lib/langfuse/otel_attributes.rb,
lib/langfuse/otel_span_batch.rb,
lib/langfuse/prompt_renderer.rb,
lib/langfuse/masking_exporter.rb,
lib/langfuse/prompt_variables.rb,
lib/langfuse/timestamp_parser.rb,
lib/langfuse/traced_execution.rb,
lib/langfuse/app_root_tracking.rb,
lib/langfuse/experiment_result.rb,
lib/langfuse/experiment_runner.rb,
lib/langfuse/otel_span_masking.rb,
lib/langfuse/chat_prompt_client.rb,
lib/langfuse/text_prompt_client.rb,
lib/langfuse/trace_export_guard.rb,
lib/langfuse/dataset_item_client.rb,
lib/langfuse/pending_score_queue.rb,
lib/langfuse/prompt_cache_events.rb,
lib/langfuse/prompt_fetch_result.rb,
lib/langfuse/rails_cache_adapter.rb,
lib/langfuse/experiment_attributes.rb,
lib/langfuse/stale_while_revalidate.rb,
lib/langfuse/otel_span_patch_applier.rb,
lib/langfuse/prompt_cache_coordinator.rb,
lib/langfuse/resilient_metrics_reporter.rb
Overview
rubocop:disable Metrics/ModuleLength
Defined Under Namespace
Modules: AppRootTracking, CacheBackend, CacheSource, CacheStatus, ExitHook, ExperimentAttributes, ForkSafety, Masking, ModelSetters, OtelAttributes, OtelSetup, PromptCacheEvents, Propagation, ReadApi, Sampling, ScoreValue, StaleWhileRevalidate, TimestampParser, TraceId, TracedExecution, Types Classes: Agent, ApiClient, ApiError, BaseObservation, BatchDeliveryError, CacheWarmer, CacheWarmingError, Chain, ChatPromptClient, Client, Config, ConfigurationError, DatasetClient, DatasetItemClient, Embedding, Error, Evaluation, Evaluator, Event, ExperimentItem, ExperimentResult, ExperimentRunner, Generation, Guardrail, ItemResult, MaskOtelSpansParams, MaskOtelSpansResult, MaskingExporter, NotFoundError, OtelSpanData, OtelSpanIdentifier, OtelSpanPatch, PendingScoreQueue, PromptCache, PromptCacheCoordinator, PromptCacheKey, PromptFetchResult, PromptRenderer, PromptVariables, RailsCacheAdapter, ResilientMetricsReporter, Retriever, ScoreClient, Span, SpanProcessor, TextPromptClient, Tool, TraceExportGuard, UnauthorizedError
Constant Summary collapse
- FLUSH_TIMEOUT =
Default timeout (in seconds) for flushing traces during experiment runs.
5- OBSERVATION_TYPE_REGISTRY =
Registry mapping observation type strings to their wrapper classes
{ OBSERVATION_TYPES[:generation] => Generation, OBSERVATION_TYPES[:embedding] => Embedding, OBSERVATION_TYPES[:event] => Event, OBSERVATION_TYPES[:agent] => Agent, OBSERVATION_TYPES[:tool] => Tool, OBSERVATION_TYPES[:chain] => Chain, OBSERVATION_TYPES[:retriever] => Retriever, OBSERVATION_TYPES[:evaluator] => Evaluator, OBSERVATION_TYPES[:guardrail] => Guardrail, OBSERVATION_TYPES[:span] => Span }.freeze
- VERSION =
"0.12.3"- LANGFUSE_TRACER_NAME =
Instrumentation scope name used by module-level Langfuse tracing.
"langfuse-rb"- KNOWN_LLM_INSTRUMENTATION_SCOPE_PREFIXES =
Conservative allowlist of instrumentation scope prefixes that clearly belong to LLM workflows.
[ LANGFUSE_TRACER_NAME, "agent_framework", "ai", "haystack", "langsmith", "litellm", "openinference", "opentelemetry.instrumentation.anthropic", "strands-agents", "vllm" ].freeze
- OBSERVATION_TYPES =
Observation type constants
{ span: "span", generation: "generation", embedding: "embedding", event: "event", agent: "agent", tool: "tool", chain: "chain", retriever: "retriever", evaluator: "evaluator", guardrail: "guardrail" }.freeze
Class Method Summary collapse
-
.client ⇒ Client
Returns the global singleton client.
-
.configuration ⇒ Config
Returns the global configuration object.
-
.configuration=(configuration) ⇒ Config
Set the global configuration object and start its process-exit lifecycle.
-
.configure {|Config| ... } ⇒ Config
Configure Langfuse globally.
-
.configured? ⇒ Boolean
Check whether the local configuration can construct a client.
-
.create_score(name:, value:, id: nil, trace_id: nil, session_id: nil, observation_id: nil, comment: nil, metadata: nil, environment: nil, data_type: :numeric, dataset_run_id: nil, config_id: nil) ⇒ void
Create a score event and queue it for batching.
-
.create_score!(name:, value:, id: nil, trace_id: nil, session_id: nil, observation_id: nil, comment: nil, metadata: nil, environment: nil, data_type: :numeric, dataset_run_id: nil, config_id: nil) ⇒ String?
Create a score immediately through the Scores API.
-
.create_trace_id(seed: nil) ⇒ String
Generate a trace ID (deterministic when seeded, random otherwise).
-
.default_export_span?(span) ⇒ Boolean
(also: is_default_export_span)
Return whether a span should be exported when no custom filter is configured.
-
.flush_scores ⇒ void
Force flush all queued score events.
-
.force_flush(timeout: 30) ⇒ void
Force flush all pending traces.
-
.genai_span?(span) ⇒ Boolean
(also: is_genai_span)
Return whether the span contains
gen_ai.*attributes. -
.known_llm_instrumentor?(span) ⇒ Boolean
(also: is_known_llm_instrumentor)
Return whether the span came from a known LLM instrumentation scope.
-
.langfuse_span?(span) ⇒ Boolean
(also: is_langfuse_span)
Return whether the span was created by Langfuse's tracer.
-
.observe(name, attrs = {}, as_type: :span, trace_id: nil, **kwargs) {|observation| ... } ⇒ BaseObservation, Object
User-facing convenience method for creating root observations.
-
.propagate_attributes(user_id: nil, session_id: nil, metadata: nil, version: nil, tags: nil, trace_name: nil, release: nil, environment: nil, as_baggage: false) { ... } ⇒ Object
Propagate trace-level attributes to all spans created within this context.
-
.reset! ⇒ void
Reset global configuration and client (useful for testing).
-
.score_active_observation(name:, value:, comment: nil, metadata: nil, data_type: :numeric) ⇒ void
Create a score for the currently active observation (from OTel span).
-
.score_active_trace(name:, value:, comment: nil, metadata: nil, data_type: :numeric) ⇒ void
Create a score for the currently active trace (from OTel span).
-
.shutdown(timeout: 30) ⇒ void
Shutdown Langfuse and flush any pending traces and scores.
-
.start_observation(name, attrs = {}, as_type: :span, trace_id: nil, parent_span_context: nil, start_time: nil, skip_validation: false) ⇒ BaseObservation
Creates a new observation (root or child).
-
.tracer_provider ⇒ OpenTelemetry::SDK::Trace::TracerProvider, OpenTelemetry::Trace::TracerProvider
Return Langfuse's internal tracer provider for explicit global OpenTelemetry installation.
Class Method Details
.client ⇒ Client
Returns the global singleton client
139 140 141 |
# File 'lib/langfuse.rb', line 139 def client @client ||= Client.new(configuration) end |
.configuration ⇒ Config
Returns the global configuration object
117 118 119 |
# File 'lib/langfuse.rb', line 117 def configuration @configuration ||= Config.new.tap { ExitHook.enable } end |
.configuration=(configuration) ⇒ Config
Set the global configuration object and start its process-exit lifecycle.
108 109 110 111 112 |
# File 'lib/langfuse.rb', line 108 def configuration=(configuration) reset! ExitHook.enable @configuration = configuration end |
.configure {|Config| ... } ⇒ Config
Configure Langfuse globally
131 132 133 134 |
# File 'lib/langfuse.rb', line 131 def configure yield(configuration) configuration end |
.configured? ⇒ Boolean
Check whether the local configuration can construct a client.
This method does not access the network or validate credentials.
148 149 150 151 152 153 154 155 156 157 158 |
# File 'lib/langfuse.rb', line 148 def configured? config = configuration return config.valid? if config.telemetry_enabled? config.validate_telemetry_disabled! true rescue ConfigurationError # Reading `configuration` builds it from the environment, which can fail # on its own before there is anything to validate. false end |
.create_score(name:, value:, id: nil, trace_id: nil, session_id: nil, observation_id: nil, comment: nil, metadata: nil, environment: nil, data_type: :numeric, dataset_run_id: nil, config_id: nil) ⇒ void
This method returns an undefined value.
Create a score event and queue it for batching
rubocop:disable Metrics/ParameterLists
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 |
# File 'lib/langfuse.rb', line 300 def create_score(name:, value:, id: nil, trace_id: nil, session_id: nil, observation_id: nil, comment: nil, metadata: nil, environment: nil, data_type: :numeric, dataset_run_id: nil, config_id: nil) client.create_score( name: name, value: value, id: id, trace_id: trace_id, session_id: session_id, observation_id: observation_id, comment: comment, metadata: , environment: environment, data_type: data_type, dataset_run_id: dataset_run_id, config_id: config_id ) end |
.create_score!(name:, value:, id: nil, trace_id: nil, session_id: nil, observation_id: nil, comment: nil, metadata: nil, environment: nil, data_type: :numeric, dataset_run_id: nil, config_id: nil) ⇒ String?
Create a score immediately through the Scores API. See Langfuse::ScoreClient#create!.
rubocop:disable Metrics/ParameterLists
341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/langfuse.rb', line 341 def create_score!(name:, value:, id: nil, trace_id: nil, session_id: nil, observation_id: nil, comment: nil, metadata: nil, environment: nil, data_type: :numeric, dataset_run_id: nil, config_id: nil) client.create_score!( name: name, value: value, id: id, trace_id: trace_id, session_id: session_id, observation_id: observation_id, comment: comment, metadata: , environment: environment, data_type: data_type, dataset_run_id: dataset_run_id, config_id: config_id ) end |
.create_trace_id(seed: nil) ⇒ String
Avoid PII or secrets as seeds. See Langfuse::TraceId.create for details.
Generate a trace ID (deterministic when seeded, random otherwise).
Use this to correlate Langfuse traces with external identifiers. The same seed always produces the same trace ID across the Ruby, Python, and JS SDKs (SHA-256 of the seed, first 16 bytes, as 32 hex chars).
438 439 440 |
# File 'lib/langfuse.rb', line 438 def create_trace_id(seed: nil) TraceId.create(seed: seed) end |
.default_export_span?(span) ⇒ Boolean Also known as: is_default_export_span
Return whether a span should be exported when no custom filter is configured.
65 66 67 |
# File 'lib/langfuse/span_filter.rb', line 65 def default_export_span?(span) langfuse_span?(span) || genai_span?(span) || known_llm_instrumentor?(span) end |
.flush_scores ⇒ void
This method returns an undefined value.
Force flush all queued score events
Sends all queued score events to the API immediately.
420 421 422 |
# File 'lib/langfuse.rb', line 420 def flush_scores client.flush_scores if @client end |
.force_flush(timeout: 30) ⇒ void
This method returns an undefined value.
Force flush all pending traces
202 203 204 |
# File 'lib/langfuse.rb', line 202 def force_flush(timeout: 30) OtelSetup.force_flush(timeout: timeout) end |
.genai_span?(span) ⇒ Boolean Also known as: is_genai_span
Return whether the span contains gen_ai.* attributes.
39 40 41 42 43 44 |
# File 'lib/langfuse/span_filter.rb', line 39 def genai_span?(span) attributes = span.attributes return false unless attributes attributes.keys.any? { |key| key.is_a?(String) && key.start_with?("gen_ai.") } end |
.known_llm_instrumentor?(span) ⇒ Boolean Also known as: is_known_llm_instrumentor
Return whether the span came from a known LLM instrumentation scope.
50 51 52 53 54 55 56 57 58 59 |
# File 'lib/langfuse/span_filter.rb', line 50 def known_llm_instrumentor?(span) scope_name = instrumentation_scope_name(span) return false unless scope_name return true if KNOWN_LLM_INSTRUMENTATION_SCOPE_PREFIXES.include?(scope_name) KNOWN_LLM_INSTRUMENTATION_SCOPE_DOTTED_PREFIXES.any? do |dotted_prefix| scope_name.start_with?(dotted_prefix) end end |
.langfuse_span?(span) ⇒ Boolean Also known as: is_langfuse_span
Return whether the span was created by Langfuse's tracer.
31 32 33 |
# File 'lib/langfuse/span_filter.rb', line 31 def langfuse_span?(span) instrumentation_scope_name(span) == LANGFUSE_TRACER_NAME end |
.observe(name, attrs = {}, as_type: :span, trace_id: nil, **kwargs) {|observation| ... } ⇒ BaseObservation, Object
User-facing convenience method for creating root observations
538 539 540 541 542 543 544 |
# File 'lib/langfuse.rb', line 538 def observe(name, attrs = {}, as_type: :span, trace_id: nil, **kwargs, &block) merged_attrs = attrs.to_h.merge(kwargs) observation = start_observation(name, merged_attrs, as_type: as_type, trace_id: trace_id) return observation unless block observation.send(:run_in_context, &block) end |
.propagate_attributes(user_id: nil, session_id: nil, metadata: nil, version: nil, tags: nil, trace_name: nil, release: nil, environment: nil, as_baggage: false) { ... } ⇒ Object
Propagate trace-level attributes to all spans created within this context.
This method sets attributes on the currently active span AND automatically propagates them to all new child spans created within the block. This is the recommended way to set trace-level attributes like user_id, session_id, and metadata dimensions that should be consistently applied across all observations in a trace.
IMPORTANT: Call this as early as possible within your trace/workflow. Only the currently active span and spans created after entering this context will have these attributes. Pre-existing spans will NOT be retroactively updated.
rubocop:disable Metrics/ParameterLists
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/langfuse.rb', line 257 def propagate_attributes(user_id: nil, session_id: nil, metadata: nil, version: nil, tags: nil, trace_name: nil, release: nil, environment: nil, as_baggage: false, &) Propagation.propagate_attributes( user_id: user_id, session_id: session_id, metadata: , version: version, tags: , trace_name: trace_name, release: release, environment: environment, as_baggage: as_baggage, & ) end |
.reset! ⇒ void
This method returns an undefined value.
Reset global configuration and client (useful for testing)
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 |
# File 'lib/langfuse.rb', line 445 def reset! ExitHook.disable client.shutdown if @client OtelSetup.shutdown(timeout: 5) if OtelSetup.initialized? @configuration = nil @client = nil @noop_tracer = nil @noop_tracer_provider = nil @emitted_warnings = nil rescue StandardError # Ignore shutdown errors during reset (e.g., in tests) @configuration = nil @client = nil @noop_tracer = nil @noop_tracer_provider = nil @emitted_warnings = nil end |
.score_active_observation(name:, value:, comment: nil, metadata: nil, data_type: :numeric) ⇒ void
This method returns an undefined value.
Create a score for the currently active observation (from OTel span)
Extracts observation_id and trace_id from the active OpenTelemetry span.
376 377 378 379 380 381 382 383 384 |
# File 'lib/langfuse.rb', line 376 def score_active_observation(name:, value:, comment: nil, metadata: nil, data_type: :numeric) client.score_active_observation( name: name, value: value, comment: comment, metadata: , data_type: data_type ) end |
.score_active_trace(name:, value:, comment: nil, metadata: nil, data_type: :numeric) ⇒ void
This method returns an undefined value.
Create a score for the currently active trace (from OTel span)
Extracts trace_id from the active OpenTelemetry span.
402 403 404 405 406 407 408 409 410 |
# File 'lib/langfuse.rb', line 402 def score_active_trace(name:, value:, comment: nil, metadata: nil, data_type: :numeric) client.score_active_trace( name: name, value: value, comment: comment, metadata: , data_type: data_type ) end |
.shutdown(timeout: 30) ⇒ void
This method returns an undefined value.
Shutdown Langfuse and flush any pending traces and scores
Normal process exit calls this automatically. Use it directly when the application needs an earlier, explicit shutdown boundary.
192 193 194 195 196 |
# File 'lib/langfuse.rb', line 192 def shutdown(timeout: 30) ExitHook.disable client.shutdown if @client OtelSetup.shutdown(timeout: timeout) end |
.start_observation(name, attrs = {}, as_type: :span, trace_id: nil, parent_span_context: nil, start_time: nil, skip_validation: false) ⇒ BaseObservation
Creates a new observation (root or child)
This is the module-level factory method that creates observations of any type. It can create root observations (when parent_span_context is nil) or child observations (when parent_span_context is provided).
rubocop:disable Metrics/ParameterLists
493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
# File 'lib/langfuse.rb', line 493 def start_observation(name, attrs = {}, as_type: :span, trace_id: nil, parent_span_context: nil, start_time: nil, skip_validation: false) parent_span_context = resolve_trace_context(trace_id, parent_span_context) type_str = as_type.to_s validate_observation_type!(as_type, type_str) unless skip_validation otel_tracer = otel_tracer() otel_span = create_otel_span( name: name, start_time: start_time, parent_span_context: parent_span_context, otel_tracer: otel_tracer ) apply_observation_attributes(otel_span, type_str, attrs) observation = wrap_otel_span(otel_span, type_str, otel_tracer) # Events auto-end immediately when created observation.end if type_str == OBSERVATION_TYPES[:event] observation end |
.tracer_provider ⇒ OpenTelemetry::SDK::Trace::TracerProvider, OpenTelemetry::Trace::TracerProvider
Return Langfuse's internal tracer provider for explicit global OpenTelemetry installation.
172 173 174 175 176 177 178 179 |
# File 'lib/langfuse.rb', line 172 def tracer_provider return noop_tracer_provider unless configuration.trace_export_enabled? OtelSetup.setup(configuration) unless OtelSetup.initialized? OtelSetup.tracer_provider rescue ConfigurationError => e raise ConfigurationError, (e.) end |