Class: OpenTrace::InstrumentationContext

Inherits:
Object
  • Object
show all
Defined in:
lib/opentrace/instrumentation_context.rb

Constant Summary collapse

FIBER_KEY =
:opentrace_buffer

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.capture_rulesObject

Optional capture rules instance. Set via configuration.



128
129
130
# File 'lib/opentrace/instrumentation_context.rb', line 128

def capture_rules
  @capture_rules
end

Class Method Details

.active?Boolean

Returns true if there is a buffer on the current Fiber.

Returns:

  • (Boolean)


93
94
95
# File 'lib/opentrace/instrumentation_context.rb', line 93

def active?
  !Fiber[FIBER_KEY].nil?
end

.buffer_poolObject

── Singleton resources (lazy-initialized) ──



99
100
101
102
103
104
105
# File 'lib/opentrace/instrumentation_context.rb', line 99

def buffer_pool
  cfg = active_config
  @buffer_pool ||= BufferPool.new(
    max_buffer_bytes: cfg.max_buffer_bytes,
    max_audit_events: cfg.audit_max_events_per_request
  )
end

.configure!(config) ⇒ Object



112
113
114
115
116
117
# File 'lib/opentrace/instrumentation_context.rb', line 112

def configure!(config)
  @config = config
  @buffer_pool = nil
  @memory_guard = nil
  @capture_rules = config.capture_rules_block ? CaptureRules.new(&config.capture_rules_block) : nil
end

.current_bufferObject

Returns the current Fiber’s RequestBuffer, or nil.



88
89
90
# File 'lib/opentrace/instrumentation_context.rb', line 88

def current_buffer
  Fiber[FIBER_KEY]
end

.memory_guardObject



107
108
109
110
# File 'lib/opentrace/instrumentation_context.rb', line 107

def memory_guard
  cfg = active_config
  @memory_guard ||= MemoryGuard.new(max_total_bytes: cfg.max_total_buffer_bytes)
end

.reset!Object

Reset singletons (for testing).



120
121
122
123
124
125
# File 'lib/opentrace/instrumentation_context.rb', line 120

def reset!
  @config = nil
  @buffer_pool = nil
  @memory_guard = nil
  @capture_rules = nil
end

.setup(env: nil, job: nil) ⇒ Object

── Setup ──

Initializes a capture context for the current Fiber. Called at the start of a request (with env:) or job (with job:).

Checks out a RequestBuffer from the global BufferPool, sets it on the current Fiber, and marks the event_type.

Returns the buffer (for callers that need it).



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/opentrace/instrumentation_context.rb', line 22

def setup(env: nil, job: nil)
  buf = buffer_pool.checkout
  allocation_bytes = buf.byte_size

  unless memory_guard.allocate(allocation_bytes)
    buffer_pool.checkin(buf)
    return nil
  end

  buf.event_type = if env
                     :http_request
                   elsif job
                     :job_perform
                   end

  Fiber[:opentrace_buffer_allocation_bytes] = allocation_bytes
  Fiber[FIBER_KEY] = buf
  buf
end

.teardown(status: nil, duration_ms: nil, error: false) ⇒ Object

── Teardown ──

Finalizes the capture context. Resolves capture level (via CaptureRules if configured), applies MemoryGuard effective level, produces the document, checks the buffer back into the pool, and clears the Fiber local.

Returns the document Hash, or nil when capture resolves to :none. The caller is responsible for enqueueing.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/opentrace/instrumentation_context.rb', line 51

def teardown(status: nil, duration_ms: nil, error: false)
  buf = Fiber[FIBER_KEY]
  return nil unless buf

  begin
    # Resolve capture level
    capture_level = resolve_capture_level(
      buf, status: status, duration_ms: duration_ms, error: error
    )

    # Apply memory guard — may downgrade under pressure
    capture_level = memory_guard.effective_level(capture_level)
    return nil if capture_level == :none

    # Build domain overrides from capture rules (if configured)
    domain_overrides = configured_domain_overrides

    # Produce the document
    doc = buf.to_document(capture_level: capture_level, domain_overrides: domain_overrides)
    doc[:duration_ms] = duration_ms if duration_ms
    doc[:pending_explains] = Fiber[:opentrace_pending_explains] if Fiber[:opentrace_pending_explains]

    doc
  ensure
    allocation_bytes = Fiber[:opentrace_buffer_allocation_bytes].to_i
    memory_guard.release(allocation_bytes) if allocation_bytes.positive?

    # Return buffer to pool and clear Fiber local
    buffer_pool.checkin(buf)
    Fiber[FIBER_KEY] = nil
    Fiber[:opentrace_buffer_allocation_bytes] = nil
  end
end