airbrake-ruby 4.10.1 → 4.12.0
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/airbrake-ruby.rb +23 -26
- data/lib/airbrake-ruby/benchmark.rb +1 -1
- data/lib/airbrake-ruby/config.rb +9 -0
- data/lib/airbrake-ruby/notice_notifier.rb +2 -1
- data/lib/airbrake-ruby/performance_breakdown.rb +11 -6
- data/lib/airbrake-ruby/performance_notifier.rb +32 -6
- data/lib/airbrake-ruby/query.rb +12 -6
- data/lib/airbrake-ruby/queue.rb +12 -8
- data/lib/airbrake-ruby/request.rb +12 -8
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/airbrake_spec.rb +9 -9
- data/spec/config_spec.rb +19 -7
- data/spec/filters/sql_filter_spec.rb +1 -3
- data/spec/notice_notifier_spec.rb +2 -2
- data/spec/performance_notifier_spec.rb +99 -38
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8c5e41d6b33c6a201ef67d32e32e69bbef6e560c1af80dc19ae8f4192d6b84fd
|
|
4
|
+
data.tar.gz: 34e30b5ce530edc18c512ba0be5392a2c53cdee68ec23eb43174e9690715f821
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: '0081a23db3f3ff08f56382e97a67685a7c28eb81c5c93963a440a5f216ddf322ffaf8dae6be14a1394edc079dbd1644511f817693a14eebb3e097243f03f74c9'
|
|
7
|
+
data.tar.gz: c9c58c197046e16f7706cddbfb4caab70837f03b457418ff22f756499efe6bd98762eca8547a9e716af9d04e20c53a4440a9ca83affc7c1713623d3a191cb560
|
data/lib/airbrake-ruby.rb
CHANGED
|
@@ -328,9 +328,8 @@ module Airbrake
|
|
|
328
328
|
notice_notifier.merge_context(context)
|
|
329
329
|
end
|
|
330
330
|
|
|
331
|
-
# Increments request statistics of a certain +route+
|
|
332
|
-
#
|
|
333
|
-
# +status_code+.
|
|
331
|
+
# Increments request statistics of a certain +route+ invoked with +method+,
|
|
332
|
+
# which returned +status_code+.
|
|
334
333
|
#
|
|
335
334
|
# After a certain amount of time (n seconds) the aggregated route
|
|
336
335
|
# information will be sent to Airbrake.
|
|
@@ -343,8 +342,7 @@ module Airbrake
|
|
|
343
342
|
# func: 'do_stuff',
|
|
344
343
|
# file: 'app/models/foo.rb',
|
|
345
344
|
# line: 452,
|
|
346
|
-
#
|
|
347
|
-
# end_time: Time.now
|
|
345
|
+
# timing: 123.45 # ms
|
|
348
346
|
# )
|
|
349
347
|
#
|
|
350
348
|
# @param [Hash{Symbol=>Object}] request_info
|
|
@@ -358,8 +356,8 @@ module Airbrake
|
|
|
358
356
|
# called the query (optional)
|
|
359
357
|
# @option request_info [Integer] :line The line that executes the query
|
|
360
358
|
# (optional)
|
|
361
|
-
# @option request_info [
|
|
362
|
-
#
|
|
359
|
+
# @option request_info [Float] :timing How much time it took to process the
|
|
360
|
+
# request (in ms)
|
|
363
361
|
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
|
364
362
|
# available in filters
|
|
365
363
|
# @return [void]
|
|
@@ -371,9 +369,8 @@ module Airbrake
|
|
|
371
369
|
performance_notifier.notify(request)
|
|
372
370
|
end
|
|
373
371
|
|
|
374
|
-
# Synchronously
|
|
375
|
-
#
|
|
376
|
-
# returned +status_code+.
|
|
372
|
+
# Synchronously increments request statistics of a certain +route+ invoked
|
|
373
|
+
# with +method+, which returned +status_code+.
|
|
377
374
|
# @since v4.10.0
|
|
378
375
|
# @see .notify_request
|
|
379
376
|
def notify_request_sync(request_info, stash = {})
|
|
@@ -382,9 +379,8 @@ module Airbrake
|
|
|
382
379
|
performance_notifier.notify_sync(request)
|
|
383
380
|
end
|
|
384
381
|
|
|
385
|
-
# Increments SQL statistics of a certain +query
|
|
386
|
-
#
|
|
387
|
-
# provided, the query is grouped by these parameters.
|
|
382
|
+
# Increments SQL statistics of a certain +query+. When +method+ and +route+
|
|
383
|
+
# are provided, the query is grouped by these parameters.
|
|
388
384
|
#
|
|
389
385
|
# After a certain amount of time (n seconds) the aggregated query
|
|
390
386
|
# information will be sent to Airbrake.
|
|
@@ -394,18 +390,17 @@ module Airbrake
|
|
|
394
390
|
# method: 'GET',
|
|
395
391
|
# route: '/things',
|
|
396
392
|
# query: 'SELECT * FROM things',
|
|
397
|
-
#
|
|
398
|
-
# end_time: Time.now
|
|
393
|
+
# timing: 123.45 # ms
|
|
399
394
|
# )
|
|
400
395
|
#
|
|
401
396
|
# @param [Hash{Symbol=>Object}] query_info
|
|
402
|
-
# @option
|
|
397
|
+
# @option query_info [String] :method The HTTP method that triggered this
|
|
403
398
|
# SQL query (optional)
|
|
404
|
-
# @option
|
|
399
|
+
# @option query_info [String] :route The route that triggered this SQL
|
|
405
400
|
# query (optional)
|
|
406
|
-
# @option
|
|
407
|
-
# @option
|
|
408
|
-
#
|
|
401
|
+
# @option query_info [String] :query The query that was executed
|
|
402
|
+
# @option query_info [Float] :timing How much time it took to process the
|
|
403
|
+
# query (in ms)
|
|
409
404
|
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
|
410
405
|
# available in filters
|
|
411
406
|
# @return [void]
|
|
@@ -417,9 +412,9 @@ module Airbrake
|
|
|
417
412
|
performance_notifier.notify(query)
|
|
418
413
|
end
|
|
419
414
|
|
|
420
|
-
# Synchronously increments SQL statistics of a certain +query
|
|
421
|
-
#
|
|
422
|
-
#
|
|
415
|
+
# Synchronously increments SQL statistics of a certain +query+. When
|
|
416
|
+
# +method+ and +route+ are provided, the query is grouped by these
|
|
417
|
+
# parameters.
|
|
423
418
|
# @since v4.10.0
|
|
424
419
|
# @see .notify_query
|
|
425
420
|
def notify_query_sync(query_info, stash = {})
|
|
@@ -436,8 +431,7 @@ module Airbrake
|
|
|
436
431
|
# route: '/thing/:id/create',
|
|
437
432
|
# response_type: 'json',
|
|
438
433
|
# groups: { db: 24.0, view: 0.4 }, # ms
|
|
439
|
-
#
|
|
440
|
-
# end_time: Time.now
|
|
434
|
+
# timing: 123.45 # ms
|
|
441
435
|
# )
|
|
442
436
|
#
|
|
443
437
|
# @param [Hash{Symbol=>Object}] breakdown_info
|
|
@@ -445,7 +439,8 @@ module Airbrake
|
|
|
445
439
|
# @option breakdown_info [String] :route
|
|
446
440
|
# @option breakdown_info [String] :response_type
|
|
447
441
|
# @option breakdown_info [Array<Hash{Symbol=>Float}>] :groups
|
|
448
|
-
# @option breakdown_info [
|
|
442
|
+
# @option breakdown_info [Float] :timing How much time it took to process
|
|
443
|
+
# the performance breakdown (in ms)
|
|
449
444
|
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
|
450
445
|
# available in filters
|
|
451
446
|
# @return [void]
|
|
@@ -481,6 +476,8 @@ module Airbrake
|
|
|
481
476
|
# failed
|
|
482
477
|
# @option queue_info [Array<Hash{Symbol=>Float}>] :groups Where the job
|
|
483
478
|
# spent its time
|
|
479
|
+
# @option breakdown_info [Float] :timing How much time it took to process
|
|
480
|
+
# the queue (in ms)
|
|
484
481
|
# @param [Hash] stash What needs to be appended to the stash, so it's
|
|
485
482
|
# available in filters
|
|
486
483
|
# @return [void]
|
data/lib/airbrake-ruby/config.rb
CHANGED
|
@@ -101,6 +101,12 @@ module Airbrake
|
|
|
101
101
|
# @since v4.6.0
|
|
102
102
|
attr_accessor :query_stats
|
|
103
103
|
|
|
104
|
+
# @return [Boolean] true if the library should send job/queue/worker stats
|
|
105
|
+
# to Airbrake, false otherwise
|
|
106
|
+
# @api public
|
|
107
|
+
# @since v4.12.0
|
|
108
|
+
attr_accessor :job_stats
|
|
109
|
+
|
|
104
110
|
class << self
|
|
105
111
|
# @return [Config]
|
|
106
112
|
attr_writer :instance
|
|
@@ -139,6 +145,7 @@ module Airbrake
|
|
|
139
145
|
self.performance_stats = true
|
|
140
146
|
self.performance_stats_flush_period = 15
|
|
141
147
|
self.query_stats = true
|
|
148
|
+
self.job_stats = true
|
|
142
149
|
|
|
143
150
|
merge(user_config)
|
|
144
151
|
end
|
|
@@ -213,6 +220,8 @@ module Airbrake
|
|
|
213
220
|
promise.reject("The Performance Stats feature is disabled")
|
|
214
221
|
elsif resource.is_a?(Airbrake::Query) && !query_stats
|
|
215
222
|
promise.reject("The Query Stats feature is disabled")
|
|
223
|
+
elsif resource.is_a?(Airbrake::Queue) && !job_stats
|
|
224
|
+
promise.reject("The Job Stats feature is disabled")
|
|
216
225
|
else
|
|
217
226
|
promise
|
|
218
227
|
end
|
|
@@ -55,7 +55,8 @@ module Airbrake
|
|
|
55
55
|
def build_notice(exception, params = {})
|
|
56
56
|
if @async_sender.closed?
|
|
57
57
|
raise Airbrake::Error,
|
|
58
|
-
"
|
|
58
|
+
"Airbrake is closed; can't build exception: " \
|
|
59
|
+
"#{exception.class}: #{exception}"
|
|
59
60
|
end
|
|
60
61
|
|
|
61
62
|
if exception.is_a?(Airbrake::Notice)
|
|
@@ -7,7 +7,8 @@ module Airbrake
|
|
|
7
7
|
# @since v4.2.0
|
|
8
8
|
# rubocop:disable Metrics/BlockLength, Metrics/ParameterLists
|
|
9
9
|
PerformanceBreakdown = Struct.new(
|
|
10
|
-
:method, :route, :response_type, :groups, :start_time, :end_time
|
|
10
|
+
:method, :route, :response_type, :groups, :start_time, :end_time, :timing,
|
|
11
|
+
:time
|
|
11
12
|
) do
|
|
12
13
|
include HashKeyable
|
|
13
14
|
include Ignorable
|
|
@@ -19,11 +20,15 @@ module Airbrake
|
|
|
19
20
|
route:,
|
|
20
21
|
response_type:,
|
|
21
22
|
groups:,
|
|
22
|
-
start_time
|
|
23
|
-
end_time: start_time + 1
|
|
23
|
+
start_time: Time.now,
|
|
24
|
+
end_time: start_time + 1,
|
|
25
|
+
timing: nil,
|
|
26
|
+
time: Time.now
|
|
24
27
|
)
|
|
25
|
-
@
|
|
26
|
-
super(
|
|
28
|
+
@time_utc = TimeTruncate.utc_truncate_minutes(time)
|
|
29
|
+
super(
|
|
30
|
+
method, route, response_type, groups, start_time, end_time, timing, time
|
|
31
|
+
)
|
|
27
32
|
end
|
|
28
33
|
|
|
29
34
|
def destination
|
|
@@ -39,7 +44,7 @@ module Airbrake
|
|
|
39
44
|
'method' => method,
|
|
40
45
|
'route' => route,
|
|
41
46
|
'responseType' => response_type,
|
|
42
|
-
'time' => @
|
|
47
|
+
'time' => @time_utc,
|
|
43
48
|
}.delete_if { |_key, val| val.nil? }
|
|
44
49
|
end
|
|
45
50
|
end
|
|
@@ -62,7 +62,7 @@ module Airbrake
|
|
|
62
62
|
@payload[resource] = { total: Airbrake::Stat.new }
|
|
63
63
|
end
|
|
64
64
|
|
|
65
|
-
@payload[resource][:total]
|
|
65
|
+
update_total(resource, @payload[resource][:total])
|
|
66
66
|
|
|
67
67
|
resource.groups.each do |name, ms|
|
|
68
68
|
@payload[resource][name] ||= Airbrake::Stat.new
|
|
@@ -70,6 +70,19 @@ module Airbrake
|
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
def update_total(resource, total)
|
|
74
|
+
if resource.timing
|
|
75
|
+
total.increment_ms(resource.timing)
|
|
76
|
+
else
|
|
77
|
+
loc = caller_locations(6..6).first
|
|
78
|
+
Kernel.warn(
|
|
79
|
+
"#{loc.path}:#{loc.lineno}: warning: :start_time and :end_time are " \
|
|
80
|
+
"deprecated. Use :timing & :time instead",
|
|
81
|
+
)
|
|
82
|
+
total.increment(resource.start_time, resource.end_time)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
73
86
|
def schedule_flush
|
|
74
87
|
return if @payload.empty?
|
|
75
88
|
|
|
@@ -107,14 +120,13 @@ module Airbrake
|
|
|
107
120
|
end
|
|
108
121
|
|
|
109
122
|
def send_resource(resource, sync:)
|
|
110
|
-
promise =
|
|
111
|
-
return promise if promise.rejected?
|
|
112
|
-
|
|
113
|
-
promise = @config.check_performance_options(resource)
|
|
123
|
+
promise = check_configuration(resource)
|
|
114
124
|
return promise if promise.rejected?
|
|
115
125
|
|
|
116
126
|
@filter_chain.refine(resource)
|
|
117
|
-
|
|
127
|
+
if resource.ignored?
|
|
128
|
+
return Promise.new.reject("#{resource.class} was ignored by a filter")
|
|
129
|
+
end
|
|
118
130
|
|
|
119
131
|
@mutex.synchronize do
|
|
120
132
|
update_payload(resource)
|
|
@@ -126,6 +138,20 @@ module Airbrake
|
|
|
126
138
|
end
|
|
127
139
|
end
|
|
128
140
|
|
|
141
|
+
def check_configuration(resource)
|
|
142
|
+
promise = @config.check_configuration
|
|
143
|
+
return promise if promise.rejected?
|
|
144
|
+
|
|
145
|
+
promise = @config.check_performance_options(resource)
|
|
146
|
+
return promise if promise.rejected?
|
|
147
|
+
|
|
148
|
+
if resource.timing && resource.timing == 0
|
|
149
|
+
return Promise.new.reject(':timing cannot be zero')
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
Promise.new
|
|
153
|
+
end
|
|
154
|
+
|
|
129
155
|
def send(sender, payload, promise)
|
|
130
156
|
signature = "#{self.class.name}##{__method__}"
|
|
131
157
|
raise "#{signature}: payload (#{payload}) cannot be empty. Race?" if payload.none?
|
data/lib/airbrake-ruby/query.rb
CHANGED
|
@@ -6,7 +6,8 @@ module Airbrake
|
|
|
6
6
|
# @since v3.2.0
|
|
7
7
|
# rubocop:disable Metrics/ParameterLists, Metrics/BlockLength
|
|
8
8
|
Query = Struct.new(
|
|
9
|
-
:method, :route, :query, :func, :file, :line, :start_time, :end_time
|
|
9
|
+
:method, :route, :query, :func, :file, :line, :start_time, :end_time,
|
|
10
|
+
:timing, :time
|
|
10
11
|
) do
|
|
11
12
|
include HashKeyable
|
|
12
13
|
include Ignorable
|
|
@@ -21,11 +22,16 @@ module Airbrake
|
|
|
21
22
|
func: nil,
|
|
22
23
|
file: nil,
|
|
23
24
|
line: nil,
|
|
24
|
-
start_time
|
|
25
|
-
end_time: start_time + 1
|
|
25
|
+
start_time: Time.now,
|
|
26
|
+
end_time: start_time + 1,
|
|
27
|
+
timing: nil,
|
|
28
|
+
time: Time.now
|
|
26
29
|
)
|
|
27
|
-
@
|
|
28
|
-
super(
|
|
30
|
+
@time_utc = TimeTruncate.utc_truncate_minutes(time)
|
|
31
|
+
super(
|
|
32
|
+
method, route, query, func, file, line, start_time, end_time, timing,
|
|
33
|
+
time
|
|
34
|
+
)
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
def destination
|
|
@@ -41,7 +47,7 @@ module Airbrake
|
|
|
41
47
|
'method' => method,
|
|
42
48
|
'route' => route,
|
|
43
49
|
'query' => query,
|
|
44
|
-
'time' => @
|
|
50
|
+
'time' => @time_utc,
|
|
45
51
|
'function' => func,
|
|
46
52
|
'file' => file,
|
|
47
53
|
'line' => line,
|
data/lib/airbrake-ruby/queue.rb
CHANGED
|
@@ -4,8 +4,10 @@ module Airbrake
|
|
|
4
4
|
# @see Airbrake.notify_queue
|
|
5
5
|
# @api public
|
|
6
6
|
# @since v4.9.0
|
|
7
|
-
# rubocop:disable Metrics/BlockLength
|
|
8
|
-
Queue = Struct.new(
|
|
7
|
+
# rubocop:disable Metrics/BlockLength, Metrics/ParameterLists
|
|
8
|
+
Queue = Struct.new(
|
|
9
|
+
:queue, :error_count, :groups, :start_time, :end_time, :timing, :time
|
|
10
|
+
) do
|
|
9
11
|
include HashKeyable
|
|
10
12
|
include Ignorable
|
|
11
13
|
include Stashable
|
|
@@ -15,10 +17,12 @@ module Airbrake
|
|
|
15
17
|
error_count:,
|
|
16
18
|
groups: {},
|
|
17
19
|
start_time: Time.now,
|
|
18
|
-
end_time: start_time + 1
|
|
20
|
+
end_time: start_time + 1,
|
|
21
|
+
timing: nil,
|
|
22
|
+
time: Time.now
|
|
19
23
|
)
|
|
20
|
-
@
|
|
21
|
-
super(queue, error_count, groups, start_time, end_time)
|
|
24
|
+
@time_utc = TimeTruncate.utc_truncate_minutes(time)
|
|
25
|
+
super(queue, error_count, groups, start_time, end_time, timing, time)
|
|
22
26
|
end
|
|
23
27
|
|
|
24
28
|
def destination
|
|
@@ -33,14 +37,14 @@ module Airbrake
|
|
|
33
37
|
{
|
|
34
38
|
'queue' => queue,
|
|
35
39
|
'errorCount' => error_count,
|
|
36
|
-
'time' => @
|
|
40
|
+
'time' => @time_utc,
|
|
37
41
|
}
|
|
38
42
|
end
|
|
39
43
|
|
|
40
44
|
def hash
|
|
41
45
|
{
|
|
42
46
|
'queue' => queue,
|
|
43
|
-
'time' => @
|
|
47
|
+
'time' => @time_utc,
|
|
44
48
|
}.hash
|
|
45
49
|
end
|
|
46
50
|
|
|
@@ -48,5 +52,5 @@ module Airbrake
|
|
|
48
52
|
self.error_count += other.error_count
|
|
49
53
|
end
|
|
50
54
|
end
|
|
51
|
-
# rubocop:enable Metrics/BlockLength
|
|
55
|
+
# rubocop:enable Metrics/BlockLength, Metrics/ParameterLists
|
|
52
56
|
end
|
|
@@ -4,8 +4,10 @@ module Airbrake
|
|
|
4
4
|
# @see Airbrake.notify_request
|
|
5
5
|
# @api public
|
|
6
6
|
# @since v3.2.0
|
|
7
|
-
# rubocop:disable Metrics/BlockLength
|
|
8
|
-
Request = Struct.new(
|
|
7
|
+
# rubocop:disable Metrics/BlockLength, Metrics/ParameterLists
|
|
8
|
+
Request = Struct.new(
|
|
9
|
+
:method, :route, :status_code, :start_time, :end_time, :timing, :time
|
|
10
|
+
) do
|
|
9
11
|
include HashKeyable
|
|
10
12
|
include Ignorable
|
|
11
13
|
include Stashable
|
|
@@ -16,11 +18,13 @@ module Airbrake
|
|
|
16
18
|
method:,
|
|
17
19
|
route:,
|
|
18
20
|
status_code:,
|
|
19
|
-
start_time
|
|
20
|
-
end_time: start_time + 1
|
|
21
|
+
start_time: Time.now,
|
|
22
|
+
end_time: start_time + 1,
|
|
23
|
+
timing: nil,
|
|
24
|
+
time: Time.now
|
|
21
25
|
)
|
|
22
|
-
@
|
|
23
|
-
super(method, route, status_code, start_time, end_time)
|
|
26
|
+
@time_utc = TimeTruncate.utc_truncate_minutes(time)
|
|
27
|
+
super(method, route, status_code, start_time, end_time, timing, time)
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
def destination
|
|
@@ -36,9 +40,9 @@ module Airbrake
|
|
|
36
40
|
'method' => method,
|
|
37
41
|
'route' => route,
|
|
38
42
|
'statusCode' => status_code,
|
|
39
|
-
'time' => @
|
|
43
|
+
'time' => @time_utc,
|
|
40
44
|
}.delete_if { |_key, val| val.nil? }
|
|
41
45
|
end
|
|
42
46
|
end
|
|
43
|
-
# rubocop:enable Metrics/BlockLength
|
|
47
|
+
# rubocop:enable Metrics/BlockLength, Metrics/ParameterLists
|
|
44
48
|
end
|
data/spec/airbrake_spec.rb
CHANGED
|
@@ -171,7 +171,7 @@ RSpec.describe Airbrake do
|
|
|
171
171
|
method: 'GET',
|
|
172
172
|
route: '/',
|
|
173
173
|
status_code: 200,
|
|
174
|
-
|
|
174
|
+
timing: 1,
|
|
175
175
|
)
|
|
176
176
|
end
|
|
177
177
|
end
|
|
@@ -187,7 +187,7 @@ RSpec.describe Airbrake do
|
|
|
187
187
|
method: 'GET',
|
|
188
188
|
route: '/',
|
|
189
189
|
status_code: 200,
|
|
190
|
-
|
|
190
|
+
timing: 1,
|
|
191
191
|
},
|
|
192
192
|
request_id: 1,
|
|
193
193
|
)
|
|
@@ -204,7 +204,7 @@ RSpec.describe Airbrake do
|
|
|
204
204
|
method: 'GET',
|
|
205
205
|
route: '/',
|
|
206
206
|
status_code: 200,
|
|
207
|
-
|
|
207
|
+
timing: 1,
|
|
208
208
|
},
|
|
209
209
|
request_id: 1,
|
|
210
210
|
)
|
|
@@ -222,7 +222,7 @@ RSpec.describe Airbrake do
|
|
|
222
222
|
method: 'GET',
|
|
223
223
|
route: '/',
|
|
224
224
|
query: '',
|
|
225
|
-
|
|
225
|
+
timing: 1,
|
|
226
226
|
)
|
|
227
227
|
end
|
|
228
228
|
end
|
|
@@ -238,7 +238,7 @@ RSpec.describe Airbrake do
|
|
|
238
238
|
method: 'GET',
|
|
239
239
|
route: '/',
|
|
240
240
|
query: '',
|
|
241
|
-
|
|
241
|
+
timing: 1,
|
|
242
242
|
},
|
|
243
243
|
request_id: 1,
|
|
244
244
|
)
|
|
@@ -255,7 +255,7 @@ RSpec.describe Airbrake do
|
|
|
255
255
|
method: 'GET',
|
|
256
256
|
route: '/',
|
|
257
257
|
query: '',
|
|
258
|
-
|
|
258
|
+
timing: 1,
|
|
259
259
|
},
|
|
260
260
|
request_id: 1,
|
|
261
261
|
)
|
|
@@ -273,7 +273,7 @@ RSpec.describe Airbrake do
|
|
|
273
273
|
method: 'GET',
|
|
274
274
|
route: '/',
|
|
275
275
|
query: '',
|
|
276
|
-
|
|
276
|
+
timing: 1,
|
|
277
277
|
)
|
|
278
278
|
end
|
|
279
279
|
end
|
|
@@ -292,7 +292,7 @@ RSpec.describe Airbrake do
|
|
|
292
292
|
route: '/',
|
|
293
293
|
response_type: :html,
|
|
294
294
|
groups: {},
|
|
295
|
-
|
|
295
|
+
timing: 1,
|
|
296
296
|
},
|
|
297
297
|
request_id: 1,
|
|
298
298
|
)
|
|
@@ -310,7 +310,7 @@ RSpec.describe Airbrake do
|
|
|
310
310
|
route: '/',
|
|
311
311
|
response_type: :html,
|
|
312
312
|
groups: {},
|
|
313
|
-
|
|
313
|
+
timing: 1,
|
|
314
314
|
},
|
|
315
315
|
request_id: 1,
|
|
316
316
|
)
|
data/spec/config_spec.rb
CHANGED
|
@@ -22,6 +22,7 @@ RSpec.describe Airbrake::Config do
|
|
|
22
22
|
its(:performance_stats) { is_expected.to eq(true) }
|
|
23
23
|
its(:performance_stats_flush_period) { is_expected.to eq(15) }
|
|
24
24
|
its(:query_stats) { is_expected.to eq(true) }
|
|
25
|
+
its(:job_stats) { is_expected.to eq(true) }
|
|
25
26
|
|
|
26
27
|
describe "#new" do
|
|
27
28
|
context "when user config is passed" do
|
|
@@ -110,9 +111,7 @@ RSpec.describe Airbrake::Config do
|
|
|
110
111
|
|
|
111
112
|
describe "#check_performance_options" do
|
|
112
113
|
it "returns a promise" do
|
|
113
|
-
resource = Airbrake::Query.new(
|
|
114
|
-
method: '', route: '', query: '', start_time: Time.now,
|
|
115
|
-
)
|
|
114
|
+
resource = Airbrake::Query.new(method: '', route: '', query: '', timing: 1)
|
|
116
115
|
expect(subject.check_performance_options(resource))
|
|
117
116
|
.to be_an(Airbrake::Promise)
|
|
118
117
|
end
|
|
@@ -122,7 +121,7 @@ RSpec.describe Airbrake::Config do
|
|
|
122
121
|
|
|
123
122
|
let(:resource) do
|
|
124
123
|
Airbrake::Request.new(
|
|
125
|
-
method: 'GET', route: '/foo', status_code: 200,
|
|
124
|
+
method: 'GET', route: '/foo', status_code: 200, timing: 1,
|
|
126
125
|
)
|
|
127
126
|
end
|
|
128
127
|
|
|
@@ -138,9 +137,7 @@ RSpec.describe Airbrake::Config do
|
|
|
138
137
|
before { subject.query_stats = false }
|
|
139
138
|
|
|
140
139
|
let(:resource) do
|
|
141
|
-
Airbrake::Query.new(
|
|
142
|
-
method: 'GET', route: '/foo', query: '', start_time: Time.new,
|
|
143
|
-
)
|
|
140
|
+
Airbrake::Query.new(method: 'GET', route: '/foo', query: '', timing: 1)
|
|
144
141
|
end
|
|
145
142
|
|
|
146
143
|
it "returns a rejected promise" do
|
|
@@ -150,5 +147,20 @@ RSpec.describe Airbrake::Config do
|
|
|
150
147
|
)
|
|
151
148
|
end
|
|
152
149
|
end
|
|
150
|
+
|
|
151
|
+
context "when job stats are disabled" do
|
|
152
|
+
before { subject.job_stats = false }
|
|
153
|
+
|
|
154
|
+
let(:resource) do
|
|
155
|
+
Airbrake::Queue.new(queue: 'foo_queue', error_count: 0, timing: 1)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
it "returns a rejected promise" do
|
|
159
|
+
promise = subject.check_performance_options(resource)
|
|
160
|
+
expect(promise.value).to eq(
|
|
161
|
+
'error' => "The Job Stats feature is disabled",
|
|
162
|
+
)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
153
165
|
end
|
|
154
166
|
end
|
|
@@ -13,9 +13,7 @@ RSpec.describe Airbrake::Filters::SqlFilter do
|
|
|
13
13
|
shared_examples "query blacklisting" do |query, opts|
|
|
14
14
|
it "ignores '#{query}'" do
|
|
15
15
|
filter = described_class.new('postgres')
|
|
16
|
-
q = Airbrake::Query.new(
|
|
17
|
-
query: query, method: 'GET', route: '/', start_time: Time.now,
|
|
18
|
-
)
|
|
16
|
+
q = Airbrake::Query.new(query: query, method: 'GET', route: '/', timing: 1)
|
|
19
17
|
filter.call(q)
|
|
20
18
|
|
|
21
19
|
expect(q.ignored?).to eq(opts[:should_ignore])
|
|
@@ -328,9 +328,9 @@ RSpec.describe Airbrake::NoticeNotifier do
|
|
|
328
328
|
end
|
|
329
329
|
|
|
330
330
|
it "raises error" do
|
|
331
|
-
expect { subject.build_notice(Exception.new) }.to raise_error(
|
|
331
|
+
expect { subject.build_notice(Exception.new('oops')) }.to raise_error(
|
|
332
332
|
Airbrake::Error,
|
|
333
|
-
|
|
333
|
+
"Airbrake is closed; can't build exception: Exception: oops",
|
|
334
334
|
)
|
|
335
335
|
end
|
|
336
336
|
end
|
|
@@ -16,6 +16,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
16
16
|
performance_stats: true,
|
|
17
17
|
performance_stats_flush_period: 0,
|
|
18
18
|
query_stats: true,
|
|
19
|
+
job_stats: true,
|
|
19
20
|
)
|
|
20
21
|
end
|
|
21
22
|
|
|
@@ -29,8 +30,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
29
30
|
func: 'foo',
|
|
30
31
|
file: 'foo.rb',
|
|
31
32
|
line: 123,
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
timing: 60000,
|
|
34
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
34
35
|
),
|
|
35
36
|
)
|
|
36
37
|
subject.close
|
|
@@ -59,8 +60,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
59
60
|
method: 'POST',
|
|
60
61
|
route: '/foo',
|
|
61
62
|
status_code: 200,
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
timing: 60000,
|
|
64
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
64
65
|
),
|
|
65
66
|
)
|
|
66
67
|
subject.close
|
|
@@ -86,8 +87,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
86
87
|
method: 'DELETE',
|
|
87
88
|
route: '/routes-breakdowns',
|
|
88
89
|
response_type: 'json',
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
timing: 60000,
|
|
91
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
91
92
|
groups: { db: 131, view: 421 },
|
|
92
93
|
),
|
|
93
94
|
)
|
|
@@ -128,8 +129,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
128
129
|
queue: 'emails',
|
|
129
130
|
error_count: 2,
|
|
130
131
|
groups: { redis: 131, sql: 421 },
|
|
131
|
-
|
|
132
|
-
|
|
132
|
+
timing: 60000,
|
|
133
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
133
134
|
),
|
|
134
135
|
)
|
|
135
136
|
subject.close
|
|
@@ -168,7 +169,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
168
169
|
method: 'GET',
|
|
169
170
|
route: '/foo',
|
|
170
171
|
status_code: 200,
|
|
171
|
-
|
|
172
|
+
timing: 60000,
|
|
173
|
+
time: Time.new(2018, 1, 1, 0, 0, 20, 0),
|
|
172
174
|
),
|
|
173
175
|
)
|
|
174
176
|
subject.close
|
|
@@ -184,7 +186,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
184
186
|
method: 'GET',
|
|
185
187
|
route: '/foo',
|
|
186
188
|
status_code: 200,
|
|
187
|
-
|
|
189
|
+
timing: 213,
|
|
188
190
|
),
|
|
189
191
|
)
|
|
190
192
|
subject.notify(
|
|
@@ -192,7 +194,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
192
194
|
method: 'GET',
|
|
193
195
|
route: '/foo',
|
|
194
196
|
status_code: 200,
|
|
195
|
-
|
|
197
|
+
timing: 123,
|
|
196
198
|
),
|
|
197
199
|
)
|
|
198
200
|
subject.close
|
|
@@ -208,8 +210,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
208
210
|
method: 'GET',
|
|
209
211
|
route: '/foo',
|
|
210
212
|
status_code: 200,
|
|
211
|
-
|
|
212
|
-
|
|
213
|
+
timing: 1000,
|
|
214
|
+
time: Time.new(2018, 1, 1, 0, 0, 49, 0),
|
|
213
215
|
),
|
|
214
216
|
)
|
|
215
217
|
subject.notify(
|
|
@@ -217,8 +219,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
217
219
|
method: 'GET',
|
|
218
220
|
route: '/foo',
|
|
219
221
|
status_code: 200,
|
|
220
|
-
|
|
221
|
-
|
|
222
|
+
timing: 6000,
|
|
223
|
+
time: Time.new(2018, 1, 1, 0, 1, 49, 0),
|
|
222
224
|
),
|
|
223
225
|
)
|
|
224
226
|
subject.close
|
|
@@ -244,8 +246,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
244
246
|
method: 'GET',
|
|
245
247
|
route: '/foo',
|
|
246
248
|
status_code: 200,
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
timing: 60000,
|
|
250
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
249
251
|
),
|
|
250
252
|
)
|
|
251
253
|
subject.notify(
|
|
@@ -253,8 +255,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
253
255
|
method: 'POST',
|
|
254
256
|
route: '/foo',
|
|
255
257
|
status_code: 200,
|
|
256
|
-
|
|
257
|
-
|
|
258
|
+
timing: 60000,
|
|
259
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
258
260
|
),
|
|
259
261
|
)
|
|
260
262
|
subject.close
|
|
@@ -280,8 +282,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
280
282
|
method: 'DELETE',
|
|
281
283
|
route: '/routes-breakdowns',
|
|
282
284
|
response_type: 'json',
|
|
283
|
-
|
|
284
|
-
|
|
285
|
+
timing: 2000,
|
|
286
|
+
time: Time.new(2018, 1, 1, 0, 0, 20, 0),
|
|
285
287
|
groups: { db: 131, view: 421 },
|
|
286
288
|
),
|
|
287
289
|
)
|
|
@@ -290,8 +292,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
290
292
|
method: 'DELETE',
|
|
291
293
|
route: '/routes-breakdowns',
|
|
292
294
|
response_type: 'json',
|
|
293
|
-
|
|
294
|
-
|
|
295
|
+
timing: 2000,
|
|
296
|
+
time: Time.new(2018, 1, 1, 0, 0, 30, 0),
|
|
295
297
|
groups: { db: 55, view: 11 },
|
|
296
298
|
),
|
|
297
299
|
)
|
|
@@ -332,8 +334,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
332
334
|
queue: 'emails',
|
|
333
335
|
error_count: 2,
|
|
334
336
|
groups: { redis: 131, sql: 421 },
|
|
335
|
-
|
|
336
|
-
|
|
337
|
+
timing: 60000,
|
|
338
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
337
339
|
),
|
|
338
340
|
)
|
|
339
341
|
subject.notify(
|
|
@@ -341,8 +343,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
341
343
|
queue: 'emails',
|
|
342
344
|
error_count: 3,
|
|
343
345
|
groups: { redis: 131, sql: 421 },
|
|
344
|
-
|
|
345
|
-
|
|
346
|
+
timing: 60000,
|
|
347
|
+
time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
346
348
|
),
|
|
347
349
|
)
|
|
348
350
|
subject.close
|
|
@@ -381,7 +383,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
381
383
|
method: 'GET',
|
|
382
384
|
route: '/foo',
|
|
383
385
|
status_code: 200,
|
|
384
|
-
|
|
386
|
+
timing: 123,
|
|
385
387
|
),
|
|
386
388
|
)
|
|
387
389
|
subject.close
|
|
@@ -392,7 +394,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
392
394
|
|
|
393
395
|
it "checks performance stat configuration" do
|
|
394
396
|
request = Airbrake::Request.new(
|
|
395
|
-
method: 'GET', route: '/foo', status_code: 200,
|
|
397
|
+
method: 'GET', route: '/foo', status_code: 200, timing: 123,
|
|
396
398
|
)
|
|
397
399
|
expect(Airbrake::Config.instance).to receive(:check_performance_options)
|
|
398
400
|
.with(request).and_return(Airbrake::Promise.new)
|
|
@@ -408,7 +410,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
408
410
|
method: 'POST',
|
|
409
411
|
route: '/foo',
|
|
410
412
|
status_code: 200,
|
|
411
|
-
|
|
413
|
+
timing: 123,
|
|
412
414
|
),
|
|
413
415
|
)
|
|
414
416
|
subject.close
|
|
@@ -445,7 +447,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
445
447
|
method: 'GET',
|
|
446
448
|
route: '/foo',
|
|
447
449
|
status_code: 200,
|
|
448
|
-
|
|
450
|
+
timing: 123,
|
|
449
451
|
),
|
|
450
452
|
)
|
|
451
453
|
|
|
@@ -454,7 +456,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
454
456
|
method: 'POST',
|
|
455
457
|
route: '/foo',
|
|
456
458
|
query: 'SELECT * FROM things',
|
|
457
|
-
|
|
459
|
+
timing: 123,
|
|
458
460
|
),
|
|
459
461
|
)
|
|
460
462
|
|
|
@@ -474,7 +476,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
474
476
|
method: 'GET',
|
|
475
477
|
route: '/foo',
|
|
476
478
|
status_code: 200,
|
|
477
|
-
|
|
479
|
+
timing: 1,
|
|
478
480
|
),
|
|
479
481
|
)
|
|
480
482
|
subject.close
|
|
@@ -488,13 +490,29 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
488
490
|
method: 'POST',
|
|
489
491
|
route: '/foo',
|
|
490
492
|
query: 'SELECT * FROM things',
|
|
491
|
-
|
|
493
|
+
timing: 1,
|
|
492
494
|
),
|
|
493
495
|
)
|
|
494
496
|
subject.close
|
|
495
497
|
|
|
496
498
|
expect(a_request(:put, queries)).not_to have_been_made
|
|
497
499
|
end
|
|
500
|
+
|
|
501
|
+
it "returns a rejected promise" do
|
|
502
|
+
promise = subject.notify(
|
|
503
|
+
Airbrake::Query.new(
|
|
504
|
+
method: 'POST',
|
|
505
|
+
route: '/foo',
|
|
506
|
+
query: 'SELECT * FROM things',
|
|
507
|
+
timing: 1,
|
|
508
|
+
),
|
|
509
|
+
)
|
|
510
|
+
subject.close
|
|
511
|
+
|
|
512
|
+
expect(promise.value).to eq(
|
|
513
|
+
'error' => 'Airbrake::Query was ignored by a filter',
|
|
514
|
+
)
|
|
515
|
+
end
|
|
498
516
|
end
|
|
499
517
|
|
|
500
518
|
context "when a filter that modifies payload was defined" do
|
|
@@ -510,7 +528,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
510
528
|
method: 'POST',
|
|
511
529
|
route: '/foo',
|
|
512
530
|
query: 'SELECT * FROM things',
|
|
513
|
-
|
|
531
|
+
timing: 123,
|
|
514
532
|
),
|
|
515
533
|
)
|
|
516
534
|
subject.close
|
|
@@ -522,6 +540,49 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
522
540
|
).to have_been_made
|
|
523
541
|
end
|
|
524
542
|
end
|
|
543
|
+
|
|
544
|
+
context "when :start_time is specified (deprecated)" do
|
|
545
|
+
before do
|
|
546
|
+
allow(Kernel).to receive(:warn)
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
it "uses the value of :start_time to update stat" do
|
|
550
|
+
subject.notify(
|
|
551
|
+
Airbrake::Query.new(
|
|
552
|
+
method: 'POST',
|
|
553
|
+
route: '/foo',
|
|
554
|
+
query: 'SELECT * FROM things',
|
|
555
|
+
start_time: Time.new(2018, 1, 1, 0, 49, 0, 0),
|
|
556
|
+
end_time: Time.new(2018, 1, 1, 0, 50, 0, 0),
|
|
557
|
+
),
|
|
558
|
+
)
|
|
559
|
+
subject.close
|
|
560
|
+
|
|
561
|
+
expect(
|
|
562
|
+
a_request(:put, queries).with(
|
|
563
|
+
body: /"count":1,"sum":60000.0,"sumsq":3600000000.0/,
|
|
564
|
+
),
|
|
565
|
+
).to have_been_made
|
|
566
|
+
end
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
context "when provided :timing is zero" do
|
|
570
|
+
it "doesn't notify" do
|
|
571
|
+
queue = Airbrake::Queue.new(queue: 'bananas', error_count: 0, timing: 0)
|
|
572
|
+
subject.notify(queue)
|
|
573
|
+
subject.close
|
|
574
|
+
|
|
575
|
+
expect(a_request(:put, queues)).not_to have_been_made
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
it "returns a rejected promise" do
|
|
579
|
+
queue = Airbrake::Queue.new(queue: 'bananas', error_count: 0, timing: 0)
|
|
580
|
+
promise = subject.notify(queue)
|
|
581
|
+
subject.close
|
|
582
|
+
|
|
583
|
+
expect(promise.value).to eq('error' => ':timing cannot be zero')
|
|
584
|
+
end
|
|
585
|
+
end
|
|
525
586
|
end
|
|
526
587
|
|
|
527
588
|
describe "#notify_sync" do
|
|
@@ -531,7 +592,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
531
592
|
method: 'POST',
|
|
532
593
|
route: '/foo',
|
|
533
594
|
query: 'SELECT * FROM things',
|
|
534
|
-
|
|
595
|
+
timing: 123,
|
|
535
596
|
),
|
|
536
597
|
)
|
|
537
598
|
|
|
@@ -560,7 +621,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
560
621
|
method: 'POST',
|
|
561
622
|
route: '/foo',
|
|
562
623
|
query: 'SELECT * FROM things',
|
|
563
|
-
|
|
624
|
+
timing: 123,
|
|
564
625
|
),
|
|
565
626
|
)
|
|
566
627
|
subject.close
|
|
@@ -591,7 +652,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
|
591
652
|
method: 'POST',
|
|
592
653
|
route: '/foo',
|
|
593
654
|
status_code: 200,
|
|
594
|
-
|
|
655
|
+
timing: 123,
|
|
595
656
|
),
|
|
596
657
|
)
|
|
597
658
|
subject.close
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: airbrake-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.12.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Airbrake Technologies, Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2020-01-07 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rbtree3
|