dead_bro 0.2.18 → 0.2.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/dead_bro/error_middleware.rb +39 -0
- data/lib/dead_bro/subscriber.rb +40 -0
- data/lib/dead_bro/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: edddcaa5684cac479f815b4d8e1a377e30f039c6ba910daa6f30b2322538c64c
|
|
4
|
+
data.tar.gz: 4841c2bcadcd841a61dafc79216e3324fa87a239dea2be7d3cce038934ba28cb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2dd9071e6620fad08ee1e700ac48199f1b3b62119e68a3d52b2b381eba6152e3a311d28bc64aeb81855a5adb9edacab73decc8ce4c71243eb71f8680cdd41cc1
|
|
7
|
+
data.tar.gz: 4a1319b9b8f32b56f24a76e4681b7c55fa7b299258b590bffee686fc82ee7d8ad642df890593bf6c62e049225d9dcfc364877fe2ebc20dd6db1262836e9fc1ac
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "digest"
|
|
3
4
|
require "rack"
|
|
4
5
|
|
|
5
6
|
module DeadBro
|
|
@@ -35,6 +36,8 @@ module DeadBro
|
|
|
35
36
|
exception_class: exception.class.name,
|
|
36
37
|
message: truncate(exception.message.to_s, 1000),
|
|
37
38
|
backtrace: safe_backtrace(exception),
|
|
39
|
+
fingerprint: compute_fingerprint(exception),
|
|
40
|
+
cause_chain: build_cause_chain(exception),
|
|
38
41
|
occurred_at: Time.now.utc.to_i,
|
|
39
42
|
rack:
|
|
40
43
|
{
|
|
@@ -67,6 +70,42 @@ module DeadBro
|
|
|
67
70
|
[]
|
|
68
71
|
end
|
|
69
72
|
|
|
73
|
+
def normalize_message(msg)
|
|
74
|
+
msg.to_s
|
|
75
|
+
.gsub(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i, "UUID")
|
|
76
|
+
.gsub(/\b\d+\b/, "N")
|
|
77
|
+
.gsub(/"[^"]*"/, '"?"')
|
|
78
|
+
.gsub(/'[^']*'/, "'?'")
|
|
79
|
+
.strip
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def compute_fingerprint(exception)
|
|
83
|
+
top_frame = Array(exception.backtrace).first.to_s.gsub(/:\d+:in /, ":N:in ")
|
|
84
|
+
input = "#{exception.class.name}|#{normalize_message(exception.message)}|#{top_frame}"
|
|
85
|
+
Digest::SHA256.hexdigest(input)[0, 16]
|
|
86
|
+
rescue
|
|
87
|
+
nil
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def build_cause_chain(exception)
|
|
91
|
+
return [] unless exception
|
|
92
|
+
chain = []
|
|
93
|
+
cause = exception.cause
|
|
94
|
+
depth = 0
|
|
95
|
+
while cause && depth < 5
|
|
96
|
+
chain << {
|
|
97
|
+
exception_class: cause.class.name,
|
|
98
|
+
message: truncate(cause.message.to_s, 500),
|
|
99
|
+
backtrace_top: Array(cause.backtrace).first(3)
|
|
100
|
+
}
|
|
101
|
+
cause = cause.cause
|
|
102
|
+
depth += 1
|
|
103
|
+
end
|
|
104
|
+
chain
|
|
105
|
+
rescue
|
|
106
|
+
[]
|
|
107
|
+
end
|
|
108
|
+
|
|
70
109
|
def safe_params(req)
|
|
71
110
|
return {} unless req
|
|
72
111
|
|
data/lib/dead_bro/subscriber.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "digest"
|
|
3
4
|
require "active_support/notifications"
|
|
4
5
|
|
|
5
6
|
module DeadBro
|
|
@@ -139,6 +140,8 @@ module DeadBro
|
|
|
139
140
|
exception_class: exception_class || exception_obj&.class&.name,
|
|
140
141
|
message: (exception_message || exception_obj&.message).to_s[0, 1000],
|
|
141
142
|
backtrace: backtrace,
|
|
143
|
+
fingerprint: compute_error_fingerprint(exception_obj),
|
|
144
|
+
cause_chain: build_cause_chain(exception_obj),
|
|
142
145
|
error: true,
|
|
143
146
|
logs: DeadBro.logger.logs
|
|
144
147
|
}
|
|
@@ -401,5 +404,42 @@ module DeadBro
|
|
|
401
404
|
rescue
|
|
402
405
|
nil
|
|
403
406
|
end
|
|
407
|
+
|
|
408
|
+
def self.normalize_error_message(msg)
|
|
409
|
+
msg.to_s
|
|
410
|
+
.gsub(/\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/i, "UUID")
|
|
411
|
+
.gsub(/\b\d+\b/, "N")
|
|
412
|
+
.gsub(/"[^"]*"/, '"?"')
|
|
413
|
+
.gsub(/'[^']*'/, "'?'")
|
|
414
|
+
.strip
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
def self.compute_error_fingerprint(exception)
|
|
418
|
+
return nil unless exception
|
|
419
|
+
top_frame = Array(exception.backtrace).first.to_s.gsub(/:\d+:in /, ":N:in ")
|
|
420
|
+
input = "#{exception.class.name}|#{normalize_error_message(exception.message)}|#{top_frame}"
|
|
421
|
+
Digest::SHA256.hexdigest(input)[0, 16]
|
|
422
|
+
rescue
|
|
423
|
+
nil
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
def self.build_cause_chain(exception)
|
|
427
|
+
return [] unless exception
|
|
428
|
+
chain = []
|
|
429
|
+
cause = exception.cause
|
|
430
|
+
depth = 0
|
|
431
|
+
while cause && depth < 5
|
|
432
|
+
chain << {
|
|
433
|
+
exception_class: cause.class.name,
|
|
434
|
+
message: cause.message.to_s[0, 500],
|
|
435
|
+
backtrace_top: Array(cause.backtrace).first(3)
|
|
436
|
+
}
|
|
437
|
+
cause = cause.cause
|
|
438
|
+
depth += 1
|
|
439
|
+
end
|
|
440
|
+
chain
|
|
441
|
+
rescue
|
|
442
|
+
[]
|
|
443
|
+
end
|
|
404
444
|
end
|
|
405
445
|
end
|
data/lib/dead_bro/version.rb
CHANGED