Module: RailsOtelContext::FrameContext
- Defined in:
- lib/rails_otel_context/frame_context.rb
Overview
Thread-local storage for explicitly pushed call-frame context.
The default code.namespace / code.function attributes are extracted by walking the Ruby call stack on every span start. That works, but costs O(stack depth) object allocations per span. FrameContext eliminates the walk by letting call sites push their class+method once at entry:
RailsOtelContext::FrameContext.with_frame(class_name: 'OrdersController',
method_name: 'create') do
# every span created inside here reads the pushed frame — no stack walk
end
The Railtie automatically installs an around_action that pushes the controller frame for all controller actions. For jobs, service objects, or any other code that creates spans, use with_frame directly or include RailsOtelContext::Frameable.
The pushed frame is a fallback for the span processor: the stack walk still runs when no frame is pushed, so existing behavior is preserved.
Class Method Summary collapse
-
.current ⇒ Object
Returns the currently pushed frame hash, or nil.
-
.pop ⇒ Object
(also: clear!)
Clears the pushed frame.
-
.push(class_name:, method_name:) ⇒ Object
Manual push without a block.
-
.with_frame(class_name:, method_name:) ⇒ Object
Pushes
class_name/method_namefor the duration of the block, restoring whatever was pushed before (supports nesting).
Class Method Details
.current ⇒ Object
Returns the currently pushed frame hash, or nil.
49 50 51 |
# File 'lib/rails_otel_context/frame_context.rb', line 49 def current Thread.current[FRAME_KEY] end |
.pop ⇒ Object Also known as: clear!
Clears the pushed frame. Pair with push in an ensure block.
44 45 46 |
# File 'lib/rails_otel_context/frame_context.rb', line 44 def pop Thread.current[FRAME_KEY] = nil end |
.push(class_name:, method_name:) ⇒ Object
Manual push without a block. Caller must call pop in an ensure.
39 40 41 |
# File 'lib/rails_otel_context/frame_context.rb', line 39 def push(class_name:, method_name:) Thread.current[FRAME_KEY] = { class_name: class_name, method_name: method_name }.freeze end |
.with_frame(class_name:, method_name:) ⇒ Object
Pushes class_name/method_name for the duration of the block, restoring whatever was pushed before (supports nesting).
30 31 32 33 34 35 36 |
# File 'lib/rails_otel_context/frame_context.rb', line 30 def with_frame(class_name:, method_name:) prev = Thread.current[FRAME_KEY] Thread.current[FRAME_KEY] = { class_name: class_name, method_name: method_name }.freeze yield ensure Thread.current[FRAME_KEY] = prev end |