Module: RailsOtelContext

Defined in:
lib/rails_otel_context.rb,
lib/rails_otel_context/railtie.rb,
lib/rails_otel_context/version.rb,
lib/rails_otel_context/adapters.rb,
lib/rails_otel_context/adapters/pg.rb,
lib/rails_otel_context/body_capture.rb,
lib/rails_otel_context/configuration.rb,
lib/rails_otel_context/frame_context.rb,
lib/rails_otel_context/adapters/redis.rb,
lib/rails_otel_context/adapters/mysql2.rb,
lib/rails_otel_context/request_context.rb,
lib/rails_otel_context/source_location.rb,
lib/rails_otel_context/adapters/trilogy.rb,
lib/rails_otel_context/adapters/clickhouse.rb,
lib/rails_otel_context/activerecord_context.rb,
lib/rails_otel_context/call_context_processor.rb,
lib/rails_otel_context/adapters/connection_pool.rb

Defined Under Namespace

Modules: ActiveRecordContext, Adapters, FrameContext, Frameable, RequestContext, SourceLocation Classes: BodyCapture, CallContextProcessor, Configuration, Railtie

Constant Summary collapse

VERSION =
'0.9.10'

Class Method Summary collapse

Class Method Details

.configurationObject



22
23
24
# File 'lib/rails_otel_context.rb', line 22

def configuration
  @configuration ||= Configuration.new
end

.configure {|configuration| ... } ⇒ Object

Yields:



26
27
28
# File 'lib/rails_otel_context.rb', line 26

def configure
  yield(configuration)
end

.install!(app_root: nil) ⇒ Object

Full installation: registers all Rails hooks (AR adapters, around_action, around_perform) and the CallContextProcessor. Safe to call from a config/initializers file when the gem is loaded with require: false:

# config/initializers/opentelemetry.rb
return unless ENV['ENABLE_OTLP']
require 'rails_otel_context'
RailsOtelContext.configure { |c| ... }
RailsOtelContext.install!

The Railtie calls this automatically via after_initialize, so apps that let Bundler auto-require the gem do not need to call it explicitly. Safe to call multiple times — idempotent.



47
48
49
50
51
# File 'lib/rails_otel_context.rb', line 47

def install!(app_root: nil)
  app_root ||= Rails.root if defined?(Rails)
  register_hooks!(app_root) unless @hooks_installed
  install_processor!
end

.install_processor!Object

Registers CallContextProcessor with the OTel tracer_provider. Called automatically by install!. Safe to call manually after a second OpenTelemetry::SDK.configure call replaces the tracer_provider — the method detects the provider change and re-registers automatically:

RailsOtelContext.install!          # hooks up AR/request context
OpenTelemetry::SDK.configure {  } # second SDK configure (replaces provider)
RailsOtelContext.install_processor! # re-registers on the new provider

Idempotent per provider instance: re-registers when OpenTelemetry::SDK.configure is called again (which replaces the global tracer_provider with a new object), but skips registration when called multiple times against the same provider.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/rails_otel_context.rb', line 65

def install_processor!
  return unless defined?(Rails) && Rails.root
  return unless defined?(OpenTelemetry)

  # Capture once: tracer_provider is a global that SDK.configure can replace
  # on another thread. A single local read makes the rest of the method consistent.
  provider = OpenTelemetry.tracer_provider
  return unless provider.respond_to?(:add_span_processor)

  # Use object identity, not a boolean flag. SDK.configure creates a new
  # TracerProvider instance each time, so equal? detects provider replacement
  # and triggers re-registration, while guarding against double-registration
  # on the same provider.
  return if @processor_registered_on.equal?(provider)

  @processor_registered_on = provider
  processor = RailsOtelContext::CallContextProcessor.new(app_root: Rails.root)
  provider.add_span_processor(processor)
end

.pop_frameObject



131
132
133
# File 'lib/rails_otel_context.rb', line 131

def pop_frame
  FrameContext.pop
end

.push_frame(class_name:, method_name:) ⇒ Object



127
128
129
# File 'lib/rails_otel_context.rb', line 127

def push_frame(class_name:, method_name:)
  FrameContext.push(class_name: class_name, method_name: method_name)
end

.reset_configuration!Object



30
31
32
# File 'lib/rails_otel_context.rb', line 30

def reset_configuration!
  @configuration = Configuration.new
end

.with_frame(class_name:, method_name:, &block) ⇒ Object

Convenience delegates to FrameContext — see FrameContext for full docs.



123
124
125
# File 'lib/rails_otel_context.rb', line 123

def with_frame(class_name:, method_name:, &block)
  FrameContext.with_frame(class_name: class_name, method_name: method_name, &block)
end