loga 2.2.0 → 2.3.0
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 +1 -0
- data/.codeclimate.yml +3 -1
- data/.gitignore +2 -0
- data/.rubocop.yml +29 -2
- data/Appraisals +4 -0
- data/CHANGELOG.md +4 -0
- data/Guardfile +14 -0
- data/README.md +4 -0
- data/gemfiles/sidekiq51.gemfile +11 -0
- data/lib/loga.rb +4 -3
- data/lib/loga/ext/core/tempfile.rb +1 -1
- data/lib/loga/formatters/simple_formatter.rb +1 -3
- data/lib/loga/rack/request.rb +2 -2
- data/lib/loga/sidekiq.rb +16 -0
- data/lib/loga/sidekiq/job_logger.rb +62 -0
- data/lib/loga/utilities.rb +1 -1
- data/lib/loga/version.rb +1 -1
- data/loga.gemspec +4 -2
- data/spec/fixtures/rails32.rb +1 -0
- data/spec/integration/rails/railtie_spec.rb +9 -8
- data/spec/integration/rails/request_spec.rb +2 -2
- data/spec/integration/sidekiq_spec.rb +131 -0
- data/spec/integration/sinatra_spec.rb +17 -16
- data/spec/loga/sidekiq/job_logger_spec.rb +115 -0
- data/spec/loga/sidekiq_spec.rb +53 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/helpers.rb +8 -1
- data/spec/support/request_spec.rb +4 -4
- data/spec/support/timecop_shared.rb +1 -0
- data/spec/unit/loga/configuration_spec.rb +7 -4
- data/spec/unit/loga/event_spec.rb +2 -2
- data/spec/unit/loga/formatters/gelf_formatter_spec.rb +7 -5
- data/spec/unit/loga/formatters/simple_formatter_spec.rb +3 -0
- data/spec/unit/loga/log_subscribers/action_mailer_spec.rb +14 -13
- data/spec/unit/loga/parameter_filter_spec.rb +1 -1
- data/spec/unit/loga/rack/logger_spec.rb +10 -6
- data/spec/unit/loga/rack/request_spec.rb +4 -3
- data/spec/unit/loga/utilities_spec.rb +3 -3
- data/spec/unit/loga_spec.rb +6 -3
- metadata +44 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99d4525427d3cfa44d95be9d47f82188246743e71aab9f8d40489214e02e4c02
|
4
|
+
data.tar.gz: 33fc287f4ecabf93cdc6d789f81a040c64eb411d7a018459fa39c91ae03c46c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ce2b115d84a4b3c1c93bf8070b0f3d7ed148df4eb1169ab57d8de2357ad03ea23c21fab2f30f6c0b24236919cbaee21565eee7fed007949a7fa6601118ef510
|
7
|
+
data.tar.gz: df05bfcd3ba233ef8a64e743fcb40c9948caeb1a82039340ae6cb24a839b2cab08044da8009f91196bf444b0b960cbcc29bd2fe9b08f8f3ac003f2757ad5d320
|
data/.circleci/config.yml
CHANGED
data/.codeclimate.yml
CHANGED
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
AllCops:
|
2
2
|
Exclude:
|
3
3
|
- '*.gemspec'
|
4
|
+
- 'gemfiles/*'
|
4
5
|
- 'spec/fixtures/**/*'
|
5
6
|
- 'vendor/bundle/**/*'
|
7
|
+
- 'gemfiles/vendor/bundle/**/*'
|
8
|
+
|
9
|
+
require: rubocop-rspec
|
6
10
|
|
7
11
|
Documentation:
|
8
12
|
Enabled: false
|
@@ -28,6 +32,25 @@ Metrics/MethodLength:
|
|
28
32
|
Enabled: true
|
29
33
|
Max: 15
|
30
34
|
|
35
|
+
RSpec/DescribeClass:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
RSpec/ExampleLength:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
RSpec/FilePath:
|
42
|
+
Exclude:
|
43
|
+
- spec/integration/rails/action_mailer_spec.rb
|
44
|
+
- spec/integration/rails/railtie_spec.rb
|
45
|
+
|
46
|
+
RSpec/MultipleExpectations:
|
47
|
+
Enabled: false
|
48
|
+
|
49
|
+
RSpec/NamedSubject:
|
50
|
+
Enabled: false
|
51
|
+
|
52
|
+
RSpec/NestedGroups:
|
53
|
+
Enabled: false
|
31
54
|
Style/BlockDelimiters:
|
32
55
|
Enabled: false
|
33
56
|
|
@@ -37,10 +60,14 @@ Style/FormatString:
|
|
37
60
|
Style/PerlBackrefs:
|
38
61
|
Enabled: false
|
39
62
|
|
40
|
-
Style/
|
63
|
+
Style/TrailingCommaInArguments:
|
64
|
+
Enabled: true
|
65
|
+
EnforcedStyleForMultiline: comma
|
66
|
+
|
67
|
+
Style/TrailingCommaInArrayLiteral:
|
41
68
|
Enabled: true
|
42
69
|
EnforcedStyleForMultiline: comma
|
43
70
|
|
44
|
-
Style/
|
71
|
+
Style/TrailingCommaInHashLiteral:
|
45
72
|
Enabled: true
|
46
73
|
EnforcedStyleForMultiline: comma
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
5
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
6
|
|
7
|
+
## [2.3.0] - 2018-06-29
|
8
|
+
### Added
|
9
|
+
Support for Sidekiq `~> 5.0`.
|
10
|
+
|
7
11
|
## [2.2.0] - 2018-05-10
|
8
12
|
### Added
|
9
13
|
Subscribe to `ActionMailer` events
|
data/Guardfile
CHANGED
@@ -39,6 +39,20 @@ group :rails do
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
+
group :sidekiq do
|
43
|
+
cmd = 'bundle exec appraisal sidekiq51 rspec'
|
44
|
+
|
45
|
+
guard :rspec, all_on_start: true, cmd: cmd do
|
46
|
+
watch('lib/loga/sidekiq/job_logger.rb') do
|
47
|
+
[
|
48
|
+
'spec/integration/sidekiq_spec.rb',
|
49
|
+
'spec/loga/sidekiq/job_logger_spec.rb',
|
50
|
+
'spec/loga/sidekiq_spec.rb',
|
51
|
+
]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
42
56
|
group :unit do
|
43
57
|
guard :rspec, cmd: 'bundle exec appraisal unit rspec' do
|
44
58
|
watch(%r{^spec/unit/.+_spec\.rb$})
|
data/README.md
CHANGED
data/lib/loga.rb
CHANGED
@@ -8,6 +8,7 @@ require 'loga/rack/logger'
|
|
8
8
|
require 'loga/rack/request'
|
9
9
|
require 'loga/rack/request_id'
|
10
10
|
require 'loga/railtie' if defined?(Rails)
|
11
|
+
require 'loga/sidekiq'
|
11
12
|
|
12
13
|
module Loga
|
13
14
|
ConfigurationError = Class.new(StandardError)
|
@@ -22,11 +23,11 @@ module Loga
|
|
22
23
|
end
|
23
24
|
|
24
25
|
def self.configure(options, framework_options = {})
|
25
|
-
if @configuration
|
26
|
-
raise ConfigurationError, 'Loga has already been configured'
|
27
|
-
end
|
26
|
+
raise ConfigurationError, 'Loga has already been configured' if @configuration
|
28
27
|
|
29
28
|
@configuration ||= Configuration.new(options, framework_options)
|
29
|
+
|
30
|
+
Loga::Sidekiq.configure_logging
|
30
31
|
end
|
31
32
|
|
32
33
|
def self.logger
|
@@ -30,9 +30,7 @@ module Loga
|
|
30
30
|
components = [event.message]
|
31
31
|
|
32
32
|
%i[type data exception].each do |attr|
|
33
|
-
if event.public_send(attr)
|
34
|
-
components.push "#{attr}=#{event.public_send(attr)}"
|
35
|
-
end
|
33
|
+
components.push "#{attr}=#{event.public_send(attr)}" if event.public_send(attr)
|
36
34
|
end
|
37
35
|
|
38
36
|
components.join(' ')
|
data/lib/loga/rack/request.rb
CHANGED
@@ -50,7 +50,7 @@ module Loga
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def filtered_form_hash
|
53
|
-
@
|
53
|
+
@filtered_form_hash ||= filter_hash(form_hash)
|
54
54
|
end
|
55
55
|
|
56
56
|
private
|
@@ -78,7 +78,7 @@ module Loga
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def parameter_filter
|
81
|
-
@
|
81
|
+
@parameter_filter ||=
|
82
82
|
ParameterFilter.new(loga_filter_parameters | action_dispatch_filter_params)
|
83
83
|
end
|
84
84
|
|
data/lib/loga/sidekiq.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'loga/sidekiq/job_logger'
|
2
|
+
|
3
|
+
module Loga
|
4
|
+
module Sidekiq
|
5
|
+
def self.configure_logging
|
6
|
+
return unless defined?(::Sidekiq)
|
7
|
+
return if Gem::Version.new(::Sidekiq::VERSION) < Gem::Version.new('5.0')
|
8
|
+
|
9
|
+
::Sidekiq.configure_server do |config|
|
10
|
+
config.options[:job_logger] = Loga::Sidekiq::JobLogger
|
11
|
+
end
|
12
|
+
|
13
|
+
::Sidekiq::Logging.logger = Loga.configuration.logger
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module Loga
|
2
|
+
module Sidekiq
|
3
|
+
# The approach of using a custom job logger in sidekiq was introduced
|
4
|
+
# in v5.0: https://github.com/mperham/sidekiq/pull/3235
|
5
|
+
# This job logger does not support logging for Sidekiq versions
|
6
|
+
# that are before 5.0
|
7
|
+
class JobLogger
|
8
|
+
include Loga::Utilities
|
9
|
+
|
10
|
+
EVENT_TYPE = 'sidekiq'.freeze
|
11
|
+
|
12
|
+
attr_reader :started_at, :data
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@started_at = Time.now
|
16
|
+
@data = {}
|
17
|
+
end
|
18
|
+
|
19
|
+
def call(item, _queue)
|
20
|
+
yield
|
21
|
+
rescue Exception => ex # rubocop:disable Lint/RescueException
|
22
|
+
data['exception'] = ex
|
23
|
+
|
24
|
+
raise
|
25
|
+
ensure
|
26
|
+
assign_data(item)
|
27
|
+
send_message
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def assign_data(item)
|
33
|
+
data['created_at'] = item['created_at']
|
34
|
+
data['enqueued_at'] = item['enqueued_at']
|
35
|
+
data['jid'] = item['jid']
|
36
|
+
data['queue'] = item['queue']
|
37
|
+
data['retry'] = item['retry']
|
38
|
+
data['params'] = item['args']
|
39
|
+
data['class'] = item['class']
|
40
|
+
data['duration'] = duration_in_ms(started_at)
|
41
|
+
end
|
42
|
+
|
43
|
+
def short_message
|
44
|
+
"#{data['class']} with jid: '#{data['jid']}' executed in #{data['duration']}ms"
|
45
|
+
end
|
46
|
+
|
47
|
+
def send_message
|
48
|
+
event = Event.new(data: data, message: short_message, type: EVENT_TYPE)
|
49
|
+
|
50
|
+
logger.public_send(compute_level, event)
|
51
|
+
end
|
52
|
+
|
53
|
+
def compute_level
|
54
|
+
data.key?('exception') ? :warn : :info
|
55
|
+
end
|
56
|
+
|
57
|
+
def logger
|
58
|
+
Loga.logger
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/loga/utilities.rb
CHANGED
data/lib/loga/version.rb
CHANGED
data/loga.gemspec
CHANGED
@@ -30,7 +30,9 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.add_development_dependency 'pry'
|
31
31
|
spec.add_development_dependency 'rack-test'
|
32
32
|
spec.add_development_dependency 'rake'
|
33
|
-
spec.add_development_dependency '
|
34
|
-
spec.add_development_dependency '
|
33
|
+
spec.add_development_dependency 'fakeredis'
|
34
|
+
spec.add_development_dependency 'rspec', '~> 3.7.0'
|
35
|
+
spec.add_development_dependency 'rubocop', '~> 0.57.0'
|
36
|
+
spec.add_development_dependency 'rubocop-rspec'
|
35
37
|
spec.add_development_dependency 'timecop'
|
36
38
|
end
|
data/spec/fixtures/rails32.rb
CHANGED
@@ -6,12 +6,13 @@ RSpec.describe Loga::Railtie do
|
|
6
6
|
|
7
7
|
describe 'Tempfile' do
|
8
8
|
let(:tempfile) { Tempfile.new('README.md') }
|
9
|
+
|
9
10
|
it 'monkey patches #as_json' do
|
10
11
|
expect(tempfile.as_json).to eql(tempfile.to_s)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
|
-
context 'development', if: Rails.env.development? do
|
15
|
+
context 'when development', if: Rails.env.development? do
|
15
16
|
describe 'loga_initialize_logger' do
|
16
17
|
let(:formatter) { Loga::Formatters::SimpleFormatter }
|
17
18
|
|
@@ -25,7 +26,7 @@ RSpec.describe Loga::Railtie do
|
|
25
26
|
end
|
26
27
|
end
|
27
28
|
|
28
|
-
context 'production', if: Rails.env.production? do
|
29
|
+
context 'when production', if: Rails.env.production? do
|
29
30
|
describe 'loga_initialize_logger' do
|
30
31
|
it 'assign Loga logger to Rails logger' do
|
31
32
|
expect(Loga.logger).to equal(Rails.logger)
|
@@ -57,7 +58,7 @@ RSpec.describe Loga::Railtie do
|
|
57
58
|
listeners.map { |l| l.instance_variable_get(:@delegate).class }
|
58
59
|
end
|
59
60
|
|
60
|
-
|
61
|
+
describe 'ActionView' do
|
61
62
|
[
|
62
63
|
'render_collection.action_view',
|
63
64
|
'render_partial.action_view',
|
@@ -66,12 +67,12 @@ RSpec.describe Loga::Railtie do
|
|
66
67
|
let(:notification) { notification }
|
67
68
|
|
68
69
|
it 'removes ActionView::LogSubscriber' do
|
69
|
-
expect(subscribers).
|
70
|
+
expect(subscribers).not_to include(ActionView::LogSubscriber)
|
70
71
|
end
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
74
|
-
|
75
|
+
describe 'ActionController' do
|
75
76
|
[
|
76
77
|
'exist_fragment?.action_controller',
|
77
78
|
'expire_fragment.action_controller',
|
@@ -91,12 +92,12 @@ RSpec.describe Loga::Railtie do
|
|
91
92
|
let(:notification) { notification }
|
92
93
|
|
93
94
|
it 'removes ActionController::LogSubscriber' do
|
94
|
-
expect(subscribers).
|
95
|
+
expect(subscribers).not_to include(ActionController::LogSubscriber)
|
95
96
|
end
|
96
97
|
end
|
97
98
|
end
|
98
99
|
|
99
|
-
|
100
|
+
describe 'ActionMailer' do
|
100
101
|
[
|
101
102
|
'receive.action_mailer',
|
102
103
|
'deliver.action_mailer',
|
@@ -105,7 +106,7 @@ RSpec.describe Loga::Railtie do
|
|
105
106
|
let(:notification) { notification }
|
106
107
|
|
107
108
|
it 'removes ActionMailer::LogSubscriber' do
|
108
|
-
expect(subscribers).
|
109
|
+
expect(subscribers).not_to include(ActionMailer::LogSubscriber)
|
109
110
|
end
|
110
111
|
end
|
111
112
|
end
|
@@ -31,7 +31,7 @@ RSpec.describe 'Structured logging with Rails', timecop: true,
|
|
31
31
|
end
|
32
32
|
|
33
33
|
describe 'LogSubscriber' do
|
34
|
-
|
34
|
+
describe 'ActionController' do
|
35
35
|
let(:action_controller_notifications) do
|
36
36
|
log_entries.select { |e| e.to_json =~ /Processing by|Completed/ }
|
37
37
|
end
|
@@ -42,7 +42,7 @@ RSpec.describe 'Structured logging with Rails', timecop: true,
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
|
45
|
+
describe 'ActionView' do
|
46
46
|
let(:action_view_notifications) do
|
47
47
|
log_entries.select { |e| e.to_json =~ /Rendered/ }
|
48
48
|
end
|
@@ -0,0 +1,131 @@
|
|
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
|
+
let(:json_line) do
|
25
|
+
target.rewind
|
26
|
+
JSON.parse(target.read)
|
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
|
+
aggregate_failures do
|
121
|
+
expect(json_line).to include(expected_attributes)
|
122
|
+
|
123
|
+
%w[_created_at _enqueued_at _jid _duration timestamp host].each do |key|
|
124
|
+
expect(json_line).to have_key(key)
|
125
|
+
end
|
126
|
+
|
127
|
+
expect(json_line['short_message']).to match(/MySidekiqWorker with jid:*/)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|