Module: PlatformSdk::Observability::Langfuse
- Defined in:
- lib/platform_sdk/observability/langfuse.rb,
lib/platform_sdk/observability/langfuse/recorder.rb,
lib/platform_sdk/observability/langfuse/coercions.rb,
lib/platform_sdk/observability/langfuse/traceable.rb,
lib/platform_sdk/observability/langfuse/spec_support.rb,
lib/platform_sdk/observability/langfuse/configuration.rb,
lib/platform_sdk/observability/langfuse/sidekiq_lifecycle.rb,
lib/platform_sdk/observability/langfuse/null_span_exporter.rb
Defined Under Namespace
Modules: Coercions, Recorder, SidekiqLifecycle, SpecSupport, Traceable Classes: Configuration, ConfigurationError, Error, NullSpanExporter
Constant Summary collapse
- OWNED_THREAD_LOCALS_KEY =
:platform_sdk_langfuse_owned_thread_locals
Class Attribute Summary collapse
-
.configuration ⇒ Object
readonly
Returns the value of attribute configuration.
Class Method Summary collapse
-
.clear_tracked_thread_locals! ⇒ Object
Clear every thread-local registered via ‘track_thread_local` on this thread, then drop the registry itself.
- .configure(app_name:, environment: nil, prompt_label: nil, exporter: nil) ⇒ Object
- .enabled? ⇒ Boolean
- .record_generation(**kwargs) ⇒ Object
- .reset! ⇒ Object
-
.set_trace_output(value) ⇒ Object
Set the trace-level output on the active parent span.
- .tracer ⇒ Object
-
.track_thread_local(*keys) ⇒ Object
Register thread-local keys that should be cleared at the next Traceable job boundary.
Class Attribute Details
.configuration ⇒ Object (readonly)
Returns the value of attribute configuration.
19 20 21 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 19 def configuration @configuration end |
Class Method Details
.clear_tracked_thread_locals! ⇒ Object
Clear every thread-local registered via ‘track_thread_local` on this thread, then drop the registry itself. Called from the Traceable wrapper’s ‘ensure` block.
113 114 115 116 117 118 119 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 113 def clear_tracked_thread_locals! owned = Thread.current[OWNED_THREAD_LOCALS_KEY] return unless owned owned.each { |k| Thread.current[k] = nil } Thread.current[OWNED_THREAD_LOCALS_KEY] = nil end |
.configure(app_name:, environment: nil, prompt_label: nil, exporter: nil) ⇒ Object
21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 21 def configure(app_name:, environment: nil, prompt_label: nil, exporter: nil) @configuration&.force_flush_and_shutdown @configuration = Configuration.new( app_name: app_name, environment: environment, prompt_label: prompt_label, exporter: exporter ) SidekiqLifecycle.install! if @configuration.enabled? @configuration end |
.enabled? ⇒ Boolean
33 34 35 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 33 def enabled? !@configuration.nil? && @configuration.enabled? end |
.record_generation(**kwargs) ⇒ Object
43 44 45 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 43 def record_generation(**kwargs) Recorder.record_generation(**kwargs) end |
.reset! ⇒ Object
85 86 87 88 89 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 85 def reset! @configuration&.force_flush_and_shutdown @configuration = nil SidekiqLifecycle.reset! end |
.set_trace_output(value) ⇒ Object
Set the trace-level output on the active parent span. Application code calls this from inside a Traceable job (or any block running under an active span) to record a meaningful summary of the job’s result.
Why this is opt-in rather than auto-captured from ‘perform`’s return value: Sidekiq’s ‘perform` return is incidental — it’s often nil, an AR transaction callback array, or otherwise unrelated to anything a human reading a trace would find useful. Only the application knows what’s meaningful (e.g. a generated record’s ID).
Example:
class MyJob
include Sidekiq::Job
include PlatformSdk::Observability::Langfuse::Traceable
def perform(args)
component = generate_component(args)
PlatformSdk::Observability::Langfuse.set_trace_output(
{ component_id: component.id, status: component.status }
)
end
end
No-ops when the SDK is disabled or no span is currently active. Never raises — observability failures must not break callers.
73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 73 def set_trace_output(value) return unless enabled? span = OpenTelemetry::Trace.current_span return unless span.context.valid? span.set_attribute('langfuse.trace.output', Recorder.stringify(value)) rescue StandardError, SystemStackError => e OpenTelemetry.handle_error(message: "Langfuse set_trace_output failed: #{e.class}: #{e.[0, 200]}") nil end |
.tracer ⇒ Object
37 38 39 40 41 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 37 def tracer return nil unless enabled? @configuration.tracer end |
.track_thread_local(*keys) ⇒ Object
Register thread-local keys that should be cleared at the next Traceable job boundary. Consumers call this when they store per-trace state on ‘Thread.current` (e.g. the ID of the last recorded message) so the value can’t leak into the next job that lands on this Sidekiq thread.
Example:
PlatformSdk::Observability::Langfuse.track_thread_local(:my_app_last_message_id)
Thread.current[:my_app_last_message_id] = msg.id
Compared to a name-prefix convention, this requires explicit opt-in (so consumers can’t accidentally have unrelated state zeroed) and is O(owned keys) instead of O(all thread locals).
104 105 106 107 108 |
# File 'lib/platform_sdk/observability/langfuse.rb', line 104 def track_thread_local(*keys) list = (Thread.current[OWNED_THREAD_LOCALS_KEY] ||= []) keys.each { |k| list << k unless list.include?(k) } nil end |