airbrake-ruby 4.8.0-java → 4.9.0-java

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 775c69e72c377a245982fca5bef3460af77b6c37d82988432fc09f2820e01fc6
4
- data.tar.gz: 83493c7a39f6eea49668f7c94fc202c90d55efcc1d4822864a70cca03c96134f
3
+ metadata.gz: 1e05d33daf76111bb1a55538d29cba82f1ac99c97578ee07843af8b88750b7a5
4
+ data.tar.gz: e7e11e55e646e58d8740a7ce6f97e0b7f3f27437f732c6d348be24df409a3ad2
5
5
  SHA512:
6
- metadata.gz: 3e99d7a4dbca2de4e45a63d0991856e68a6d4250979b2989208597ba65f6f6559aab001702cd0d2140902b15b3f87bb6c75a21b3c9c97a272f68b4d62922a4e8
7
- data.tar.gz: 030edc9303bd0f1042a6aa3f3ec5b672ab58598fee90a71e6d7f6a6fed84716d2043afab9edf46b3bdd6ee9939ef6b979ad78dc37575be774663ac84e8af73a7
6
+ metadata.gz: f8b47d08818f4dec1b1d3ed5e381e10392e1da33677894e8a10d2e07c9ede4b1adffeab060a931b13da9f26f4d6f9f5ff25b9ec6beba677a674528260246fd0c
7
+ data.tar.gz: 4a77aa66088214bddeab8b4c7eac2c82a3f1f7354fe6d37c8e679c4e46a16efde2c753ee3fb02397612f0ea1c93e8430968057aa70b45a6e0a97658158346d46
@@ -9,6 +9,8 @@ require 'time'
9
9
  require 'airbrake-ruby/version'
10
10
  require 'airbrake-ruby/loggable'
11
11
  require 'airbrake-ruby/stashable'
12
+ require 'airbrake-ruby/mergeable'
13
+ require 'airbrake-ruby/grouppable'
12
14
  require 'airbrake-ruby/config'
13
15
  require 'airbrake-ruby/config/validator'
14
16
  require 'airbrake-ruby/promise'
@@ -52,6 +54,7 @@ require 'airbrake-ruby/performance_breakdown'
52
54
  require 'airbrake-ruby/benchmark'
53
55
  require 'airbrake-ruby/monotonic_time'
54
56
  require 'airbrake-ruby/timed_trace'
57
+ require 'airbrake-ruby/queue'
55
58
 
56
59
  # Airbrake is a thin wrapper around instances of the notifier classes (such as
57
60
  # notice, performance & deploy notifiers). It creates a way to access them via a
@@ -69,6 +72,7 @@ require 'airbrake-ruby/timed_trace'
69
72
  #
70
73
  # @since v1.0.0
71
74
  # @api public
75
+ # rubocop:disable Metrics/ModuleLength
72
76
  module Airbrake
73
77
  # The general error that this library uses when it wants to raise.
74
78
  Error = Class.new(StandardError)
@@ -423,6 +427,31 @@ module Airbrake
423
427
  performance_notifier.notify(performance_breakdown)
424
428
  end
425
429
 
430
+ # Increments statistics of a certain queue (worker).
431
+ #
432
+ # @example
433
+ # Airbrake.notify_queue(
434
+ # queue: 'emails',
435
+ # error_count: 1,
436
+ # groups: { redis: 24.0, sql: 0.4 } # ms
437
+ # )
438
+ #
439
+ # @param [Hash{Symbol=>Object}] queue_info
440
+ # @option queue_info [String] :queue The name of the queue/worker
441
+ # @option queue_info [Integer] :error_count How many times this worker
442
+ # failed
443
+ # @option queue_info [Array<Hash{Symbol=>Float}>] :groups Where the job
444
+ # spent its time
445
+ # @param [Hash] stash What needs to be appeneded to the stash, so it's
446
+ # available in filters
447
+ # @return [void]
448
+ # @since v4.9.0
449
+ def notify_queue(queue_info, stash = {})
450
+ queue = Queue.new(queue_info)
451
+ queue.stash.merge!(stash)
452
+ performance_notifier.notify(queue)
453
+ end
454
+
426
455
  # Runs a callback before {.notify_request} or {.notify_query} kicks in. This
427
456
  # is useful if you want to ignore specific resources or filter the data the
428
457
  # resource contains.
@@ -513,3 +542,4 @@ module Airbrake
513
542
  end
514
543
  end
515
544
  end
