airbrake-ruby 4.13.0-java → 4.13.1-java
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/config.rb +3 -1
- data/lib/airbrake-ruby/loggable.rb +1 -1
- data/lib/airbrake-ruby/monotonic_time.rb +5 -0
- data/lib/airbrake-ruby/performance_notifier.rb +52 -64
- data/lib/airbrake-ruby/stat.rb +7 -11
- data/lib/airbrake-ruby/tdigest.rb +41 -58
- data/lib/airbrake-ruby/version.rb +1 -1
- data/spec/config_spec.rb +6 -0
- data/spec/loggable_spec.rb +17 -0
- data/spec/monotonic_time_spec.rb +11 -0
- data/spec/stat_spec.rb +0 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 591974a4b164f19bfa3a83b3d9b6441f500759d04fd094c36c44d830f44782ee
|
4
|
+
data.tar.gz: 2f2d9bd955015731f70abc13a6dafd3a73002567cea3b0b8b6bb0a1ae456a8be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17715cc9ce22e0b1ac5972d7b26f6bc3a30bc1ea18c136eb531f5c57d344e2dc53ebc316bc21bd788e03615584bcb131b682cf1552c2ed48bbe3c4509dd7d91e
|
7
|
+
data.tar.gz: 65fbb12a214ea879b6b69405950f11d2c7d599f09bc1735e90bb3744e86f021482bf44e996a8392270bf6c6818294899eb9c0c672c25f8cd1a188ed5995f45fc
|
data/lib/airbrake-ruby/config.rb
CHANGED
@@ -119,12 +119,13 @@ module Airbrake
|
|
119
119
|
|
120
120
|
# @param [Hash{Symbol=>Object}] user_config the hash to be used to build the
|
121
121
|
# config
|
122
|
+
# rubocop:disable Metrics/AbcSize
|
122
123
|
def initialize(user_config = {})
|
123
124
|
self.proxy = {}
|
124
125
|
self.queue_size = 100
|
125
126
|
self.workers = 1
|
126
127
|
self.code_hunks = true
|
127
|
-
self.logger = ::Logger.new(File::NULL)
|
128
|
+
self.logger = ::Logger.new(File::NULL).tap { |l| l.level = Logger::WARN }
|
128
129
|
self.project_id = user_config[:project_id]
|
129
130
|
self.project_key = user_config[:project_key]
|
130
131
|
self.host = 'https://api.airbrake.io'
|
@@ -149,6 +150,7 @@ module Airbrake
|
|
149
150
|
|
150
151
|
merge(user_config)
|
151
152
|
end
|
153
|
+
# rubocop:enable Metrics/AbcSize
|
152
154
|
|
153
155
|
# The full URL to the Airbrake Notice API. Based on the +:host+ option.
|
154
156
|
# @return [URI] the endpoint address
|
@@ -14,18 +14,20 @@ module Airbrake
|
|
14
14
|
@flush_period = Airbrake::Config.instance.performance_stats_flush_period
|
15
15
|
@async_sender = AsyncSender.new(:put)
|
16
16
|
@sync_sender = SyncSender.new(:put)
|
17
|
-
@payload = {}
|
18
17
|
@schedule_flush = nil
|
19
|
-
@mutex = Mutex.new
|
20
18
|
@filter_chain = FilterChain.new
|
21
|
-
|
19
|
+
|
20
|
+
@payload = {}.extend(MonitorMixin)
|
21
|
+
@has_payload = @payload.new_cond
|
22
22
|
end
|
23
23
|
|
24
24
|
# @param [Hash] resource
|
25
25
|
# @see Airbrake.notify_query
|
26
26
|
# @see Airbrake.notify_request
|
27
27
|
def notify(resource)
|
28
|
-
|
28
|
+
@payload.synchronize do
|
29
|
+
send_resource(resource, sync: false)
|
30
|
+
end
|
29
31
|
end
|
30
32
|
|
31
33
|
# @param [Hash] resource
|
@@ -46,7 +48,7 @@ module Airbrake
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def close
|
49
|
-
@
|
51
|
+
@payload.synchronize do
|
50
52
|
@schedule_flush.kill if @schedule_flush
|
51
53
|
@async_sender.close
|
52
54
|
logger.debug("#{LOG_LABEL} performance notifier closed")
|
@@ -55,6 +57,46 @@ module Airbrake
|
|
55
57
|
|
56
58
|
private
|
57
59
|
|
60
|
+
def schedule_flush
|
61
|
+
@schedule_flush ||= Thread.new do
|
62
|
+
loop do
|
63
|
+
@payload.synchronize do
|
64
|
+
@last_flush_time ||= MonotonicTime.time_in_s
|
65
|
+
|
66
|
+
while (MonotonicTime.time_in_s - @last_flush_time) < @flush_period
|
67
|
+
@has_payload.wait(@flush_period)
|
68
|
+
end
|
69
|
+
|
70
|
+
if @payload.none?
|
71
|
+
@last_flush_time = nil
|
72
|
+
next
|
73
|
+
end
|
74
|
+
|
75
|
+
send(@async_sender, @payload, Airbrake::Promise.new)
|
76
|
+
@payload.clear
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def send_resource(resource, sync:)
|
83
|
+
promise = check_configuration(resource)
|
84
|
+
return promise if promise.rejected?
|
85
|
+
|
86
|
+
@filter_chain.refine(resource)
|
87
|
+
if resource.ignored?
|
88
|
+
return Promise.new.reject("#{resource.class} was ignored by a filter")
|
89
|
+
end
|
90
|
+
|
91
|
+
update_payload(resource)
|
92
|
+
if sync || @flush_period == 0
|
93
|
+
send(@sync_sender, @payload, promise)
|
94
|
+
else
|
95
|
+
@has_payload.signal
|
96
|
+
schedule_flush
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
58
100
|
def update_payload(resource)
|
59
101
|
if (total_stat = @payload[resource])
|
60
102
|
@payload.key(total_stat).merge(resource)
|
@@ -83,61 +125,6 @@ module Airbrake
|
|
83
125
|
end
|
84
126
|
end
|
85
127
|
|
86
|
-
def schedule_flush
|
87
|
-
return if @payload.empty?
|
88
|
-
|
89
|
-
if @schedule_flush && @schedule_flush.status == 'sleep' && @waiting
|
90
|
-
begin
|
91
|
-
@schedule_flush.run
|
92
|
-
rescue ThreadError => exception
|
93
|
-
logger.error("#{LOG_LABEL}: error occurred while flushing: #{exception}")
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
@schedule_flush ||= spawn_timer
|
98
|
-
end
|
99
|
-
|
100
|
-
def spawn_timer
|
101
|
-
Thread.new do
|
102
|
-
loop do
|
103
|
-
if @payload.none?
|
104
|
-
@waiting = true
|
105
|
-
Thread.stop
|
106
|
-
@waiting = false
|
107
|
-
end
|
108
|
-
|
109
|
-
sleep(@flush_period)
|
110
|
-
|
111
|
-
payload = nil
|
112
|
-
@mutex.synchronize do
|
113
|
-
payload = @payload
|
114
|
-
@payload = {}
|
115
|
-
end
|
116
|
-
|
117
|
-
send(@async_sender, payload, Airbrake::Promise.new)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
def send_resource(resource, sync:)
|
123
|
-
promise = check_configuration(resource)
|
124
|
-
return promise if promise.rejected?
|
125
|
-
|
126
|
-
@filter_chain.refine(resource)
|
127
|
-
if resource.ignored?
|
128
|
-
return Promise.new.reject("#{resource.class} was ignored by a filter")
|
129
|
-
end
|
130
|
-
|
131
|
-
@mutex.synchronize do
|
132
|
-
update_payload(resource)
|
133
|
-
if sync || @flush_period == 0
|
134
|
-
send(@sync_sender, @payload, promise)
|
135
|
-
else
|
136
|
-
schedule_flush
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
128
|
def check_configuration(resource)
|
142
129
|
promise = @config.check_configuration
|
143
130
|
return promise if promise.rejected?
|
@@ -153,16 +140,17 @@ module Airbrake
|
|
153
140
|
end
|
154
141
|
|
155
142
|
def send(sender, payload, promise)
|
156
|
-
|
157
|
-
raise "#{signature}: payload (#{payload}) cannot be empty. Race?" if payload.none?
|
158
|
-
|
159
|
-
logger.debug { "#{LOG_LABEL} #{signature}: #{payload}" }
|
143
|
+
raise "payload cannot be empty. Race?" if payload.none?
|
160
144
|
|
161
145
|
with_grouped_payload(payload) do |resource_hash, destination|
|
162
146
|
url = URI.join(
|
163
147
|
@config.host,
|
164
148
|
"api/v5/projects/#{@config.project_id}/#{destination}",
|
165
149
|
)
|
150
|
+
|
151
|
+
logger.debug do
|
152
|
+
"#{LOG_LABEL} #{self.class.name}##{__method__}: #{resource_hash}"
|
153
|
+
end
|
166
154
|
sender.send(resource_hash, promise, url)
|
167
155
|
end
|
168
156
|
|
data/lib/airbrake-ruby/stat.rb
CHANGED
@@ -14,15 +14,13 @@ module Airbrake
|
|
14
14
|
#
|
15
15
|
# @since v3.2.0
|
16
16
|
class Stat
|
17
|
-
attr_accessor :
|
17
|
+
attr_accessor :sum, :sumsq, :tdigest
|
18
18
|
|
19
|
-
# @param [Integer] count How many times this stat was incremented
|
20
19
|
# @param [Float] sum The sum of duration in milliseconds
|
21
20
|
# @param [Float] sumsq The squared sum of duration in milliseconds
|
22
21
|
# @param [TDigest::TDigest] tdigest Packed durations. By default,
|
23
22
|
# compression is 20
|
24
|
-
def initialize(
|
25
|
-
@count = count
|
23
|
+
def initialize(sum: 0.0, sumsq: 0.0, tdigest: TDigest.new(0.05))
|
26
24
|
@sum = sum
|
27
25
|
@sumsq = sumsq
|
28
26
|
@tdigest = tdigest
|
@@ -33,15 +31,15 @@ module Airbrake
|
|
33
31
|
def to_h
|
34
32
|
tdigest.compress!
|
35
33
|
{
|
36
|
-
'count' =>
|
34
|
+
'count' => tdigest.size,
|
37
35
|
'sum' => sum,
|
38
36
|
'sumsq' => sumsq,
|
39
37
|
'tdigest' => Base64.strict_encode64(tdigest.as_small_bytes),
|
40
38
|
}
|
41
39
|
end
|
42
40
|
|
43
|
-
# Increments
|
44
|
-
# and +start_time+.
|
41
|
+
# Increments tdigest timings and updates tdigest with the difference between
|
42
|
+
# +end_time+ and +start_time+.
|
45
43
|
#
|
46
44
|
# @param [Date] start_time
|
47
45
|
# @param [Date] end_time
|
@@ -51,13 +49,11 @@ module Airbrake
|
|
51
49
|
increment_ms((end_time - start_time) * 1000)
|
52
50
|
end
|
53
51
|
|
54
|
-
# Increments
|
52
|
+
# Increments tdigest timings and updates tdigest with given +ms+ value.
|
55
53
|
#
|
56
54
|
# @param [Float] ms
|
57
55
|
# @return [void]
|
58
56
|
def increment_ms(ms)
|
59
|
-
self.count += 1
|
60
|
-
|
61
57
|
self.sum += ms
|
62
58
|
self.sumsq += ms * ms
|
63
59
|
|
@@ -69,7 +65,7 @@ module Airbrake
|
|
69
65
|
#
|
70
66
|
# @return [String]
|
71
67
|
def inspect
|
72
|
-
"#<struct Airbrake::Stat count=#{
|
68
|
+
"#<struct Airbrake::Stat count=#{tdigest.size}, sum=#{sum}, sumsq=#{sumsq}>"
|
73
69
|
end
|
74
70
|
alias pretty_print inspect
|
75
71
|
end
|
@@ -37,14 +37,15 @@ module Airbrake
|
|
37
37
|
end
|
38
38
|
|
39
39
|
attr_accessor :centroids
|
40
|
+
attr_reader :size
|
41
|
+
|
40
42
|
def initialize(delta = 0.01, k = 25, cx = 1.1)
|
41
43
|
@delta = delta
|
42
44
|
@k = k
|
43
45
|
@cx = cx
|
44
46
|
@centroids = RBTree.new
|
45
|
-
@
|
46
|
-
@
|
47
|
-
reset!
|
47
|
+
@size = 0
|
48
|
+
@last_cumulate = 0
|
48
49
|
end
|
49
50
|
|
50
51
|
def +(other)
|
@@ -59,8 +60,8 @@ module Airbrake
|
|
59
60
|
# compression as defined by Java implementation
|
60
61
|
size = @centroids.size
|
61
62
|
output = [VERBOSE_ENCODING, compression, size]
|
62
|
-
output += @centroids.map
|
63
|
-
output += @centroids.map
|
63
|
+
output += @centroids.each_value.map(&:mean)
|
64
|
+
output += @centroids.each_value.map(&:n)
|
64
65
|
output.pack("NGNG#{size}N#{size}")
|
65
66
|
end
|
66
67
|
|
@@ -70,14 +71,14 @@ module Airbrake
|
|
70
71
|
output = [self.class::SMALL_ENCODING, compression, size]
|
71
72
|
x = 0
|
72
73
|
# delta encoding allows saving 4-bytes floats
|
73
|
-
mean_arr = @centroids.map do |
|
74
|
+
mean_arr = @centroids.each_value.map do |c|
|
74
75
|
val = c.mean - x
|
75
76
|
x = c.mean
|
76
77
|
val
|
77
78
|
end
|
78
79
|
output += mean_arr
|
79
80
|
# Variable length encoding of numbers
|
80
|
-
c_arr = @centroids.each_with_object([]) do |
|
81
|
+
c_arr = @centroids.each_value.each_with_object([]) do |c, arr|
|
81
82
|
k = 0
|
82
83
|
n = c.n
|
83
84
|
while n < 0 || n > 0x7f
|
@@ -95,7 +96,7 @@ module Airbrake
|
|
95
96
|
# rubocop:enable Metrics/AbcSize
|
96
97
|
|
97
98
|
def as_json(_ = nil)
|
98
|
-
@centroids.map
|
99
|
+
@centroids.each_value.map(&:as_json)
|
99
100
|
end
|
100
101
|
|
101
102
|
def bound_mean(x)
|
@@ -138,21 +139,17 @@ module Airbrake
|
|
138
139
|
end
|
139
140
|
|
140
141
|
def find_nearest(x)
|
141
|
-
return
|
142
|
-
|
143
|
-
ceil = @centroids.upper_bound(x)
|
144
|
-
floor = @centroids.lower_bound(x)
|
142
|
+
return if size == 0
|
145
143
|
|
146
|
-
|
147
|
-
|
144
|
+
upper_key, upper = @centroids.upper_bound(x)
|
145
|
+
lower_key, lower = @centroids.lower_bound(x)
|
146
|
+
return lower unless upper_key
|
147
|
+
return upper unless lower_key
|
148
148
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
if (floor_key - x).abs < (ceil_key - x).abs
|
153
|
-
floor[1]
|
149
|
+
if (lower_key - x).abs < (upper_key - x).abs
|
150
|
+
lower
|
154
151
|
else
|
155
|
-
|
152
|
+
upper
|
156
153
|
end
|
157
154
|
end
|
158
155
|
|
@@ -186,7 +183,7 @@ module Airbrake
|
|
186
183
|
mean_cumn += (item - lower.mean) * (upper.mean_cumn - lower.mean_cumn) \
|
187
184
|
/ (upper.mean - lower.mean)
|
188
185
|
end
|
189
|
-
mean_cumn / @
|
186
|
+
mean_cumn / @size
|
190
187
|
end
|
191
188
|
end
|
192
189
|
is_array ? x : x.first
|
@@ -207,7 +204,7 @@ module Airbrake
|
|
207
204
|
nil
|
208
205
|
else
|
209
206
|
_cumulate(true)
|
210
|
-
h = @
|
207
|
+
h = @size * item
|
211
208
|
lower, upper = bound_mean_cumn(h)
|
212
209
|
if lower.nil? && upper.nil?
|
213
210
|
nil
|
@@ -237,17 +234,12 @@ module Airbrake
|
|
237
234
|
|
238
235
|
def reset!
|
239
236
|
@centroids.clear
|
240
|
-
@
|
241
|
-
@nreset += 1
|
237
|
+
@size = 0
|
242
238
|
@last_cumulate = 0
|
243
239
|
end
|
244
240
|
|
245
|
-
def size
|
246
|
-
@n || 0
|
247
|
-
end
|
248
|
-
|
249
241
|
def to_a
|
250
|
-
@centroids.
|
242
|
+
@centroids.each_value.to_a
|
251
243
|
end
|
252
244
|
|
253
245
|
# rubocop:disable Metrics/PerceivedComplexity, Metrics/MethodLength
|
@@ -307,16 +299,16 @@ module Airbrake
|
|
307
299
|
|
308
300
|
private
|
309
301
|
|
310
|
-
def _add_weight(
|
311
|
-
|
312
|
-
|
313
|
-
|
302
|
+
def _add_weight(centroid, x, n)
|
303
|
+
unless x == centroid.mean
|
304
|
+
centroid.mean += n * (x - centroid.mean) / (centroid.n + n)
|
305
|
+
end
|
314
306
|
|
315
|
-
|
316
|
-
nearest.mean_cumn += n / 2.0
|
317
|
-
nearest.n += n
|
307
|
+
_cumulate(false, true) if centroid.mean_cumn.nil?
|
318
308
|
|
319
|
-
|
309
|
+
centroid.cumn += n
|
310
|
+
centroid.mean_cumn += n / 2.0
|
311
|
+
centroid.n += n
|
320
312
|
end
|
321
313
|
|
322
314
|
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
@@ -325,17 +317,17 @@ module Airbrake
|
|
325
317
|
factor = if @last_cumulate == 0
|
326
318
|
Float::INFINITY
|
327
319
|
else
|
328
|
-
(@
|
320
|
+
(@size.to_f / @last_cumulate)
|
329
321
|
end
|
330
|
-
return if @
|
322
|
+
return if @size == @last_cumulate || (!exact && @cx && @cx > factor)
|
331
323
|
end
|
332
324
|
|
333
325
|
cumn = 0
|
334
|
-
@centroids.
|
326
|
+
@centroids.each_value do |c|
|
335
327
|
c.mean_cumn = cumn + c.n / 2.0
|
336
328
|
cumn = c.cumn = cumn + c.n
|
337
329
|
end
|
338
|
-
@
|
330
|
+
@size = @last_cumulate = cumn
|
339
331
|
nil
|
340
332
|
end
|
341
333
|
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
@@ -345,28 +337,25 @@ module Airbrake
|
|
345
337
|
def _digest(x, n)
|
346
338
|
# Use 'first' and 'last' instead of min/max because of performance reasons
|
347
339
|
# This works because RBTree is sorted
|
348
|
-
min = @centroids.first
|
349
|
-
max = @centroids.last
|
350
|
-
|
351
|
-
min = min.nil? ? nil : min[1]
|
352
|
-
max = max.nil? ? nil : max[1]
|
340
|
+
min = min.last if (min = @centroids.first)
|
341
|
+
max = max.last if (max = @centroids.last)
|
353
342
|
nearest = find_nearest(x)
|
354
343
|
|
355
|
-
@
|
344
|
+
@size += n
|
356
345
|
|
357
346
|
if nearest && nearest.mean == x
|
358
347
|
_add_weight(nearest, x, n)
|
359
348
|
elsif nearest == min
|
360
|
-
|
349
|
+
@centroids[x] = Centroid.new(x, n, 0)
|
361
350
|
elsif nearest == max
|
362
|
-
|
351
|
+
@centroids[x] = Centroid.new(x, n, @size)
|
363
352
|
else
|
364
|
-
p = nearest.mean_cumn.to_f / @
|
365
|
-
max_n = (4 * @
|
353
|
+
p = nearest.mean_cumn.to_f / @size
|
354
|
+
max_n = (4 * @size * @delta * p * (1 - p)).floor
|
366
355
|
if max_n - nearest.n >= n
|
367
356
|
_add_weight(nearest, x, n)
|
368
357
|
else
|
369
|
-
|
358
|
+
@centroids[x] = Centroid.new(x, n, nearest.cumn)
|
370
359
|
end
|
371
360
|
end
|
372
361
|
|
@@ -382,12 +371,6 @@ module Airbrake
|
|
382
371
|
end
|
383
372
|
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity,
|
384
373
|
# rubocop:enable Metrics/AbcSize
|
385
|
-
|
386
|
-
def _new_centroid(x, n, cumn)
|
387
|
-
c = Centroid.new(x, n, cumn)
|
388
|
-
@centroids[x] = c
|
389
|
-
c
|
390
|
-
end
|
391
374
|
end
|
392
375
|
# rubocop:enable Metrics/ClassLength
|
393
376
|
end
|
data/spec/config_spec.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
RSpec.describe Airbrake::Loggable do
|
2
|
+
describe ".instance" do
|
3
|
+
it "returns a logger" do
|
4
|
+
expect(described_class.instance).to be_a(Logger)
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
describe "#logger" do
|
9
|
+
let(:subject) do
|
10
|
+
Class.new { include Airbrake::Loggable }.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns a logger that has Logger::WARN severity" do
|
14
|
+
expect(subject.logger.level).to eq(Logger::WARN)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/spec/monotonic_time_spec.rb
CHANGED
@@ -9,4 +9,15 @@ RSpec.describe Airbrake::MonotonicTime do
|
|
9
9
|
expect(subject.time_in_ms).to be > old_time
|
10
10
|
end
|
11
11
|
end
|
12
|
+
|
13
|
+
describe ".time_in_s" do
|
14
|
+
it "returns monotonic time in seconds" do
|
15
|
+
expect(subject.time_in_s).to be_a(Float)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "always returns time in the future" do
|
19
|
+
old_time = subject.time_in_s
|
20
|
+
expect(subject.time_in_s).to be > old_time
|
21
|
+
end
|
22
|
+
end
|
12
23
|
end
|
data/spec/stat_spec.rb
CHANGED
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.13.
|
4
|
+
version: 4.13.1
|
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: 2020-
|
11
|
+
date: 2020-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rbtree-jruby
|
@@ -120,6 +120,7 @@ files:
|
|
120
120
|
- spec/helpers.rb
|
121
121
|
- spec/ignorable_spec.rb
|
122
122
|
- spec/inspectable_spec.rb
|
123
|
+
- spec/loggable_spec.rb
|
123
124
|
- spec/monotonic_time_spec.rb
|
124
125
|
- spec/nested_exception_spec.rb
|
125
126
|
- spec/notice_notifier/options_spec.rb
|
@@ -189,6 +190,7 @@ test_files:
|
|
189
190
|
- spec/tdigest_spec.rb
|
190
191
|
- spec/async_sender_spec.rb
|
191
192
|
- spec/stat_spec.rb
|
193
|
+
- spec/loggable_spec.rb
|
192
194
|
- spec/backtrace_spec.rb
|
193
195
|
- spec/notice_notifier_spec.rb
|
194
196
|
- spec/time_truncate_spec.rb
|