Module: Sentiero::Fingerprint

Defined in:
lib/sentiero/fingerprint.rb

Overview

Computes the grouping fingerprint for an exception occurrence. The normalization regexes are deliberately linear-time (simple character classes with a single quantifier, no nesting) so untrusted backtraces cannot trigger catastrophic backtracking (ReDoS).

Constant Summary collapse

MAX_FRAMES =

Only the top frames drive grouping (deeper frames vary by call site).

5
MAX_FRAME_LENGTH =
1000

Class Method Summary collapse

Class Method Details

.compute(exception_class:, backtrace:, project:) ⇒ Object



17
18
19
20
21
# File 'lib/sentiero/fingerprint.rb', line 17

def compute(exception_class:, backtrace:, project:)
  frames = Array(backtrace).first(MAX_FRAMES).map { |frame| normalize_frame(frame.to_s) }
  input = "#{project}\n#{exception_class}\n#{frames.join("\n")}"
  Digest::SHA256.hexdigest(input)[0, 40]
end

.normalize_frame(frame) ⇒ Object

Strips per-occurrence noise (memory addresses, line numbers). Digits inside identifiers (e.g. step_1, V2::Api) are preserved so distinct methods do not collapse into one group.



26
27
28
29
30
31
32
# File 'lib/sentiero/fingerprint.rb', line 26

def normalize_frame(frame)
  frame = frame[0, MAX_FRAME_LENGTH].strip
  frame
    .gsub(/0x[0-9a-fA-F]+/, "0xHEX") # memory addresses
    .gsub(/:[0-9]+(?=:in )/, ":N") # `path:LINE:in 'method'`
    .gsub(/:[0-9]+\z/, ":N") # `path:LINE` (top-level frame, no method)
end