545
+ # rubocop:enable Metrics/ModuleLength
@@ -0,0 +1,12 @@
1
+ module Airbrake
2
+ # Grouppable adds the `#groups` method, so that we don't need to define it in
3
+ # all of performance models every time we add a model without groups.
4
+ #
5
+ # @since 4.9.0
6
+ # @api private
7
+ module Grouppable
8
+ def groups
9
+ {}
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ module Airbrake
2
+ # Mergeable adds the `#merge` method, so that we don't need to define it in
3
+ # all of performance models every time we add a model.
4
+ #
5
+ # @since 4.9.0
6
+ # @api private
7
+ module Mergeable
8
+ def merge(_other)
9
+ nil
10
+ end
11
+ end
12
+ end
@@ -12,6 +12,7 @@ module Airbrake
12
12
  include HashKeyable
13
13
  include Ignorable
14
14
  include Stashable
15
+ include Mergeable
15
16
 
16
17
  def initialize(
17
18
  method:,
@@ -61,7 +61,12 @@ module Airbrake
61
61
  private
62
62
 
63
63
  def update_payload(resource)
64
- @payload[resource] ||= { total: Airbrake::Stat.new }
64
+ if (total_stat = @payload[resource])
65
+ @payload.key(total_stat).merge(resource)
66
+ else
67
+ @payload[resource] = { total: Airbrake::Stat.new }
68
+ end
69
+
65
70
  @payload[resource][:total].increment(resource.start_time, resource.end_time)
66
71
 
67
72
  resource.groups.each do |name, ms|
@@ -11,6 +11,8 @@ module Airbrake
11
11
  include HashKeyable
12
12
  include Ignorable
13
13
  include Stashable
14
+ include Mergeable
15
+ include Grouppable
14
16
 
15
17
  def initialize(
16
18
  method:,
@@ -34,10 +36,6 @@ module Airbrake
34
36
  'queries'
35
37
  end
36
38
 
37
- def groups
38
- {}
39
- end
40
-
41
39
  def to_h
42
40
  {
43
41
  'method' => method,
@@ -0,0 +1,52 @@
1
+ module Airbrake
2
+ # Queue represents a queue (worker).
3
+ #
4
+ # @see Airbrake.notify_queue
5
+ # @api public
6
+ # @since v4.9.0
7
+ # rubocop:disable Metrics/BlockLength
8
+ Queue = Struct.new(:queue, :error_count, :groups, :start_time, :end_time) do
9
+ include HashKeyable
10
+ include Ignorable
11
+ include Stashable
12
+
13
+ def initialize(
14
+ queue:,
15
+ error_count:,
16
+ groups: {},
17
+ start_time: Time.now,
18
+ end_time: Time.now
19
+ )
20
+ @start_time_utc = TimeTruncate.utc_truncate_minutes(start_time)
21
+ super(queue, error_count, groups, start_time, end_time)
22
+ end
23
+
24
+ def destination
25
+ 'queues-stats'
26
+ end
27
+
28
+ def cargo
29
+ 'queues'
30
+ end
31
+
32
+ def to_h
33
+ {
34
+ 'queue' => queue,
35
+ 'errorCount' => error_count,
36
+ 'time' => @start_time_utc
37
+ }
38
+ end
39
+
40
+ def hash
41
+ {
42
+ 'queue' => queue,
43
+ 'time' => @start_time_utc
44
+ }.hash
45
+ end
46
+
47
+ def merge(other)
48
+ self.error_count += other.error_count
49
+ end
50
+ end
51
+ # rubocop:enable Metrics/BlockLength
52
+ end
@@ -9,6 +9,8 @@ module Airbrake
9
9
  include HashKeyable
10
10
  include Ignorable
11
11
  include Stashable
12
+ include Mergeable
13
+ include Grouppable
12
14
 
13
15
  def initialize(
14
16
  method:,
@@ -29,10 +31,6 @@ module Airbrake
29
31
  'routes'
30
32
  end
31
33
 
32
- def groups
33
- {}
34
- end
35
-
36
34
  def to_h
37
35
  {
38
36
  'method' => method,
@@ -2,5 +2,5 @@
2
2
  # More information: http://semver.org/
3
3
  module Airbrake
4
4
  # @return [String] the library version
5
- AIRBRAKE_RUBY_VERSION = '4.8.0'.freeze
5
+ AIRBRAKE_RUBY_VERSION = '4.9.0'.freeze
6
6
  end
@@ -303,6 +303,37 @@ RSpec.describe Airbrake do
303
303
  end
304
304
  end
305
305
 
306
+ describe "#notify_queue" do
307
+ context "when :stash key is not provided" do
308
+ it "doesn't add anything to the stash of the queue" do
309
+ expect(described_class.performance_notifier).to receive(:notify) do |queue|
310
+ expect(queue.stash).to be_empty
311
+ end
312
+
313
+ described_class.notify_queue(
314
+ queue: 'bananas',
315
+ error_count: 10
316
+ )
317
+ end
318
+ end
319
+
320
+ context "when :stash key is provided" do
321
+ it "adds the value as the stash of the queue" do
322
+ expect(described_class.performance_notifier).to receive(:notify) do |queue|
323
+ expect(queue.stash).to eq(request_id: 1)
324
+ end
325
+
326
+ described_class.notify_queue(
327
+ {
328
+ queue: 'bananas',
329
+ error_count: 10
330
+ },
331
+ request_id: 1
332
+ )
333
+ end
334
+ end
335
+ end
336
+
306
337
  describe ".performance_notifier" do
307
338
  it "returns a performance notifier" do
308
339
  expect(described_class.performance_notifier)
@@ -2,11 +2,13 @@ RSpec.describe Airbrake::PerformanceNotifier do
2
2
  let(:routes) { 'https://api.airbrake.io/api/v5/projects/1/routes-stats' }
3
3
  let(:queries) { 'https://api.airbrake.io/api/v5/projects/1/queries-stats' }
4
4
  let(:breakdowns) { 'https://api.airbrake.io/api/v5/projects/1/routes-breakdowns' }
5
+ let(:queues) { 'https://api.airbrake.io/api/v5/projects/1/queues-stats' }
5
6
 
6
7
  before do
7
8
  stub_request(:put, routes).to_return(status: 200, body: '')
8
9
  stub_request(:put, queries).to_return(status: 200, body: '')
9
10
  stub_request(:put, breakdowns).to_return(status: 200, body: '')
11
+ stub_request(:put, queues).to_return(status: 200, body: '')
10
12
 
11
13
  Airbrake::Config.instance = Airbrake::Config.new(
12
14
  project_id: 1,
@@ -120,6 +122,46 @@ RSpec.describe Airbrake::PerformanceNotifier do
120
122
  ).to have_been_made
121
123
  end
122
124
 
125
+ it "sends full queue" do
126
+ subject.notify(
127
+ Airbrake::Queue.new(
128
+ queue: 'emails',
129
+ error_count: 2,
130
+ groups: { redis: 131, sql: 421 },
131
+ start_time: Time.new(2018, 1, 1, 0, 49, 0, 0),
132
+ end_time: Time.new(2018, 1, 1, 0, 50, 0, 0)
133
+ )
134
+ )
135
+ subject.close
136
+
137
+ expect(
138
+ a_request(:put, queues).with(body: /
139
+ \A{"queues":\[{
140
+ "queue":"emails",
141
+ "errorCount":2,
142
+ "time":"2018-01-01T00:49:00\+00:00",
143
+ "count":1,
144
+ "sum":60000.0,
145
+ "sumsq":3600000000.0,
146
+ "tdigest":"AAAAAkA0AAAAAAAAAAAAAUdqYAAB",
147
+ "groups":{
148
+ "redis":{
149
+ "count":1,
150
+ "sum":131.0,
151
+ "sumsq":17161.0,
152
+ "tdigest":"AAAAAkA0AAAAAAAAAAAAAUMDAAAB"
153
+ },
154
+ "sql":{
155
+ "count":1,
156
+ "sum":421.0,
157
+ "sumsq":177241.0,
158
+ "tdigest":"AAAAAkA0AAAAAAAAAAAAAUPSgAAB"
159
+ }
160
+ }
161
+ }\]}\z/x)
162
+ ).to have_been_made
163
+ end
164
+
123
165
  it "rounds time to the floor minute" do
124
166
  subject.notify(
125
167
  Airbrake::Request.new(
@@ -284,6 +326,55 @@ RSpec.describe Airbrake::PerformanceNotifier do
284
326
  ).to have_been_made
285
327
  end
286
328
 
329
+ it "groups queues by queue key" do
330
+ subject.notify(
331
+ Airbrake::Queue.new(
332
+ queue: 'emails',
333
+ error_count: 2,
334
+ groups: { redis: 131, sql: 421 },
335
+ start_time: Time.new(2018, 1, 1, 0, 49, 0, 0),
336
+ end_time: Time.new(2018, 1, 1, 0, 50, 0, 0)
337
+ )
338
+ )
339
+ subject.notify(
340
+ Airbrake::Queue.new(
341
+ queue: 'emails',
342
+ error_count: 3,
343
+ groups: { redis: 131, sql: 421 },
344
+ start_time: Time.new(2018, 1, 1, 0, 49, 0, 0),
345
+ end_time: Time.new(2018, 1, 1, 0, 50, 0, 0)
346
+ )
347
+ )
348
+ subject.close
349
+
350
+ expect(
351
+ a_request(:put, queues).with(body: /
352
+ \A{"queues":\[{
353
+ "queue":"emails",
354
+ "errorCount":5,
355
+ "time":"2018-01-01T00:49:00\+00:00",
356
+ "count":2,
357
+ "sum":120000.0,
358
+ "sumsq":7200000000.0,
359
+ "tdigest":"AAAAAkA0AAAAAAAAAAAAAUdqYAAC",
360
+ "groups":{
361
+ "redis":{
362
+ "count":2,
363
+ "sum":262.0,
364
+ "sumsq":34322.0,
365
+ "tdigest":"AAAAAkA0AAAAAAAAAAAAAUMDAAAC"
366
+ },
367
+ "sql":{
368
+ "count":2,
369
+ "sum":842.0,
370
+ "sumsq":354482.0,
371
+ "tdigest":"AAAAAkA0AAAAAAAAAAAAAUPSgAAC"
372
+ }
373
+ }
374
+ }\]}\z/x)
375
+ ).to have_been_made
376
+ end
377
+
287
378
  it "returns a promise" do
288
379
  promise = subject.notify(
289
380
  Airbrake::Request.new(
@@ -0,0 +1,11 @@
1
+ RSpec.describe Airbrake::Queue do
2
+ subject { described_class.new(queue: 'bananas', error_count: 0) }
3
+
4
+ describe "#ignore" do
5
+ it { is_expected.to respond_to(:ignore!) }
6
+ end
7
+
8
+ describe "#stash" do
9
+ it { is_expected.to respond_to(:stash) }
10
+ end
11
+ end
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.8.0
4
+ version: 4.9.0
5
5
  platform: java
6
6
  authors:
7
7
  - Airbrake Technologies, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-10-23 00:00:00.000000000 Z
11
+ date: 2019-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rbtree-jruby
@@ -62,10 +62,12 @@ files:
62
62
  - lib/airbrake-ruby/filters/sql_filter.rb
63
63
  - lib/airbrake-ruby/filters/system_exit_filter.rb
64
64
  - lib/airbrake-ruby/filters/thread_filter.rb
65
+ - lib/airbrake-ruby/grouppable.rb
65
66
  - lib/airbrake-ruby/hash_keyable.rb
66
67
  - lib/airbrake-ruby/ignorable.rb
67
68
  - lib/airbrake-ruby/inspectable.rb
68
69
  - lib/airbrake-ruby/loggable.rb
70
+ - lib/airbrake-ruby/mergeable.rb
69
71
  - lib/airbrake-ruby/monotonic_time.rb
70
72
  - lib/airbrake-ruby/nested_exception.rb
71
73
  - lib/airbrake-ruby/notice.rb
@@ -74,6 +76,7 @@ files:
74
76
  - lib/airbrake-ruby/performance_notifier.rb
75
77
  - lib/airbrake-ruby/promise.rb
76
78
  - lib/airbrake-ruby/query.rb
79
+ - lib/airbrake-ruby/queue.rb
77
80
  - lib/airbrake-ruby/request.rb
78
81
  - lib/airbrake-ruby/response.rb
79
82
  - lib/airbrake-ruby/stashable.rb
@@ -126,6 +129,7 @@ files:
126
129
  - spec/performance_notifier_spec.rb
127
130
  - spec/promise_spec.rb
128
131
  - spec/query_spec.rb
132
+ - spec/queue_spec.rb
129
133
  - spec/request_spec.rb
130
134
  - spec/response_spec.rb
131
135
  - spec/spec_helper.rb
@@ -203,6 +207,7 @@ test_files:
203
207
  - spec/notice_notifier/options_spec.rb
204
208
  - spec/filter_chain_spec.rb
205
209
  - spec/response_spec.rb
210
+ - spec/queue_spec.rb
206
211
  - spec/code_hunk_spec.rb
207
212
  - spec/fixtures/notroot.txt
208
213
  - spec/fixtures/project_root/long_line.txt