dontbugme 0.1.2 → 0.1.4
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/app/controllers/dontbugme/traces_controller.rb +1 -1
- data/app/views/dontbugme/traces/show.html.erb +1 -1
- data/app/views/layouts/dontbugme/application.html.erb +1 -0
- data/lib/dontbugme/config/routes.rb +2 -2
- data/lib/dontbugme/configuration.rb +4 -6
- data/lib/dontbugme/middleware/rack.rb +1 -0
- data/lib/dontbugme/middleware/sidekiq.rb +1 -0
- data/lib/dontbugme/span.rb +3 -1
- data/lib/dontbugme/store/async.rb +12 -0
- data/lib/dontbugme/store/memory.rb +5 -5
- data/lib/dontbugme/store/postgresql.rb +21 -21
- data/lib/dontbugme/store/sqlite.rb +4 -1
- data/lib/dontbugme/subscribers/action_mailer.rb +1 -1
- data/lib/dontbugme/subscribers/active_job.rb +1 -1
- data/lib/dontbugme/trace.rb +3 -2
- data/lib/dontbugme/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: f1bab13c641c7fb30659e5ed19ef54331355ae7239d722a585e094115b47a0a9
|
|
4
|
+
data.tar.gz: ab863ecd3c380117ae77c731b9a917795c0fa4bc89c0a6cbe2f0d780b5597b59
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a1b4ee5fdbd1a36898a712ce07ceca1016b487d9362a61745116172250eb9cecb905919d1b327f4c2ae4e3a6e0c66cf4c97e53b4f91e8247de658cc9621e5059
|
|
7
|
+
data.tar.gz: e033607a2dad279edd380e60ab2633fa940a8d04189bcb2c7b0289e99bf599b2d6ecada08b590b39f137717179d03576f289e6c3e375fda634eab84b36a75878
|
|
@@ -24,7 +24,7 @@ module Dontbugme
|
|
|
24
24
|
@trace_a = params[:a].present? ? store.find_trace(params[:a]) : nil
|
|
25
25
|
@trace_b = params[:b].present? ? store.find_trace(params[:b]) : nil
|
|
26
26
|
@diff_output = if @trace_a && @trace_b
|
|
27
|
-
Formatters::Diff.format(@trace_a, @trace_b)
|
|
27
|
+
Dontbugme::Formatters::Diff.format(@trace_a, @trace_b)
|
|
28
28
|
else
|
|
29
29
|
nil
|
|
30
30
|
end
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
· <%= link_to "Follow chain", root_path(correlation_id: @trace.correlation_id) %>
|
|
7
7
|
<% end %>
|
|
8
8
|
</p>
|
|
9
|
-
<div class="timeline"><%= Formatters::Timeline.format(@trace) %></div>
|
|
9
|
+
<div class="timeline"><%= Dontbugme::Formatters::Timeline.format(@trace) %></div>
|
|
10
10
|
</div>
|
|
11
11
|
|
|
12
12
|
<p style="margin-top: 16px;">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
root to: 'traces#index'
|
|
3
|
+
Dontbugme::Engine.routes.draw do
|
|
4
|
+
root to: 'traces#index'
|
|
5
5
|
get 'diff', to: 'traces#diff', as: :diff
|
|
6
6
|
get ':id', to: 'traces#show', as: :trace, constraints: { id: /tr_[a-f0-9]+/ }
|
|
7
7
|
end
|
|
@@ -134,13 +134,11 @@ module Dontbugme
|
|
|
134
134
|
private
|
|
135
135
|
|
|
136
136
|
def retention_seconds(value, unit)
|
|
137
|
-
return value if value.is_a?(Integer)
|
|
138
|
-
return value.to_i if defined?(ActiveSupport) && value.respond_to?(:to_i)
|
|
139
|
-
|
|
140
137
|
case unit
|
|
141
|
-
when :
|
|
142
|
-
when :
|
|
143
|
-
|
|
138
|
+
when nil, :seconds then value.to_i
|
|
139
|
+
when :hours then (value.to_f * 3600).to_i
|
|
140
|
+
when :days then (value.to_f * 86400).to_i
|
|
141
|
+
else value.to_i
|
|
144
142
|
end
|
|
145
143
|
end
|
|
146
144
|
end
|
|
@@ -9,6 +9,7 @@ module Dontbugme
|
|
|
9
9
|
|
|
10
10
|
def call(env)
|
|
11
11
|
return @app.call(env) unless Dontbugme.config.recording?
|
|
12
|
+
return @app.call(env) unless Dontbugme.config.should_record_request?(env)
|
|
12
13
|
|
|
13
14
|
request = ::Rack::Request.new(env)
|
|
14
15
|
request_id = env['action_dispatch.request_id'] || request.get_header('HTTP_X_REQUEST_ID') || SecureRandom.uuid
|
|
@@ -7,6 +7,7 @@ module Dontbugme
|
|
|
7
7
|
return yield unless Dontbugme.config.recording?
|
|
8
8
|
|
|
9
9
|
job_class = job['class'] || job[:class] || 'Unknown'
|
|
10
|
+
return yield unless Dontbugme.config.should_record_job?(job_class)
|
|
10
11
|
jid = job['jid'] || job[:jid] || SecureRandom.hex(8)
|
|
11
12
|
correlation_id = job['correlation_id'] || job[:correlation_id] || Correlation.current
|
|
12
13
|
Correlation.current = correlation_id
|
data/lib/dontbugme/span.rb
CHANGED
|
@@ -38,7 +38,7 @@ module Dontbugme
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def self.from_h(hash)
|
|
41
|
-
new(
|
|
41
|
+
span = new(
|
|
42
42
|
category: hash[:category] || hash['category'],
|
|
43
43
|
operation: hash[:operation] || hash['operation'],
|
|
44
44
|
detail: hash[:detail] || hash['detail'],
|
|
@@ -47,6 +47,8 @@ module Dontbugme
|
|
|
47
47
|
duration_ms: hash[:duration_ms] || hash['duration_ms'],
|
|
48
48
|
source: hash[:source] || hash['source']
|
|
49
49
|
)
|
|
50
|
+
span.instance_variable_set(:@id, (hash[:id] || hash['id']).to_s) if hash[:id] || hash['id']
|
|
51
|
+
span
|
|
50
52
|
end
|
|
51
53
|
|
|
52
54
|
private
|
|
@@ -6,10 +6,12 @@ module Dontbugme
|
|
|
6
6
|
def initialize(backend)
|
|
7
7
|
@backend = backend
|
|
8
8
|
@queue = Queue.new
|
|
9
|
+
@pid = Process.pid
|
|
9
10
|
@thread = start_worker
|
|
10
11
|
end
|
|
11
12
|
|
|
12
13
|
def save_trace(trace)
|
|
14
|
+
restart_worker_if_forked
|
|
13
15
|
@queue << [:save, trace]
|
|
14
16
|
end
|
|
15
17
|
|
|
@@ -22,11 +24,19 @@ module Dontbugme
|
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def cleanup(before:)
|
|
27
|
+
restart_worker_if_forked
|
|
25
28
|
@queue << [:cleanup, before]
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
private
|
|
29
32
|
|
|
33
|
+
def restart_worker_if_forked
|
|
34
|
+
return if Process.pid == @pid
|
|
35
|
+
|
|
36
|
+
@pid = Process.pid
|
|
37
|
+
@thread = start_worker
|
|
38
|
+
end
|
|
39
|
+
|
|
30
40
|
def start_worker
|
|
31
41
|
Thread.new do
|
|
32
42
|
loop do
|
|
@@ -37,6 +47,8 @@ module Dontbugme
|
|
|
37
47
|
when :cleanup
|
|
38
48
|
@backend.cleanup(before: arg)
|
|
39
49
|
end
|
|
50
|
+
rescue StandardError => e
|
|
51
|
+
warn "[Dontbugme] Async store error: #{e.class} #{e.message}"
|
|
40
52
|
end
|
|
41
53
|
end
|
|
42
54
|
end
|
|
@@ -24,7 +24,7 @@ module Dontbugme
|
|
|
24
24
|
def search(filters = {})
|
|
25
25
|
traces = @mutex.synchronize { @traces.values.dup }
|
|
26
26
|
traces = apply_filters(traces, filters)
|
|
27
|
-
traces.
|
|
27
|
+
traces.map { |h| Trace.from_h(h) }
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
def cleanup(before:)
|
|
@@ -37,8 +37,8 @@ module Dontbugme
|
|
|
37
37
|
private
|
|
38
38
|
|
|
39
39
|
def apply_filters(traces, filters)
|
|
40
|
-
traces = traces.select { |t| t[:status] == filters[:status].to_s } if filters[:status]
|
|
41
|
-
traces = traces.select { |t| t[:status] == filters['status'].to_s } if filters['status']
|
|
40
|
+
traces = traces.select { |t| t[:status].to_s == filters[:status].to_s } if filters[:status]
|
|
41
|
+
traces = traces.select { |t| t[:status].to_s == filters['status'].to_s } if filters['status']
|
|
42
42
|
traces = traces.select { |t| t[:kind].to_s == filters[:kind].to_s } if filters[:kind]
|
|
43
43
|
if filters[:identifier]
|
|
44
44
|
pattern = /#{Regexp.escape(filters[:identifier].to_s)}/i
|
|
@@ -48,8 +48,8 @@ module Dontbugme
|
|
|
48
48
|
cid = filters[:correlation_id].to_s
|
|
49
49
|
traces = traces.select { |t| (t[:correlation_id] || t.dig(:metadata, :correlation_id)).to_s == cid }
|
|
50
50
|
end
|
|
51
|
-
|
|
52
|
-
traces
|
|
51
|
+
limit = filters[:limit] || filters['limit'] || 100
|
|
52
|
+
traces.sort_by { |t| t[:started_at] || '' }.reverse.first(limit)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def parse_time(val)
|
|
@@ -14,22 +14,7 @@ module Dontbugme
|
|
|
14
14
|
def save_trace(trace)
|
|
15
15
|
data = trace.to_h
|
|
16
16
|
correlation_id = data[:correlation_id] || data[:metadata]&.dig(:correlation_id)
|
|
17
|
-
|
|
18
|
-
<<~SQL,
|
|
19
|
-
INSERT INTO dontbugme_traces
|
|
20
|
-
(id, kind, identifier, status, started_at, duration_ms, correlation_id, metadata_json, spans_json, error_json)
|
|
21
|
-
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
|
22
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
23
|
-
kind = EXCLUDED.kind,
|
|
24
|
-
identifier = EXCLUDED.identifier,
|
|
25
|
-
status = EXCLUDED.status,
|
|
26
|
-
started_at = EXCLUDED.started_at,
|
|
27
|
-
duration_ms = EXCLUDED.duration_ms,
|
|
28
|
-
correlation_id = EXCLUDED.correlation_id,
|
|
29
|
-
metadata_json = EXCLUDED.metadata_json,
|
|
30
|
-
spans_json = EXCLUDED.spans_json,
|
|
31
|
-
error_json = EXCLUDED.error_json
|
|
32
|
-
SQL
|
|
17
|
+
params = [
|
|
33
18
|
data[:id],
|
|
34
19
|
data[:kind].to_s,
|
|
35
20
|
data[:identifier],
|
|
@@ -40,7 +25,22 @@ module Dontbugme
|
|
|
40
25
|
data[:metadata].to_json,
|
|
41
26
|
data[:spans].to_json,
|
|
42
27
|
data[:error]&.to_json
|
|
43
|
-
|
|
28
|
+
]
|
|
29
|
+
exec_params(<<~SQL, params)
|
|
30
|
+
INSERT INTO dontbugme_traces
|
|
31
|
+
(id, kind, identifier, status, started_at, duration_ms, correlation_id, metadata_json, spans_json, error_json)
|
|
32
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
|
|
33
|
+
ON CONFLICT (id) DO UPDATE SET
|
|
34
|
+
kind = EXCLUDED.kind,
|
|
35
|
+
identifier = EXCLUDED.identifier,
|
|
36
|
+
status = EXCLUDED.status,
|
|
37
|
+
started_at = EXCLUDED.started_at,
|
|
38
|
+
duration_ms = EXCLUDED.duration_ms,
|
|
39
|
+
correlation_id = EXCLUDED.correlation_id,
|
|
40
|
+
metadata_json = EXCLUDED.metadata_json,
|
|
41
|
+
spans_json = EXCLUDED.spans_json,
|
|
42
|
+
error_json = EXCLUDED.error_json
|
|
43
|
+
SQL
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def find_trace(trace_id)
|
|
@@ -92,6 +92,8 @@ module Dontbugme
|
|
|
92
92
|
exec_params('DELETE FROM dontbugme_traces WHERE started_at < $1', [cutoff])
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
+
private
|
|
96
|
+
|
|
95
97
|
def query_result(sql, params)
|
|
96
98
|
if conn.respond_to?(:exec_query)
|
|
97
99
|
conn.exec_query(sql, 'Dontbugme', params)
|
|
@@ -106,8 +108,6 @@ module Dontbugme
|
|
|
106
108
|
row
|
|
107
109
|
end
|
|
108
110
|
|
|
109
|
-
private
|
|
110
|
-
|
|
111
111
|
def conn
|
|
112
112
|
@connection
|
|
113
113
|
end
|
|
@@ -159,8 +159,8 @@ module Dontbugme
|
|
|
159
159
|
conn.execute('CREATE INDEX IF NOT EXISTS idx_dontbugme_started_at ON dontbugme_traces(started_at)')
|
|
160
160
|
conn.execute('CREATE INDEX IF NOT EXISTS idx_dontbugme_status ON dontbugme_traces(status)')
|
|
161
161
|
conn.execute('CREATE INDEX IF NOT EXISTS idx_dontbugme_correlation_id ON dontbugme_traces(correlation_id)')
|
|
162
|
-
rescue StandardError
|
|
163
|
-
|
|
162
|
+
rescue StandardError => e
|
|
163
|
+
raise e if e.message !~ /already exists/i
|
|
164
164
|
end
|
|
165
165
|
|
|
166
166
|
def row_to_trace(row)
|
data/lib/dontbugme/trace.rb
CHANGED
|
@@ -43,7 +43,7 @@ module Dontbugme
|
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def raw_spans
|
|
46
|
-
@spans.
|
|
46
|
+
@spans.dup
|
|
47
47
|
end
|
|
48
48
|
|
|
49
49
|
def finish!(error: nil)
|
|
@@ -74,12 +74,13 @@ module Dontbugme
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def to_h
|
|
77
|
+
finished_at_time = @finished_at ? (@started_at_utc + (duration_ms || 0) / 1000.0) : nil
|
|
77
78
|
{
|
|
78
79
|
id: id,
|
|
79
80
|
kind: kind,
|
|
80
81
|
identifier: identifier,
|
|
81
82
|
started_at: format_time(started_at_utc),
|
|
82
|
-
finished_at:
|
|
83
|
+
finished_at: finished_at_time ? format_time(finished_at_time) : nil,
|
|
83
84
|
duration_ms: duration_ms,
|
|
84
85
|
status: status,
|
|
85
86
|
error: error,
|
data/lib/dontbugme/version.rb
CHANGED