airbrake-ruby 4.10.1 → 4.12.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|