Module: RailsOtelContext::SourceLocation

Included in:
CallContextProcessor
Defined in:
lib/rails_otel_context/source_location.rb

Overview

Shared call-site extraction for DB adapters and CallContextProcessor.

Every adapter (Trilogy, PG, MySQL2) includes this on class << self and calls call_site_for_app after (or around) the query. Because the adapter is closer to user code in the call stack than CallContextProcessor#on_start is, the walk reaches the app frame in fewer iterations — and returns class + method + filepath + lineno in one shot.

CallContextProcessor includes this too so it can share the same logic in its stack-walk fallback path.

Instance Method Summary collapse

Instance Method Details

#apply_call_site_to_span(span, site) ⇒ Object

Applies all four call-site attributes to span in one go.



40
41
42
43
44
45
46
47
# File 'lib/rails_otel_context/source_location.rb', line 40

def apply_call_site_to_span(span, site)
  return unless site && span.context.valid?

  span.set_attribute('code.namespace', site[:class_name])
  span.set_attribute('code.function',  site[:method_name]) if site[:method_name]
  span.set_attribute('code.filepath',  site[:filepath])
  span.set_attribute('code.lineno',    site[:lineno]) if site[:lineno]
end

#apply_source_to_span(span, source) ⇒ Object

Legacy helper — use apply_call_site_to_span for new code.



67
68
69
70
71
72
# File 'lib/rails_otel_context/source_location.rb', line 67

def apply_source_to_span(span, source)
  return unless source

  span.set_attribute('code.filepath', source[0])
  span.set_attribute('code.lineno',   source[1])
end

#call_site_for_appObject

Returns the first app-code frame as a Hash:

{ class_name:, method_name:, filepath:, lineno: }

Returns nil when no app frame is found or the feature is unavailable. Requires app_root to be defined on the including object.



25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/rails_otel_context/source_location.rb', line 25

def call_site_for_app
  return unless Thread.respond_to?(:each_caller_location)

  Thread.each_caller_location do |location|
    path = location.absolute_path || location.path
    next unless path&.start_with?(app_root)
    next if path.include?('/gems/')

    return build_call_site(location, path)
  end

  nil
end

#source_location_for_appObject

Legacy helper kept for Redis and ClickHouse adapters that only need filepath + lineno. Migrate those adapters to call_site_for_app + apply_call_site_to_span to remove this.



51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rails_otel_context/source_location.rb', line 51

def source_location_for_app
  return unless Thread.respond_to?(:each_caller_location)

  prefix = app_root_prefix
  Thread.each_caller_location do |location|
    path = location.absolute_path || location.path
    next unless path&.start_with?(app_root)
    next if path.include?('/gems/')

    return [path.delete_prefix(prefix), location.lineno]
  end

  nil
end