loga 2.4.0 → 2.5.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +12 -0
- data/Appraisals +19 -7
- data/CHANGELOG.md +20 -0
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/gemfiles/rails60.gemfile +11 -0
- data/gemfiles/sidekiq51.gemfile +1 -1
- data/gemfiles/sidekiq6.gemfile +11 -0
- data/gemfiles/sinatra14.gemfile +1 -1
- data/gemfiles/unit.gemfile +1 -1
- data/lib/loga/configuration.rb +1 -0
- data/lib/loga/formatters/gelf_formatter.rb +16 -1
- data/lib/loga/rack/logger.rb +31 -41
- data/lib/loga/railtie.rb +1 -1
- data/lib/loga/sidekiq.rb +13 -5
- data/lib/loga/{sidekiq → sidekiq5}/job_logger.rb +1 -3
- data/lib/loga/sidekiq6/job_logger.rb +50 -0
- data/lib/loga/version.rb +1 -1
- data/loga.gemspec +1 -1
- data/spec/fixtures/rails60.rb +80 -0
- data/spec/integration/sidekiq5_spec.rb +143 -0
- data/spec/integration/sidekiq6_spec.rb +164 -0
- data/spec/integration/sinatra_spec.rb +1 -1
- data/spec/loga/{sidekiq → sidekiq5}/job_logger_spec.rb +2 -1
- data/spec/loga/sidekiq6/job_logger_spec.rb +121 -0
- data/spec/loga/sidekiq_spec.rb +10 -3
- data/spec/spec_helper.rb +17 -8
- data/spec/unit/loga/formatters/gelf_formatter_spec.rb +43 -0
- data/spec/unit/loga/rack/logger_spec.rb +58 -37
- metadata +18 -9
- data/spec/integration/sidekiq_spec.rb +0 -147
data/spec/loga/sidekiq_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
RSpec.describe Loga::Sidekiq do
|
4
4
|
describe '.configure_logging' do
|
5
|
-
context 'when sidekiq
|
5
|
+
context 'when sidekiq is defined' do
|
6
6
|
it 'gets invoked on Loga.configure' do
|
7
7
|
allow(described_class).to receive(:configure_logging)
|
8
8
|
|
@@ -18,7 +18,7 @@ RSpec.describe Loga::Sidekiq do
|
|
18
18
|
expect(described_class).to have_received(:configure_logging)
|
19
19
|
end
|
20
20
|
|
21
|
-
it 'assigns our custom sidekiq job logger' do
|
21
|
+
it 'assigns our custom sidekiq job logger depending on the sidekiq version' do
|
22
22
|
Loga.reset
|
23
23
|
|
24
24
|
Loga.configure(
|
@@ -28,7 +28,14 @@ RSpec.describe Loga::Sidekiq do
|
|
28
28
|
format: :gelf,
|
29
29
|
)
|
30
30
|
|
31
|
-
|
31
|
+
m = ENV['BUNDLE_GEMFILE'].match(/sidekiq(?<version>\d+)/)
|
32
|
+
|
33
|
+
case m['version']
|
34
|
+
when '51'
|
35
|
+
expect(::Sidekiq.options[:job_logger]).to eq(Loga::Sidekiq5::JobLogger)
|
36
|
+
when '6'
|
37
|
+
expect(::Sidekiq.options[:job_logger]).to eq(Loga::Sidekiq6::JobLogger)
|
38
|
+
end
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
data/spec/spec_helper.rb
CHANGED
@@ -29,14 +29,23 @@ when /sinatra/
|
|
29
29
|
when /unit/
|
30
30
|
rspec_pattern = 'unit/**/*_spec.rb'
|
31
31
|
require 'loga'
|
32
|
-
when /sidekiq/
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
when /sidekiq(?<version>\d+)/
|
33
|
+
case $LAST_MATCH_INFO['version']
|
34
|
+
when '51'
|
35
|
+
rspec_pattern = [
|
36
|
+
'spec/integration/sidekiq5_spec.rb',
|
37
|
+
'spec/loga/sidekiq5/**/*_spec.rb',
|
38
|
+
'spec/loga/sidekiq_spec.rb',
|
39
|
+
].join(',')
|
40
|
+
when '6'
|
41
|
+
rspec_pattern = [
|
42
|
+
'spec/integration/sidekiq6_spec.rb',
|
43
|
+
'spec/loga/sidekiq6/**/*_spec.rb',
|
44
|
+
'spec/loga/sidekiq_spec.rb',
|
45
|
+
].join(',')
|
46
|
+
else
|
47
|
+
raise 'FIXME: Unknown sidekiq - update this file.'
|
48
|
+
end
|
40
49
|
|
41
50
|
require 'sidekiq'
|
42
51
|
require 'sidekiq/cli'
|
@@ -166,6 +166,49 @@ describe Loga::Formatters::GELFFormatter do
|
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
169
|
+
context 'when working with sidekiq context' do
|
170
|
+
let(:options) { { message: 'Wooden house' } }
|
171
|
+
let(:message) { Loga::Event.new(options) }
|
172
|
+
let(:sidekiq_context) { { class: 'MyWorker', jid: '123' } }
|
173
|
+
|
174
|
+
before do
|
175
|
+
klass = Class.new do
|
176
|
+
class << self
|
177
|
+
attr_accessor :current
|
178
|
+
end
|
179
|
+
end
|
180
|
+
klass.current = sidekiq_context
|
181
|
+
stub_const('::Sidekiq::Context', klass)
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'includes the ::Sidekiq::Context.current data' do
|
185
|
+
expect(json['_class']).to eq('MyWorker')
|
186
|
+
expect(json['_jid']).to eq('123')
|
187
|
+
end
|
188
|
+
|
189
|
+
include_examples 'valid GELF message'
|
190
|
+
|
191
|
+
describe 'overwriting sidekiq context data with manual one' do
|
192
|
+
let(:options) { { message: 'Test', data: { class: 'CoolTest' } } }
|
193
|
+
|
194
|
+
it 'uses the manual data instead of the sidekiq context' do
|
195
|
+
expect(json['_class']).to eq('CoolTest')
|
196
|
+
end
|
197
|
+
|
198
|
+
include_examples 'valid GELF message'
|
199
|
+
end
|
200
|
+
|
201
|
+
describe ':elapsed in the sidekiq context' do
|
202
|
+
let(:sidekiq_context) { { class: 'MyWorker', jid: '123', elapsed: '22.2' } }
|
203
|
+
|
204
|
+
it 'transforms it to _duration' do
|
205
|
+
expect(json['_duration']).to eq(22.2)
|
206
|
+
end
|
207
|
+
|
208
|
+
include_examples 'valid GELF message'
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
169
212
|
{
|
170
213
|
'DEBUG' => 7,
|
171
214
|
'INFO' => 6,
|
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rack/test'
|
3
3
|
|
4
|
-
# rubocop:disable RSpec/
|
4
|
+
# rubocop:disable RSpec/VerifiedDoubles RSpec/MessageSpies
|
5
5
|
describe Loga::Rack::Logger do
|
6
|
-
subject { described_class.new(app) }
|
6
|
+
subject(:middleware) { described_class.new(app) }
|
7
7
|
|
8
8
|
let(:env) { Rack::MockRequest.env_for('/about_us?limit=1', options) }
|
9
9
|
let(:options) { {} }
|
@@ -21,18 +21,25 @@ describe Loga::Rack::Logger do
|
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
24
|
-
|
24
|
+
let(:started_at) { Time.new(2021, 1, 2, 9, 30, 4.500, '+00:00') }
|
25
|
+
|
26
|
+
around do |example|
|
27
|
+
Timecop.freeze(Time.new(2021, 1, 2, 9, 30, 5.000, '+00:00'), &example)
|
28
|
+
end
|
29
|
+
|
30
|
+
before do
|
31
|
+
allow(Loga).to receive(:configuration).and_return(configuration)
|
32
|
+
end
|
25
33
|
|
26
34
|
shared_examples 'logs the event' do |details|
|
27
35
|
let(:level) { details[:level] }
|
28
36
|
|
29
|
-
before do
|
30
|
-
allow(subject).to receive(:started_at).and_return(:timestamp)
|
31
|
-
allow(subject).to receive(:duration_in_ms).with(any_args).and_return(5)
|
32
|
-
end
|
33
|
-
|
34
37
|
it 'instantiates a Loga::Event' do
|
35
|
-
|
38
|
+
allow(Loga::Event).to receive(:new).and_call_original
|
39
|
+
|
40
|
+
middleware.call(env, started_at)
|
41
|
+
|
42
|
+
expect(Loga::Event).to have_received(:new).with(
|
36
43
|
data: {
|
37
44
|
request: {
|
38
45
|
'status' => response_status,
|
@@ -42,21 +49,19 @@ describe Loga::Rack::Logger do
|
|
42
49
|
'request_id' => nil,
|
43
50
|
'request_ip' => nil,
|
44
51
|
'user_agent' => nil,
|
45
|
-
'duration' =>
|
52
|
+
'duration' => 500,
|
46
53
|
},
|
47
54
|
},
|
48
55
|
exception: logged_exception,
|
49
56
|
message: %r{^GET \/about_us\?limit=1 #{response_status} in \d+ms$},
|
50
|
-
timestamp:
|
57
|
+
timestamp: started_at,
|
51
58
|
type: 'request',
|
52
59
|
)
|
53
|
-
|
54
|
-
subject.call(env)
|
55
60
|
end
|
56
61
|
|
57
62
|
it "logs the Loga::Event with severity #{details[:level]}" do
|
58
63
|
allow(logger).to receive(level)
|
59
|
-
|
64
|
+
middleware.call(env, started_at)
|
60
65
|
expect(logger).to have_received(level).with(an_instance_of(Loga::Event))
|
61
66
|
end
|
62
67
|
end
|
@@ -65,12 +70,35 @@ describe Loga::Rack::Logger do
|
|
65
70
|
let(:exception) { StandardError.new }
|
66
71
|
let(:logged_exception) { nil }
|
67
72
|
let(:response_status) { 200 }
|
73
|
+
let(:exception_class) { Class.new(StandardError) }
|
68
74
|
|
69
75
|
context 'when an exception is raised' do
|
70
|
-
let(:app) { ->(_env) { raise
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
let(:app) { ->(_env) { raise exception_class } }
|
77
|
+
let(:response_status) { 500 }
|
78
|
+
|
79
|
+
it 'raises error, but still logs an event' do
|
80
|
+
allow(Loga::Event).to receive(:new).and_call_original
|
81
|
+
|
82
|
+
expect { middleware.call(env, started_at) }.to raise_error(exception_class)
|
83
|
+
|
84
|
+
expect(Loga::Event).to have_received(:new).with(
|
85
|
+
data: {
|
86
|
+
request: {
|
87
|
+
'status' => response_status,
|
88
|
+
'method' => 'GET',
|
89
|
+
'path' => '/about_us',
|
90
|
+
'params' => { 'limit' => '1' },
|
91
|
+
'request_id' => nil,
|
92
|
+
'request_ip' => nil,
|
93
|
+
'user_agent' => nil,
|
94
|
+
'duration' => 500,
|
95
|
+
},
|
96
|
+
},
|
97
|
+
exception: logged_exception,
|
98
|
+
message: %r{^GET \/about_us\?limit=1 #{response_status} in \d+ms$},
|
99
|
+
timestamp: started_at,
|
100
|
+
type: 'request',
|
101
|
+
)
|
74
102
|
end
|
75
103
|
end
|
76
104
|
|
@@ -112,28 +140,21 @@ describe Loga::Rack::Logger do
|
|
112
140
|
end
|
113
141
|
|
114
142
|
context 'when the logger is tagged' do
|
115
|
-
let(:logger) {
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
block.call
|
122
|
-
end
|
123
|
-
end
|
143
|
+
let(:logger) { Loga::TaggedLogging.new(Logger.new('/dev/null')) }
|
144
|
+
let(:fake_tag_proc) { double(:proc, call: true) }
|
145
|
+
|
146
|
+
let(:tags) { [->(request) { fake_tag_proc.call(request) }] }
|
147
|
+
|
148
|
+
include_examples 'logs the event', level: :info
|
124
149
|
|
125
|
-
|
126
|
-
|
150
|
+
it 'calls the tags and computes them' do
|
151
|
+
middleware.call(env)
|
127
152
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
expect(logger).to have_received(:tagged).with(:tag) do |&block|
|
132
|
-
expect(block.call).to eq(:response)
|
133
|
-
end
|
134
|
-
end
|
153
|
+
expect(fake_tag_proc)
|
154
|
+
.to have_received(:call)
|
155
|
+
.with(instance_of(Loga::Rack::Request))
|
135
156
|
end
|
136
157
|
end
|
137
158
|
end
|
138
159
|
end
|
139
|
-
# rubocop:enable RSpec/
|
160
|
+
# rubocop:enable RSpec/VerifiedDoubles RSpec/MessageSpies
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loga
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4
|
4
|
+
version: 2.5.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Funding Circle
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -56,14 +56,14 @@ dependencies:
|
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '1.6'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '1.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
@@ -259,7 +259,9 @@ files:
|
|
259
259
|
- gemfiles/rails42.gemfile
|
260
260
|
- gemfiles/rails50.gemfile
|
261
261
|
- gemfiles/rails52.gemfile
|
262
|
+
- gemfiles/rails60.gemfile
|
262
263
|
- gemfiles/sidekiq51.gemfile
|
264
|
+
- gemfiles/sidekiq6.gemfile
|
263
265
|
- gemfiles/sinatra14.gemfile
|
264
266
|
- gemfiles/unit.gemfile
|
265
267
|
- lib/loga.rb
|
@@ -279,7 +281,8 @@ files:
|
|
279
281
|
- lib/loga/railtie.rb
|
280
282
|
- lib/loga/service_version_strategies.rb
|
281
283
|
- lib/loga/sidekiq.rb
|
282
|
-
- lib/loga/
|
284
|
+
- lib/loga/sidekiq5/job_logger.rb
|
285
|
+
- lib/loga/sidekiq6/job_logger.rb
|
283
286
|
- lib/loga/tagged_logging.rb
|
284
287
|
- lib/loga/utilities.rb
|
285
288
|
- lib/loga/version.rb
|
@@ -290,13 +293,16 @@ files:
|
|
290
293
|
- spec/fixtures/rails42.rb
|
291
294
|
- spec/fixtures/rails50.rb
|
292
295
|
- spec/fixtures/rails52.rb
|
296
|
+
- spec/fixtures/rails60.rb
|
293
297
|
- spec/fixtures/random_bin
|
294
298
|
- spec/integration/rails/action_mailer_spec.rb
|
295
299
|
- spec/integration/rails/railtie_spec.rb
|
296
300
|
- spec/integration/rails/request_spec.rb
|
297
|
-
- spec/integration/
|
301
|
+
- spec/integration/sidekiq5_spec.rb
|
302
|
+
- spec/integration/sidekiq6_spec.rb
|
298
303
|
- spec/integration/sinatra_spec.rb
|
299
|
-
- spec/loga/
|
304
|
+
- spec/loga/sidekiq5/job_logger_spec.rb
|
305
|
+
- spec/loga/sidekiq6/job_logger_spec.rb
|
300
306
|
- spec/loga/sidekiq_spec.rb
|
301
307
|
- spec/spec_helper.rb
|
302
308
|
- spec/support/gethostname_shared.rb
|
@@ -345,13 +351,16 @@ test_files:
|
|
345
351
|
- spec/fixtures/rails42.rb
|
346
352
|
- spec/fixtures/rails50.rb
|
347
353
|
- spec/fixtures/rails52.rb
|
354
|
+
- spec/fixtures/rails60.rb
|
348
355
|
- spec/fixtures/random_bin
|
349
356
|
- spec/integration/rails/action_mailer_spec.rb
|
350
357
|
- spec/integration/rails/railtie_spec.rb
|
351
358
|
- spec/integration/rails/request_spec.rb
|
352
|
-
- spec/integration/
|
359
|
+
- spec/integration/sidekiq5_spec.rb
|
360
|
+
- spec/integration/sidekiq6_spec.rb
|
353
361
|
- spec/integration/sinatra_spec.rb
|
354
|
-
- spec/loga/
|
362
|
+
- spec/loga/sidekiq5/job_logger_spec.rb
|
363
|
+
- spec/loga/sidekiq6/job_logger_spec.rb
|
355
364
|
- spec/loga/sidekiq_spec.rb
|
356
365
|
- spec/spec_helper.rb
|
357
366
|
- spec/support/gethostname_shared.rb
|
@@ -1,147 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'timecop'
|
3
|
-
require 'fakeredis'
|
4
|
-
|
5
|
-
dummy_redis_config = ConnectionPool.new(size: 5) { Redis.new }
|
6
|
-
|
7
|
-
Sidekiq.configure_client do |config|
|
8
|
-
config.redis = dummy_redis_config
|
9
|
-
end
|
10
|
-
|
11
|
-
Sidekiq.configure_server do |config|
|
12
|
-
config.redis = dummy_redis_config
|
13
|
-
end
|
14
|
-
|
15
|
-
class MySidekiqWorker
|
16
|
-
include Sidekiq::Worker
|
17
|
-
|
18
|
-
def perform(_name); end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe 'Sidekiq client logger' do
|
22
|
-
let(:target) { StringIO.new }
|
23
|
-
|
24
|
-
def read_json_log(line:)
|
25
|
-
target.rewind
|
26
|
-
JSON.parse(target.each_line.drop(line - 1).first)
|
27
|
-
end
|
28
|
-
|
29
|
-
before do
|
30
|
-
Redis.current.flushall
|
31
|
-
|
32
|
-
Loga.reset
|
33
|
-
|
34
|
-
Loga.configure(
|
35
|
-
service_name: 'hello_world_app',
|
36
|
-
service_version: '1.0',
|
37
|
-
device: target,
|
38
|
-
format: :gelf,
|
39
|
-
)
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'has the proper job logger' do
|
43
|
-
job_logger = Loga::Sidekiq::JobLogger
|
44
|
-
|
45
|
-
expect(Sidekiq.options[:job_logger]).to eq job_logger
|
46
|
-
end
|
47
|
-
|
48
|
-
it 'has the proper logger Sidekiq::Logging.logger' do
|
49
|
-
expect(Sidekiq::Logging.logger).to eq Loga.logger
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'has the proper logger for Sidekiq.logger' do
|
53
|
-
expect(Sidekiq.logger).to eq Loga.logger
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'pushes a new element in the default queue' do
|
57
|
-
MySidekiqWorker.perform_async('Bob')
|
58
|
-
|
59
|
-
last_element = JSON.parse(Redis.current.lpop('queue:default'))
|
60
|
-
|
61
|
-
aggregate_failures do
|
62
|
-
expect(last_element['class']).to eq 'MySidekiqWorker'
|
63
|
-
expect(last_element['args']).to eq ['Bob']
|
64
|
-
expect(last_element['retry']).to eq true
|
65
|
-
expect(last_element['queue']).to eq 'default'
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
if ENV['BUNDLE_GEMFILE'] =~ /sidekiq51/
|
70
|
-
# https://github.com/mperham/sidekiq/blob/97363210b47a4f8a1d8c1233aaa059d6643f5040/test/test_actors.rb#L57-L79
|
71
|
-
let(:mgr) do
|
72
|
-
Class.new do
|
73
|
-
attr_reader :latest_error, :mutex, :cond
|
74
|
-
|
75
|
-
def initialize
|
76
|
-
@mutex = ::Mutex.new
|
77
|
-
@cond = ::ConditionVariable.new
|
78
|
-
end
|
79
|
-
|
80
|
-
def processor_died(_inst, err)
|
81
|
-
@latest_error = err
|
82
|
-
|
83
|
-
@mutex.synchronize { @cond.signal }
|
84
|
-
end
|
85
|
-
|
86
|
-
def processor_stopped(_inst)
|
87
|
-
@mutex.synchronize { @cond.signal }
|
88
|
-
end
|
89
|
-
|
90
|
-
def options
|
91
|
-
{
|
92
|
-
concurrency: 3,
|
93
|
-
queues: ['default'],
|
94
|
-
job_logger: Loga::Sidekiq::JobLogger,
|
95
|
-
}
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'logs the job processing event' do
|
101
|
-
MySidekiqWorker.perform_async('Bob')
|
102
|
-
|
103
|
-
require 'sidekiq/processor'
|
104
|
-
Sidekiq::Processor.new(mgr.new).start
|
105
|
-
sleep 0.5
|
106
|
-
|
107
|
-
expected_attributes = {
|
108
|
-
'_queue'=> 'default',
|
109
|
-
'_retry'=> true,
|
110
|
-
'_params'=> ['Bob'],
|
111
|
-
'_class'=> 'MySidekiqWorker',
|
112
|
-
'_type'=> 'sidekiq',
|
113
|
-
'_service.name'=> 'hello_world_app',
|
114
|
-
'_service.version'=> '1.0',
|
115
|
-
'_tags'=> '',
|
116
|
-
'level'=> 6,
|
117
|
-
'version'=> '1.1',
|
118
|
-
}
|
119
|
-
|
120
|
-
json_line = read_json_log(line: 1)
|
121
|
-
|
122
|
-
aggregate_failures do
|
123
|
-
expect(json_line).to include(expected_attributes)
|
124
|
-
|
125
|
-
%w[_created_at _enqueued_at _jid _duration timestamp host].each do |key|
|
126
|
-
expect(json_line).to have_key(key)
|
127
|
-
end
|
128
|
-
|
129
|
-
expect(json_line['short_message']).to match(/MySidekiqWorker with jid:*/)
|
130
|
-
end
|
131
|
-
|
132
|
-
# This was a bug - the duration was constantly incresing based on when
|
133
|
-
# the logger was created. https://github.com/FundingCircle/loga/pull/117
|
134
|
-
#
|
135
|
-
# Test that after sleeping for few seconds the duration is still under 500ms
|
136
|
-
sleep 1
|
137
|
-
|
138
|
-
MySidekiqWorker.perform_async('Bob')
|
139
|
-
|
140
|
-
sleep 1
|
141
|
-
|
142
|
-
json_line = read_json_log(line: 2)
|
143
|
-
|
144
|
-
expect(json_line['_duration']).to be < 500
|
145
|
-
end
|
146
|
-
end
|
147
|
-
end
|