bugwatch-ruby 0.7.1 → 0.8.1
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/README.md +2 -2
- data/lib/bugwatch/active_job_handler.rb +2 -0
- data/lib/bugwatch/configuration.rb +7 -1
- data/lib/bugwatch/controller_rescue_hook.rb +23 -0
- data/lib/bugwatch/error_subscriber.rb +2 -0
- data/lib/bugwatch/http_call_buffer.rb +61 -0
- data/lib/bugwatch/http_call_sender.rb +68 -0
- data/lib/bugwatch/http_tracker.rb +101 -0
- data/lib/bugwatch/middleware.rb +24 -4
- data/lib/bugwatch/railtie.rb +10 -0
- data/lib/bugwatch/reported_exceptions.rb +19 -0
- data/lib/bugwatch/version.rb +1 -1
- data/lib/bugwatch.rb +13 -1
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f7845d9912f5a403dec979a3457ab7e121a12fb3de870b978d864d8eafb71755
|
|
4
|
+
data.tar.gz: cc43de7851a77523328ca61f5e8b0cd0d4aaa0f9867b3229aa9e34fb04e45a1a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1d5479d1aa4ea0b1060c06328835f8c11b808389d83656a70121ab78e8ff30887caf828433edc27541d39e91ae76e43a568fa08bbf30e014a9c12246d5b88fb3
|
|
7
|
+
data.tar.gz: 3eb19a7f384614714730f68b07243d98064c4b90cca61b90a92b84a10a817cceabc1a520cf61ffdfcdc806a7deb64f0d7dc6157a7f9e0a9b0724ac809f243afb
|
data/README.md
CHANGED
|
@@ -257,8 +257,8 @@ Sensitive params (`password`, `token`, `secret`, `key`, `auth`, `credit`, `card`
|
|
|
257
257
|
## Publishing
|
|
258
258
|
|
|
259
259
|
```bash
|
|
260
|
-
cd /
|
|
260
|
+
cd gems/bugwatch-ruby
|
|
261
261
|
gem build bugwatch-ruby.gemspec
|
|
262
262
|
gem signin
|
|
263
|
-
gem push bugwatch-ruby-0.
|
|
263
|
+
gem push bugwatch-ruby-0.8.0.gem
|
|
264
264
|
```
|
|
@@ -3,6 +3,7 @@ module Bugwatch
|
|
|
3
3
|
def call(job, exception)
|
|
4
4
|
return if Bugwatch.configuration.ignore?(exception)
|
|
5
5
|
return unless Bugwatch.configuration.notify_for_release_stage?
|
|
6
|
+
return if ReportedExceptions.reported?(exception)
|
|
6
7
|
|
|
7
8
|
payload = ErrorBuilder.new(exception).build
|
|
8
9
|
payload[:context] = {
|
|
@@ -13,6 +14,7 @@ module Bugwatch
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
Notification.new(payload).deliver
|
|
17
|
+
ReportedExceptions.mark(exception)
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
private
|
|
@@ -13,7 +13,10 @@ module Bugwatch
|
|
|
13
13
|
:enable_db_tracking,
|
|
14
14
|
:db_sample_rate,
|
|
15
15
|
:db_query_threshold_ms,
|
|
16
|
-
:max_queries_per_request
|
|
16
|
+
:max_queries_per_request,
|
|
17
|
+
:enable_http_tracking,
|
|
18
|
+
:http_sample_rate,
|
|
19
|
+
:max_http_calls_per_request
|
|
17
20
|
|
|
18
21
|
def initialize
|
|
19
22
|
@endpoint = nil
|
|
@@ -28,6 +31,9 @@ module Bugwatch
|
|
|
28
31
|
@db_sample_rate = 1.0
|
|
29
32
|
@db_query_threshold_ms = 0.0
|
|
30
33
|
@max_queries_per_request = 200
|
|
34
|
+
@enable_http_tracking = true
|
|
35
|
+
@http_sample_rate = 1.0
|
|
36
|
+
@max_http_calls_per_request = 100
|
|
31
37
|
end
|
|
32
38
|
|
|
33
39
|
def notify_for_release_stage?
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
module Bugwatch
|
|
2
|
+
module ControllerRescueHook
|
|
3
|
+
def rescue_with_handler(exception, **kwargs)
|
|
4
|
+
handler = super
|
|
5
|
+
|
|
6
|
+
if handler && exception.is_a?(Exception) && !ReportedExceptions.reported?(exception)
|
|
7
|
+
begin
|
|
8
|
+
context = {
|
|
9
|
+
handled: true,
|
|
10
|
+
controller: self.class.name,
|
|
11
|
+
action: (action_name if respond_to?(:action_name))
|
|
12
|
+
}.compact
|
|
13
|
+
|
|
14
|
+
Bugwatch.notify(exception, context: context)
|
|
15
|
+
rescue StandardError
|
|
16
|
+
# Never let reporting break the host's rescue flow
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
handler
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -3,6 +3,7 @@ module Bugwatch
|
|
|
3
3
|
def report(error, handled:, severity:, context: {}, source: nil)
|
|
4
4
|
return if Bugwatch.configuration.ignore?(error)
|
|
5
5
|
return unless Bugwatch.configuration.notify_for_release_stage?
|
|
6
|
+
return if ReportedExceptions.reported?(error)
|
|
6
7
|
|
|
7
8
|
payload = ErrorBuilder.new(error).build
|
|
8
9
|
payload[:context] = context.merge(
|
|
@@ -12,6 +13,7 @@ module Bugwatch
|
|
|
12
13
|
).compact
|
|
13
14
|
|
|
14
15
|
Notification.new(payload).deliver
|
|
16
|
+
ReportedExceptions.mark(error)
|
|
15
17
|
end
|
|
16
18
|
end
|
|
17
19
|
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module Bugwatch
|
|
2
|
+
class HttpCallBuffer
|
|
3
|
+
BATCH_SIZE = 50
|
|
4
|
+
FLUSH_INTERVAL = 15 # seconds
|
|
5
|
+
|
|
6
|
+
def initialize(config: Bugwatch.configuration)
|
|
7
|
+
@config = config
|
|
8
|
+
@sender = HttpCallSender.new(config: config)
|
|
9
|
+
@mutex = Mutex.new
|
|
10
|
+
@buffer = []
|
|
11
|
+
start_flusher
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def push(payload)
|
|
15
|
+
should_flush = false
|
|
16
|
+
|
|
17
|
+
@mutex.synchronize do
|
|
18
|
+
@buffer << payload
|
|
19
|
+
should_flush = @buffer.size >= BATCH_SIZE
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
flush if should_flush
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def flush
|
|
26
|
+
batch = @mutex.synchronize do
|
|
27
|
+
items = @buffer
|
|
28
|
+
@buffer = []
|
|
29
|
+
items
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
@sender.send_batch(batch) unless batch.empty?
|
|
33
|
+
rescue StandardError
|
|
34
|
+
# Never let flushing break the app
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def shutdown
|
|
38
|
+
stop_flusher
|
|
39
|
+
flush
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def start_flusher
|
|
45
|
+
@flusher = Thread.new do
|
|
46
|
+
loop do
|
|
47
|
+
sleep FLUSH_INTERVAL
|
|
48
|
+
flush
|
|
49
|
+
end
|
|
50
|
+
rescue StandardError
|
|
51
|
+
# Silently handle thread errors
|
|
52
|
+
end
|
|
53
|
+
@flusher.abort_on_exception = false
|
|
54
|
+
@flusher.daemon = true if @flusher.respond_to?(:daemon=)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def stop_flusher
|
|
58
|
+
@flusher&.kill
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "uri"
|
|
3
|
+
require "json"
|
|
4
|
+
|
|
5
|
+
module Bugwatch
|
|
6
|
+
class HttpCallSender
|
|
7
|
+
TIMEOUT = 3
|
|
8
|
+
|
|
9
|
+
def initialize(config: Bugwatch.configuration)
|
|
10
|
+
@config = config
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def send_batch(grouped_payloads)
|
|
14
|
+
return if grouped_payloads.empty?
|
|
15
|
+
return unless @config.api_key
|
|
16
|
+
return unless @config.endpoint
|
|
17
|
+
|
|
18
|
+
Thread.new do
|
|
19
|
+
Bugwatch.without_tracking { post_batch(grouped_payloads) }
|
|
20
|
+
rescue StandardError
|
|
21
|
+
# Fire-and-forget: swallow all errors
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def post_batch(grouped_payloads)
|
|
28
|
+
records = grouped_payloads.flat_map do |group|
|
|
29
|
+
group[:calls].map do |c|
|
|
30
|
+
{
|
|
31
|
+
transaction_name: group[:transaction_name],
|
|
32
|
+
environment: group[:environment],
|
|
33
|
+
occurred_at: group[:occurred_at],
|
|
34
|
+
host: c[:host],
|
|
35
|
+
port: c[:port],
|
|
36
|
+
method: c[:method],
|
|
37
|
+
path: c[:path],
|
|
38
|
+
status_code: c[:status_code],
|
|
39
|
+
duration_ms: c[:duration_ms],
|
|
40
|
+
library: c[:library],
|
|
41
|
+
caller_location: c[:caller_location]
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
return if records.empty?
|
|
47
|
+
|
|
48
|
+
uri = URI.parse("#{@config.endpoint.chomp("/")}/api/v1/http_calls/batch")
|
|
49
|
+
|
|
50
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
|
51
|
+
http.use_ssl = uri.scheme == "https"
|
|
52
|
+
http.open_timeout = TIMEOUT
|
|
53
|
+
http.read_timeout = TIMEOUT
|
|
54
|
+
http.write_timeout = TIMEOUT
|
|
55
|
+
|
|
56
|
+
request = Net::HTTP::Post.new(uri.path)
|
|
57
|
+
request["Content-Type"] = "application/json"
|
|
58
|
+
request["X-Api-Key"] = @config.api_key
|
|
59
|
+
request["X-BugWatch-Ruby"] = Bugwatch::VERSION
|
|
60
|
+
|
|
61
|
+
request.body = JSON.generate({ http_calls: records })
|
|
62
|
+
|
|
63
|
+
http.request(request)
|
|
64
|
+
rescue StandardError
|
|
65
|
+
# Silently discard network errors
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require "net/http"
|
|
2
|
+
|
|
3
|
+
module Bugwatch
|
|
4
|
+
module HttpTracker
|
|
5
|
+
THREAD_KEY = :bugwatch_http_tracker
|
|
6
|
+
|
|
7
|
+
CALLER_FILTER = %r{/(bugwatch|ruby/gems)/}
|
|
8
|
+
|
|
9
|
+
module NetHttpPatch
|
|
10
|
+
def request(req, body = nil, &block)
|
|
11
|
+
return super if Thread.current[:bugwatch_skip_tracking]
|
|
12
|
+
return super unless HttpTracker.collecting?
|
|
13
|
+
|
|
14
|
+
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
15
|
+
response = super
|
|
16
|
+
duration_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).round(2)
|
|
17
|
+
|
|
18
|
+
HttpTracker.handle_call(self, req, response, duration_ms)
|
|
19
|
+
response
|
|
20
|
+
rescue Exception # rubocop:disable Lint/RescueException
|
|
21
|
+
raise
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
module_function
|
|
26
|
+
|
|
27
|
+
def subscribe!
|
|
28
|
+
return if Net::HTTP.ancestors.include?(NetHttpPatch)
|
|
29
|
+
|
|
30
|
+
Net::HTTP.prepend(NetHttpPatch)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def start_request(collecting:)
|
|
34
|
+
Thread.current[THREAD_KEY] = {
|
|
35
|
+
calls: [],
|
|
36
|
+
collecting: collecting
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def finish_request
|
|
41
|
+
state = Thread.current[THREAD_KEY]
|
|
42
|
+
Thread.current[THREAD_KEY] = nil
|
|
43
|
+
state
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def clear
|
|
47
|
+
Thread.current[THREAD_KEY] = nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def collecting?
|
|
51
|
+
state = Thread.current[THREAD_KEY]
|
|
52
|
+
state && state[:collecting]
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def handle_call(http, req, response, duration_ms)
|
|
56
|
+
state = Thread.current[THREAD_KEY]
|
|
57
|
+
return unless state
|
|
58
|
+
return unless state[:collecting]
|
|
59
|
+
|
|
60
|
+
config = Bugwatch.configuration
|
|
61
|
+
return if state[:calls].size >= config.max_http_calls_per_request
|
|
62
|
+
|
|
63
|
+
state[:calls] << {
|
|
64
|
+
host: http.address,
|
|
65
|
+
port: http.port,
|
|
66
|
+
method: req.method,
|
|
67
|
+
path: extract_path(req.path),
|
|
68
|
+
status_code: response.code.to_i,
|
|
69
|
+
duration_ms: duration_ms,
|
|
70
|
+
library: detect_library,
|
|
71
|
+
caller_location: extract_caller
|
|
72
|
+
}
|
|
73
|
+
rescue StandardError
|
|
74
|
+
# Never let tracking break the app
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def extract_path(full_path)
|
|
78
|
+
full_path.to_s.split("?").first
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def detect_library
|
|
82
|
+
caller_locations(4, 20)&.each do |loc|
|
|
83
|
+
path = loc.path.to_s
|
|
84
|
+
return "faraday" if path.include?("faraday")
|
|
85
|
+
return "httparty" if path.include?("httparty")
|
|
86
|
+
end
|
|
87
|
+
"net_http"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def extract_caller
|
|
91
|
+
caller_locations(4, 30)&.each do |loc|
|
|
92
|
+
path = loc.path.to_s
|
|
93
|
+
next if path.match?(CALLER_FILTER)
|
|
94
|
+
return "#{loc.path}:#{loc.lineno}"
|
|
95
|
+
end
|
|
96
|
+
nil
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
private_class_method :handle_call, :extract_path, :detect_library, :extract_caller
|
|
100
|
+
end
|
|
101
|
+
end
|
data/lib/bugwatch/middleware.rb
CHANGED
|
@@ -12,11 +12,15 @@ module Bugwatch
|
|
|
12
12
|
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
13
13
|
BreadcrumbCollector.clear
|
|
14
14
|
UserContext.clear
|
|
15
|
+
ReportedExceptions.clear
|
|
15
16
|
|
|
16
17
|
config = Bugwatch.configuration
|
|
17
18
|
collecting = config.enable_db_tracking && (rand < config.db_sample_rate)
|
|
18
19
|
DbTracker.start_request(collecting: collecting)
|
|
19
20
|
|
|
21
|
+
collecting_http = config.enable_http_tracking && (rand < config.http_sample_rate)
|
|
22
|
+
HttpTracker.start_request(collecting: collecting_http)
|
|
23
|
+
|
|
20
24
|
begin
|
|
21
25
|
status, headers, body = @app.call(env)
|
|
22
26
|
record_transaction(env, status, start)
|
|
@@ -24,16 +28,22 @@ module Bugwatch
|
|
|
24
28
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
|
25
29
|
duration_ms = ((Process.clock_gettime(Process::CLOCK_MONOTONIC) - start) * 1000).round
|
|
26
30
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
begin
|
|
32
|
+
if !Bugwatch.configuration.ignore?(e) && !ReportedExceptions.reported?(e)
|
|
33
|
+
payload = ErrorBuilder.new(e, env).build
|
|
34
|
+
payload[:duration_ms] = duration_ms
|
|
35
|
+
Notification.new(payload).deliver
|
|
36
|
+
ReportedExceptions.mark(e)
|
|
37
|
+
end
|
|
38
|
+
rescue StandardError
|
|
39
|
+
# Never let reporting failures drop the original exception
|
|
31
40
|
end
|
|
32
41
|
|
|
33
42
|
record_transaction(env, 500, start)
|
|
34
43
|
raise
|
|
35
44
|
ensure
|
|
36
45
|
DbTracker.clear
|
|
46
|
+
HttpTracker.clear
|
|
37
47
|
end
|
|
38
48
|
end
|
|
39
49
|
|
|
@@ -74,6 +84,16 @@ module Bugwatch
|
|
|
74
84
|
queries: db_result[:queries]
|
|
75
85
|
})
|
|
76
86
|
end
|
|
87
|
+
|
|
88
|
+
http_result = HttpTracker.finish_request
|
|
89
|
+
if http_result && http_result[:calls].any?
|
|
90
|
+
Bugwatch.http_call_buffer.push({
|
|
91
|
+
transaction_name: payload[:name],
|
|
92
|
+
environment: config.release_stage,
|
|
93
|
+
occurred_at: payload[:occurred_at],
|
|
94
|
+
calls: http_result[:calls]
|
|
95
|
+
})
|
|
96
|
+
end
|
|
77
97
|
rescue StandardError
|
|
78
98
|
# Never let tracking break the app
|
|
79
99
|
end
|
data/lib/bugwatch/railtie.rb
CHANGED
|
@@ -31,11 +31,21 @@ module Bugwatch
|
|
|
31
31
|
end
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
+
initializer "bugwatch.http_tracking" do
|
|
35
|
+
Bugwatch::HttpTracker.subscribe! if Bugwatch.configuration.enable_http_tracking
|
|
36
|
+
end
|
|
37
|
+
|
|
34
38
|
initializer "bugwatch.error_subscriber" do
|
|
35
39
|
if defined?(Rails.error) && Rails.error.respond_to?(:subscribe)
|
|
36
40
|
Rails.error.subscribe(Bugwatch::ErrorSubscriber.new)
|
|
37
41
|
end
|
|
38
42
|
end
|
|
43
|
+
|
|
44
|
+
initializer "bugwatch.controller_rescue_hook" do
|
|
45
|
+
ActiveSupport.on_load(:action_controller) do
|
|
46
|
+
prepend Bugwatch::ControllerRescueHook
|
|
47
|
+
end
|
|
48
|
+
end
|
|
39
49
|
end
|
|
40
50
|
|
|
41
51
|
module ControllerMethods
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Bugwatch
|
|
2
|
+
module ReportedExceptions
|
|
3
|
+
THREAD_KEY = :bugwatch_reported_exceptions
|
|
4
|
+
|
|
5
|
+
def self.mark(exception)
|
|
6
|
+
return unless exception
|
|
7
|
+
(Thread.current[THREAD_KEY] ||= []) << exception.object_id
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.reported?(exception)
|
|
11
|
+
return false unless exception
|
|
12
|
+
(Thread.current[THREAD_KEY] || []).include?(exception.object_id)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.clear
|
|
16
|
+
Thread.current[THREAD_KEY] = nil
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/bugwatch/version.rb
CHANGED
data/lib/bugwatch.rb
CHANGED
|
@@ -6,6 +6,7 @@ require_relative "bugwatch/configuration"
|
|
|
6
6
|
require_relative "bugwatch/user_context"
|
|
7
7
|
require_relative "bugwatch/breadcrumb_collector"
|
|
8
8
|
require_relative "bugwatch/backtrace_cleaner"
|
|
9
|
+
require_relative "bugwatch/reported_exceptions"
|
|
9
10
|
require_relative "bugwatch/error_builder"
|
|
10
11
|
require_relative "bugwatch/report_builder"
|
|
11
12
|
require_relative "bugwatch/notification"
|
|
@@ -14,11 +15,15 @@ require_relative "bugwatch/transaction_buffer"
|
|
|
14
15
|
require_relative "bugwatch/db_tracker"
|
|
15
16
|
require_relative "bugwatch/db_query_sender"
|
|
16
17
|
require_relative "bugwatch/db_query_buffer"
|
|
18
|
+
require_relative "bugwatch/http_tracker"
|
|
19
|
+
require_relative "bugwatch/http_call_sender"
|
|
20
|
+
require_relative "bugwatch/http_call_buffer"
|
|
17
21
|
require_relative "bugwatch/feedback_sender"
|
|
18
22
|
require_relative "bugwatch/feedback_helper"
|
|
19
23
|
require_relative "bugwatch/middleware"
|
|
20
24
|
require_relative "bugwatch/active_job_handler"
|
|
21
25
|
require_relative "bugwatch/error_subscriber"
|
|
26
|
+
require_relative "bugwatch/controller_rescue_hook"
|
|
22
27
|
require_relative "bugwatch/railtie" if defined?(Rails::Railtie)
|
|
23
28
|
|
|
24
29
|
module Bugwatch
|
|
@@ -34,10 +39,12 @@ module Bugwatch
|
|
|
34
39
|
def notify(exception, context: {})
|
|
35
40
|
return if configuration.ignore?(exception)
|
|
36
41
|
return unless configuration.notify_for_release_stage?
|
|
42
|
+
return if ReportedExceptions.reported?(exception)
|
|
37
43
|
|
|
38
44
|
payload = ErrorBuilder.new(exception).build
|
|
39
45
|
payload.merge!(context)
|
|
40
46
|
Notification.new(payload).deliver
|
|
47
|
+
ReportedExceptions.mark(exception)
|
|
41
48
|
end
|
|
42
49
|
|
|
43
50
|
def report(title, category: "other", severity: "warning", tags: {})
|
|
@@ -138,10 +145,15 @@ module Bugwatch
|
|
|
138
145
|
def db_query_buffer
|
|
139
146
|
@db_query_buffer ||= DbQueryBuffer.new(config: configuration)
|
|
140
147
|
end
|
|
148
|
+
|
|
149
|
+
def http_call_buffer
|
|
150
|
+
@http_call_buffer ||= HttpCallBuffer.new(config: configuration)
|
|
151
|
+
end
|
|
141
152
|
end
|
|
142
153
|
end
|
|
143
154
|
|
|
144
155
|
at_exit do
|
|
145
156
|
Bugwatch.transaction_buffer.shutdown rescue nil
|
|
146
|
-
Bugwatch.db_query_buffer.shutdown
|
|
157
|
+
Bugwatch.db_query_buffer.shutdown rescue nil
|
|
158
|
+
Bugwatch.http_call_buffer.shutdown rescue nil
|
|
147
159
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: bugwatch-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BugWatch
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-04-
|
|
10
|
+
date: 2026-04-22 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: railties
|
|
@@ -52,6 +52,7 @@ files:
|
|
|
52
52
|
- lib/bugwatch/backtrace_cleaner.rb
|
|
53
53
|
- lib/bugwatch/breadcrumb_collector.rb
|
|
54
54
|
- lib/bugwatch/configuration.rb
|
|
55
|
+
- lib/bugwatch/controller_rescue_hook.rb
|
|
55
56
|
- lib/bugwatch/db_query_buffer.rb
|
|
56
57
|
- lib/bugwatch/db_query_sender.rb
|
|
57
58
|
- lib/bugwatch/db_tracker.rb
|
|
@@ -59,10 +60,14 @@ files:
|
|
|
59
60
|
- lib/bugwatch/error_subscriber.rb
|
|
60
61
|
- lib/bugwatch/feedback_helper.rb
|
|
61
62
|
- lib/bugwatch/feedback_sender.rb
|
|
63
|
+
- lib/bugwatch/http_call_buffer.rb
|
|
64
|
+
- lib/bugwatch/http_call_sender.rb
|
|
65
|
+
- lib/bugwatch/http_tracker.rb
|
|
62
66
|
- lib/bugwatch/middleware.rb
|
|
63
67
|
- lib/bugwatch/notification.rb
|
|
64
68
|
- lib/bugwatch/railtie.rb
|
|
65
69
|
- lib/bugwatch/report_builder.rb
|
|
70
|
+
- lib/bugwatch/reported_exceptions.rb
|
|
66
71
|
- lib/bugwatch/transaction_buffer.rb
|
|
67
72
|
- lib/bugwatch/transaction_sender.rb
|
|
68
73
|
- lib/bugwatch/user_context.rb
|