airbrake-ruby 6.0.1-java → 6.0.2-java
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/config.rb +3 -3
- data/lib/airbrake-ruby/filters/sql_filter.rb +6 -6
- data/lib/airbrake-ruby/performance_notifier.rb +38 -38
- data/lib/airbrake-ruby/stat.rb +1 -1
- data/lib/airbrake-ruby/time_truncate.rb +2 -2
- data/lib/airbrake-ruby/version.rb +1 -1
- data/lib/airbrake-ruby.rb +21 -21
- data/spec/config_spec.rb +8 -8
- data/spec/performance_notifier_spec.rb +3 -3
- data/spec/time_truncate_spec.rb +23 -8
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99722e48e1e7d0c25b7daa374be62e44eba21cde2029d4994a80110a5f5909fb
|
4
|
+
data.tar.gz: 6f5e8d2411eee4e18ff97ef7d89b3c4a1c8ebb3ba5ec14fafe24c25e850672b1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1700009af941919c7c755536affac726c452e03f0d064a9c69a478cf7757a0b6b1ced42e87bd7f6bbc15a3bbdec538704621dc46fed97b5295a36be8d6bb2cef
|
7
|
+
data.tar.gz: f8b22c23d2534b1f4dc12dd1b5d8bf970504b297a61421cda6d496ec2f1143ac9eb031e2c1b033e8d8a24b94b634c2a17ea475f9ef13d482be08a419a54b1d98
|
data/lib/airbrake-ruby/config.rb
CHANGED
@@ -248,14 +248,14 @@ module Airbrake
|
|
248
248
|
|
249
249
|
# @return [Promise] resolved promise if neither of the performance options
|
250
250
|
# reject it, false otherwise
|
251
|
-
def check_performance_options(
|
251
|
+
def check_performance_options(metric)
|
252
252
|
promise = Airbrake::Promise.new
|
253
253
|
|
254
254
|
if !performance_stats
|
255
255
|
promise.reject("The Performance Stats feature is disabled")
|
256
|
-
elsif
|
256
|
+
elsif metric.is_a?(Airbrake::Query) && !query_stats
|
257
257
|
promise.reject("The Query Stats feature is disabled")
|
258
|
-
elsif
|
258
|
+
elsif metric.is_a?(Airbrake::Queue) && !job_stats
|
259
259
|
promise.reject("The Job Stats feature is disabled")
|
260
260
|
else
|
261
261
|
promise
|
@@ -108,20 +108,20 @@ module Airbrake
|
|
108
108
|
@regexp = Regexp.union(features)
|
109
109
|
end
|
110
110
|
|
111
|
-
# @param [Airbrake::Query]
|
112
|
-
def call(
|
113
|
-
return unless
|
111
|
+
# @param [Airbrake::Query] metric
|
112
|
+
def call(metric)
|
113
|
+
return unless metric.respond_to?(:query)
|
114
114
|
|
115
|
-
query =
|
115
|
+
query = metric.query
|
116
116
|
if IGNORED_QUERIES.any? { |q| q =~ query }
|
117
|
-
|
117
|
+
metric.ignore!
|
118
118
|
return
|
119
119
|
end
|
120
120
|
|
121
121
|
q = query.gsub(@regexp, FILTERED)
|
122
122
|
q.gsub!(POST_FILTER, FILTERED) if q =~ POST_FILTER
|
123
123
|
q = ERROR_MSG if UNMATCHED_PAIR[@dialect] =~ q
|
124
|
-
|
124
|
+
metric.query = q
|
125
125
|
end
|
126
126
|
end
|
127
127
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Airbrake
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# PerformanceNotifier aggregates performance data and periodically sends it to
|
3
|
+
# Airbrake.
|
4
4
|
#
|
5
5
|
# @api public
|
6
6
|
# @since v3.2.0
|
@@ -21,20 +21,20 @@ module Airbrake
|
|
21
21
|
@has_payload = @payload.new_cond
|
22
22
|
end
|
23
23
|
|
24
|
-
# @param [Hash]
|
24
|
+
# @param [Hash] metric
|
25
25
|
# @see Airbrake.notify_query
|
26
26
|
# @see Airbrake.notify_request
|
27
|
-
def notify(
|
27
|
+
def notify(metric)
|
28
28
|
@payload.synchronize do
|
29
|
-
|
29
|
+
send_metric(metric, sync: false)
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
-
# @param [Hash]
|
33
|
+
# @param [Hash] metric
|
34
34
|
# @since v4.10.0
|
35
35
|
# @see Airbrake.notify_queue_sync
|
36
|
-
def notify_sync(
|
37
|
-
|
36
|
+
def notify_sync(metric)
|
37
|
+
send_metric(metric, sync: true).value
|
38
38
|
end
|
39
39
|
|
40
40
|
# @see Airbrake.add_performance_filter
|
@@ -78,16 +78,16 @@ module Airbrake
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
-
def
|
82
|
-
promise = check_configuration(
|
81
|
+
def send_metric(metric, sync:)
|
82
|
+
promise = check_configuration(metric)
|
83
83
|
return promise if promise.rejected?
|
84
84
|
|
85
|
-
@filter_chain.refine(
|
86
|
-
if
|
87
|
-
return Promise.new.reject("#{
|
85
|
+
@filter_chain.refine(metric)
|
86
|
+
if metric.ignored?
|
87
|
+
return Promise.new.reject("#{metric.class} was ignored by a filter")
|
88
88
|
end
|
89
89
|
|
90
|
-
update_payload(
|
90
|
+
update_payload(metric)
|
91
91
|
if sync || @flush_period == 0
|
92
92
|
send(@sync_sender, @payload, promise)
|
93
93
|
else
|
@@ -96,29 +96,29 @@ module Airbrake
|
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
|
-
def update_payload(
|
100
|
-
if (total_stat = @payload[
|
101
|
-
@payload.key(total_stat).merge(
|
99
|
+
def update_payload(metric)
|
100
|
+
if (total_stat = @payload[metric])
|
101
|
+
@payload.key(total_stat).merge(metric)
|
102
102
|
else
|
103
|
-
@payload[
|
103
|
+
@payload[metric] = { total: Airbrake::Stat.new }
|
104
104
|
end
|
105
105
|
|
106
|
-
@payload[
|
106
|
+
@payload[metric][:total].increment_ms(metric.timing)
|
107
107
|
|
108
|
-
|
109
|
-
@payload[
|
110
|
-
@payload[
|
108
|
+
metric.groups.each do |name, ms|
|
109
|
+
@payload[metric][name] ||= Airbrake::Stat.new
|
110
|
+
@payload[metric][name].increment_ms(ms)
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
def check_configuration(
|
114
|
+
def check_configuration(metric)
|
115
115
|
promise = @config.check_configuration
|
116
116
|
return promise if promise.rejected?
|
117
117
|
|
118
|
-
promise = @config.check_performance_options(
|
118
|
+
promise = @config.check_performance_options(metric)
|
119
119
|
return promise if promise.rejected?
|
120
120
|
|
121
|
-
if
|
121
|
+
if metric.timing && metric.timing == 0
|
122
122
|
return Promise.new.reject(':timing cannot be zero')
|
123
123
|
end
|
124
124
|
|
@@ -128,47 +128,47 @@ module Airbrake
|
|
128
128
|
def send(sender, payload, promise)
|
129
129
|
raise "payload cannot be empty. Race?" if payload.none?
|
130
130
|
|
131
|
-
with_grouped_payload(payload) do |
|
131
|
+
with_grouped_payload(payload) do |metric_hash, destination|
|
132
132
|
url = URI.join(
|
133
133
|
@config.apm_host,
|
134
134
|
"api/v5/projects/#{@config.project_id}/#{destination}",
|
135
135
|
)
|
136
136
|
|
137
137
|
logger.debug do
|
138
|
-
"#{LOG_LABEL} #{self.class.name}##{__method__}: #{
|
138
|
+
"#{LOG_LABEL} #{self.class.name}##{__method__}: #{metric_hash}"
|
139
139
|
end
|
140
|
-
sender.send(
|
140
|
+
sender.send(metric_hash, promise, url)
|
141
141
|
end
|
142
142
|
|
143
143
|
promise
|
144
144
|
end
|
145
145
|
|
146
146
|
def with_grouped_payload(raw_payload)
|
147
|
-
grouped_payload = raw_payload.group_by do |
|
148
|
-
[
|
147
|
+
grouped_payload = raw_payload.group_by do |metric, _stats|
|
148
|
+
[metric.cargo, metric.destination]
|
149
149
|
end
|
150
150
|
|
151
|
-
grouped_payload.each do |(cargo, destination),
|
151
|
+
grouped_payload.each do |(cargo, destination), metrics|
|
152
152
|
payload = {}
|
153
|
-
payload[cargo] =
|
153
|
+
payload[cargo] = serialize_metrics(metrics)
|
154
154
|
payload['environment'] = @config.environment if @config.environment
|
155
155
|
|
156
156
|
yield(payload, destination)
|
157
157
|
end
|
158
158
|
end
|
159
159
|
|
160
|
-
def
|
161
|
-
|
162
|
-
|
160
|
+
def serialize_metrics(metrics)
|
161
|
+
metrics.map do |metric, stats|
|
162
|
+
metric_hash = metric.to_h.merge!(stats[:total].to_h)
|
163
163
|
|
164
|
-
if
|
164
|
+
if metric.groups.any?
|
165
165
|
group_stats = stats.reject { |name, _stat| name == :total }
|
166
|
-
|
166
|
+
metric_hash['groups'] = group_stats.merge(group_stats) do |_name, stat|
|
167
167
|
stat.to_h
|
168
168
|
end
|
169
169
|
end
|
170
170
|
|
171
|
-
|
171
|
+
metric_hash
|
172
172
|
end
|
173
173
|
end
|
174
174
|
end
|
data/lib/airbrake-ruby/stat.rb
CHANGED
@@ -4,7 +4,7 @@ module Airbrake
|
|
4
4
|
# Stat is a data structure that allows accumulating performance data (route
|
5
5
|
# performance, SQL query performance and such). It's powered by TDigests.
|
6
6
|
#
|
7
|
-
# Usually, one Stat corresponds to one
|
7
|
+
# Usually, one Stat corresponds to one metric (route or query,
|
8
8
|
# etc.). Incrementing a stat means pushing new performance statistics.
|
9
9
|
#
|
10
10
|
# @example
|
@@ -6,10 +6,10 @@ module Airbrake
|
|
6
6
|
module TimeTruncate
|
7
7
|
# Truncate +time+ to floor minute and turn it into an RFC3339 timestamp.
|
8
8
|
#
|
9
|
-
# @param [Time] time
|
9
|
+
# @param [Time, Integer, Float] time
|
10
10
|
# @return [String]
|
11
11
|
def self.utc_truncate_minutes(time)
|
12
|
-
tm = time.getutc
|
12
|
+
tm = Time.at(time).getutc
|
13
13
|
|
14
14
|
Time.utc(tm.year, tm.month, tm.day, tm.hour, tm.min).to_datetime.rfc3339
|
15
15
|
end
|
data/lib/airbrake-ruby.rb
CHANGED
@@ -364,23 +364,14 @@ module Airbrake
|
|
364
364
|
# method: 'POST',
|
365
365
|
# route: '/thing/:id/create',
|
366
366
|
# status_code: 200,
|
367
|
-
# func: 'do_stuff',
|
368
|
-
# file: 'app/models/foo.rb',
|
369
|
-
# line: 452,
|
370
367
|
# timing: 123.45 # ms
|
371
368
|
# )
|
372
369
|
#
|
373
370
|
# @param [Hash{Symbol=>Object}] request_info
|
374
371
|
# @option request_info [String] :method The HTTP method that was invoked
|
375
372
|
# @option request_info [String] :route The route that was invoked
|
376
|
-
# @option request_info [Integer] :status_code The
|
373
|
+
# @option request_info [Integer] :status_code The response code that the
|
377
374
|
# route returned
|
378
|
-
# @option request_info [String] :func The function that called the query
|
379
|
-
# (optional)
|
380
|
-
# @option request_info [String] :file The file that has the function that
|
381
|
-
# called the query (optional)
|
382
|
-
# @option request_info [Integer] :line The line that executes the query
|
383
|
-
# (optional)
|
384
375
|
# @option request_info [Float] :timing How much time it took to process the
|
385
376
|
# request (in ms)
|
386
377
|
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
@@ -415,6 +406,9 @@ module Airbrake
|
|
415
406
|
# method: 'GET',
|
416
407
|
# route: '/things',
|
417
408
|
# query: 'SELECT * FROM things',
|
409
|
+
# func: 'do_stuff',
|
410
|
+
# file: 'app/models/foo.rb',
|
411
|
+
# line: 452,
|
418
412
|
# timing: 123.45 # ms
|
419
413
|
# )
|
420
414
|
#
|
@@ -424,6 +418,12 @@ module Airbrake
|
|
424
418
|
# @option query_info [String] :route The route that triggered this SQL
|
425
419
|
# query (optional)
|
426
420
|
# @option query_info [String] :query The query that was executed
|
421
|
+
# @option request_info [String] :func The function that called the query
|
422
|
+
# (optional)
|
423
|
+
# @option request_info [String] :file The file that has the function that
|
424
|
+
# called the query (optional)
|
425
|
+
# @option request_info [Integer] :line The line that executes the query
|
426
|
+
# (optional)
|
427
427
|
# @option query_info [Float] :timing How much time it took to process the
|
428
428
|
# query (in ms)
|
429
429
|
# @param [Hash] stash What needs to be appeneded to the stash, so it's
|
@@ -451,7 +451,7 @@ module Airbrake
|
|
451
451
|
# Increments performance breakdown statistics of a certain route.
|
452
452
|
#
|
453
453
|
# @example
|
454
|
-
# Airbrake.
|
454
|
+
# Airbrake.notify_performance_breakdown(
|
455
455
|
# method: 'POST',
|
456
456
|
# route: '/thing/:id/create',
|
457
457
|
# response_type: 'json',
|
@@ -523,24 +523,24 @@ module Airbrake
|
|
523
523
|
performance_notifier.notify_sync(queue)
|
524
524
|
end
|
525
525
|
|
526
|
-
# Runs a callback before {.notify_request}
|
527
|
-
# is useful if you want to
|
528
|
-
#
|
526
|
+
# Runs a callback before {.notify_request}, {.notify_query}, {.notify_queue}
|
527
|
+
# or {.notify_performance_breakdown} kicks in. This is useful if you want to
|
528
|
+
# ignore specific metrics or filter the data the metric contains.
|
529
529
|
#
|
530
|
-
# @example Ignore all
|
530
|
+
# @example Ignore all metrics
|
531
531
|
# Airbrake.add_performance_filter(&:ignore!)
|
532
532
|
# @example Filter sensitive data
|
533
|
-
# Airbrake.add_performance_filter do |
|
534
|
-
# case
|
533
|
+
# Airbrake.add_performance_filter do |metric|
|
534
|
+
# case metric
|
535
535
|
# when Airbrake::Query
|
536
|
-
#
|
536
|
+
# metric.route = '[Filtered]'
|
537
537
|
# when Airbrake::Request
|
538
|
-
#
|
538
|
+
# metric.query = '[Filtered]'
|
539
539
|
# end
|
540
540
|
# end
|
541
541
|
# @example Filter with help of a class
|
542
542
|
# class MyFilter
|
543
|
-
# def call(
|
543
|
+
# def call(metric)
|
544
544
|
# # ...
|
545
545
|
# end
|
546
546
|
# end
|
@@ -548,7 +548,7 @@ module Airbrake
|
|
548
548
|
# Airbrake.add_performance_filter(MyFilter.new)
|
549
549
|
#
|
550
550
|
# @param [#call] filter The filter object
|
551
|
-
# @yield [
|
551
|
+
# @yield [metric] The metric to filter
|
552
552
|
# @yieldparam [Airbrake::Query, Airbrake::Request]
|
553
553
|
# @yieldreturn [void]
|
554
554
|
# @return [void]
|
data/spec/config_spec.rb
CHANGED
@@ -127,22 +127,22 @@ RSpec.describe Airbrake::Config do
|
|
127
127
|
|
128
128
|
describe "#check_performance_options" do
|
129
129
|
it "returns a promise" do
|
130
|
-
|
131
|
-
expect(config.check_performance_options(
|
130
|
+
metric = Airbrake::Query.new(method: '', route: '', query: '', timing: 1)
|
131
|
+
expect(config.check_performance_options(metric))
|
132
132
|
.to be_an(Airbrake::Promise)
|
133
133
|
end
|
134
134
|
|
135
135
|
context "when performance stats are disabled" do
|
136
136
|
before { config.performance_stats = false }
|
137
137
|
|
138
|
-
let(:
|
138
|
+
let(:metric) do
|
139
139
|
Airbrake::Request.new(
|
140
140
|
method: 'GET', route: '/foo', status_code: 200, timing: 1,
|
141
141
|
)
|
142
142
|
end
|
143
143
|
|
144
144
|
it "returns a rejected promise" do
|
145
|
-
promise = config.check_performance_options(
|
145
|
+
promise = config.check_performance_options(metric)
|
146
146
|
expect(promise.value).to eq(
|
147
147
|
'error' => "The Performance Stats feature is disabled",
|
148
148
|
)
|
@@ -152,12 +152,12 @@ RSpec.describe Airbrake::Config do
|
|
152
152
|
context "when query stats are disabled" do
|
153
153
|
before { config.query_stats = false }
|
154
154
|
|
155
|
-
let(:
|
155
|
+
let(:metric) do
|
156
156
|
Airbrake::Query.new(method: 'GET', route: '/foo', query: '', timing: 1)
|
157
157
|
end
|
158
158
|
|
159
159
|
it "returns a rejected promise" do
|
160
|
-
promise = config.check_performance_options(
|
160
|
+
promise = config.check_performance_options(metric)
|
161
161
|
expect(promise.value).to eq(
|
162
162
|
'error' => "The Query Stats feature is disabled",
|
163
163
|
)
|
@@ -167,12 +167,12 @@ RSpec.describe Airbrake::Config do
|
|
167
167
|
context "when job stats are disabled" do
|
168
168
|
before { config.job_stats = false }
|
169
169
|
|
170
|
-
let(:
|
170
|
+
let(:metric) do
|
171
171
|
Airbrake::Queue.new(queue: 'foo_queue', error_count: 0, timing: 1)
|
172
172
|
end
|
173
173
|
|
174
174
|
it "returns a rejected promise" do
|
175
|
-
promise = config.check_performance_options(
|
175
|
+
promise = config.check_performance_options(metric)
|
176
176
|
expect(promise.value).to eq(
|
177
177
|
'error' => "The Job Stats feature is disabled",
|
178
178
|
)
|
@@ -522,8 +522,8 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
522
522
|
|
523
523
|
context "when a filter that modifies payload was defined" do
|
524
524
|
before do
|
525
|
-
perf_notifier.add_filter do |
|
526
|
-
|
525
|
+
perf_notifier.add_filter do |metric|
|
526
|
+
metric.route = '[Filtered]'
|
527
527
|
end
|
528
528
|
end
|
529
529
|
|
@@ -621,7 +621,7 @@ RSpec.describe Airbrake::PerformanceNotifier do
|
|
621
621
|
describe "#delete_filter" do
|
622
622
|
let(:filter) do
|
623
623
|
Class.new do
|
624
|
-
def call(
|
624
|
+
def call(metric); end
|
625
625
|
end
|
626
626
|
end
|
627
627
|
|
data/spec/time_truncate_spec.rb
CHANGED
@@ -1,15 +1,30 @@
|
|
1
1
|
RSpec.describe Airbrake::TimeTruncate do
|
2
|
+
time = Time.new(2018, 1, 1, 0, 0, 20, 0)
|
3
|
+
time_with_zone = Time.new(2018, 1, 1, 0, 0, 20, '-05:00')
|
4
|
+
|
2
5
|
describe "#utc_truncate_minutes" do
|
3
|
-
|
4
|
-
time
|
5
|
-
|
6
|
-
|
6
|
+
shared_examples 'time conversion' do |t|
|
7
|
+
it "truncates the time to the floor minute and returns an RFC3339 timestamp" do
|
8
|
+
expect(described_class.utc_truncate_minutes(t))
|
9
|
+
.to eq('2018-01-01T00:00:00+00:00')
|
10
|
+
end
|
11
|
+
|
12
|
+
it "converts time with zone to UTC" do
|
13
|
+
expect(described_class.utc_truncate_minutes(time_with_zone))
|
14
|
+
.to eq('2018-01-01T05:00:00+00:00')
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when the time argument is a Time object" do
|
19
|
+
include_examples 'time conversion', time
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when the time argument is a Float" do
|
23
|
+
include_examples 'time conversion', time.to_f
|
7
24
|
end
|
8
25
|
|
9
|
-
|
10
|
-
time
|
11
|
-
expect(described_class.utc_truncate_minutes(time))
|
12
|
-
.to eq('2018-01-01T05:00:00+00:00')
|
26
|
+
context "when the time argument is an Integer" do
|
27
|
+
include_examples 'time conversion', time.to_i
|
13
28
|
end
|
14
29
|
end
|
15
30
|
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: 6.0.
|
4
|
+
version: 6.0.2
|
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:
|
11
|
+
date: 2022-01-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rbtree-jruby
|
@@ -155,7 +155,8 @@ files:
|
|
155
155
|
homepage: https://airbrake.io
|
156
156
|
licenses:
|
157
157
|
- MIT
|
158
|
-
metadata:
|
158
|
+
metadata:
|
159
|
+
rubygems_mfa_required: 'true'
|
159
160
|
post_install_message:
|
160
161
|
rdoc_options: []
|
161
162
|
require_paths:
|