Class: Skylight::Extensions::SourceLocation

Inherits:
Extension show all
Includes:
Util::Logging
Defined in:
lib/skylight/extensions/source_location.rb

Constant Summary collapse

META_KEYS =
%i[source_location source_file source_line].freeze
MAX_CALLER_DEPTH =
75

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Util::Logging

#config_for_logging, #debug, #error, #fmt, #info, #log, #log_context, #raise_on_error?, #t, #trace, #trace?, #warn

Constructor Details

#initializeSourceLocation

Returns a new instance of SourceLocation.



16
17
18
19
20
21
22
# File 'lib/skylight/extensions/source_location.rb', line 16

def initialize(*)
  super
  cache_size = (config[:source_location_cache_size] || 1000).to_i
  @caller_cache = Util::LruCache.new(cache_size)
  @instance_method_source_location_cache = Util::LruCache.new(cache_size)
  gem_require_trie # memoize this at startup
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



9
10
11
# File 'lib/skylight/extensions/source_location.rb', line 9

def config
  @config
end

Instance Method Details

#allowed_meta_keysObject



111
112
113
# File 'lib/skylight/extensions/source_location.rb', line 111

def allowed_meta_keys
  META_KEYS
end

#process_instrument_options(opts, meta) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/skylight/extensions/source_location.rb', line 34

def process_instrument_options(opts, meta)
  source_location = opts[:source_location] || opts[:meta]&.[](:source_location)
  source_file = opts[:source_file] || opts[:meta]&.[](:source_file)
  source_line = opts[:source_line] || opts[:meta]&.[](:source_line)
  source_name_hint, const_name, method_name =
    opts[:source_location_hint] || opts[:meta]&.[](:source_location_hint)
  instrument_location = opts[:sk_instrument_location]

  if source_location
    meta[:source_location] = source_location
  elsif source_name_hint
    source_location = dispatch_hinted_source_location(source_name_hint, const_name, method_name)
    meta[:source_file], meta[:source_line] = source_location
    meta.delete(:source_location_hint) if source_location
  elsif source_file
    meta[:source_file] = source_file
    meta[:source_line] = source_line
  elsif instrument_location && project_path?(instrument_location.absolute_path)
    meta[:source_file] = instrument_location.absolute_path
    meta[:source_line] = instrument_location.lineno
  else
    warn "Ignoring source_line without source_file" if source_line
    if (location = find_caller(cache_key: opts.hash))
      meta[:source_file] = location.absolute_path
      meta[:source_line] = location.lineno
    end
  end

  meta
end

#process_normalizer_meta(payload, meta, **opts) ⇒ Object



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

def process_normalizer_meta(payload, meta, **opts)
  if opts[:source_location] && (opts[:source_file] || opts[:source_line])
    warn "Found both source_location and source_file or source_line in normalizer\n" \
           "  location=#{opts[:source_location]}; file=#{opts[:source_file]}; line=#{opts[:source_line]}"
  end

  sl =
    if (source_name, constant_name, method_name = opts[:source_location_hint])
      dispatch_hinted_source_location(source_name, constant_name, method_name)
    elsif opts[:source_file]
      [opts[:source_file], opts[:source_line]]
    end

  sl ||= source_location(payload, meta, cache_key: opts[:cache_key])

  if sl
    trace("normalizer source_location=#{sl}")
    meta[:source_file], meta[:source_line] = sl
  end

  meta
end

#process_trace_meta(meta) ⇒ Object



24
25
26
27
28
29
30
31
32
# File 'lib/skylight/extensions/source_location.rb', line 24

def process_trace_meta(meta)
  unless meta[:source_location] || meta[:source_file]
    warn "Ignoring source_line without source_file" if meta[:source_line]
    if (location = find_caller)
      meta[:source_file] = location.absolute_path
      meta[:source_line] = location.lineno
    end
  end
end

#trace_preprocess_meta(meta) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/skylight/extensions/source_location.rb', line 88

def trace_preprocess_meta(meta)
  source_line = meta.delete(:source_line)
  source_file = meta.delete(:source_file)

  if meta[:source_location]
    if source_file || source_line
      warn "Found both source_location and source_file or source_line, using source_location\n" \
             "  location=#{meta[:source_location]}; file=#{source_file}; line=#{source_line}"
    end

    unless meta[:source_location].is_a?(String)
      warn "Found non-string value for source_location; skipping"
      meta.delete(:source_location)
    end
  elsif source_file
    meta[:source_location] = sanitize_source_location(source_file, source_line)
  elsif source_line
    warn "Ignoring source_line without source_file; source_line=#{source_line}"
  end

  trace("source_location=#{meta[:source_location]}") if meta[:source_location]
end