rails_semantic_logger 4.4.2 → 4.5.0
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/README.md +1 -1
- data/Rakefile +9 -9
- data/lib/rails_semantic_logger.rb +23 -12
- data/lib/rails_semantic_logger/action_controller/log_subscriber.rb +12 -5
- data/lib/rails_semantic_logger/action_view/log_subscriber.rb +16 -13
- data/lib/rails_semantic_logger/active_job/log_subscriber.rb +121 -0
- data/lib/rails_semantic_logger/active_record/log_subscriber.rb +33 -3
- data/lib/rails_semantic_logger/delayed_job/plugin.rb +1 -1
- data/lib/rails_semantic_logger/engine.rb +78 -57
- data/lib/rails_semantic_logger/extensions/active_job/logging.rb +1 -122
- data/lib/rails_semantic_logger/extensions/active_model_serializers/logging.rb +1 -1
- data/lib/rails_semantic_logger/rack/logger.rb +9 -9
- data/lib/rails_semantic_logger/version.rb +1 -1
- metadata +14 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 073a9356b40dc5616e3e4b179ea108d7419dc9e4bba685c230e41acd93ca48d4
|
4
|
+
data.tar.gz: 106766c0a81ed7a2d7b25c7810aa1edac1eedf5638426373209b168d7ea57b43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd450ba87b0d22e139fd7afa626ed4fb8566e3ebc70880c05fe2c73c1ff5067a8d3626a8bddd742160a3d25eced3f8e4431e1fac96432f0fe53e6ec740c78d46
|
7
|
+
data.tar.gz: 2bee7d442cab44140f00b9ca74d0b343d6e19933953487c5b21c094bea0c7f811f2bb6014090eda6a778eb1ebd8209f86a9b4c3afb471fd1fa9955ad3fc160e4
|
data/README.md
CHANGED
@@ -21,7 +21,7 @@ SemanticLogger::Processor.instance.instance_variable_set(:@queue, Queue.new)
|
|
21
21
|
|
22
22
|
## Supports
|
23
23
|
|
24
|
-
|
24
|
+
For the complete list of supported Ruby and Rails versions, see the [Testing file](https://github.com/rocketjob/rails_semantic_logger/blob/master/.travis.yml).
|
25
25
|
|
26
26
|
## Author
|
27
27
|
|
data/Rakefile
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
# Setup bundler to avoid having to run bundle exec all the time.
|
2
|
-
require
|
3
|
-
require
|
2
|
+
require "rubygems"
|
3
|
+
require "bundler/setup"
|
4
4
|
|
5
|
-
require
|
6
|
-
require_relative
|
5
|
+
require "rake/testtask"
|
6
|
+
require_relative "lib/rails_semantic_logger/version"
|
7
7
|
|
8
8
|
task :gem do
|
9
|
-
system
|
9
|
+
system "gem build rails_semantic_logger.gemspec"
|
10
10
|
end
|
11
11
|
|
12
12
|
task publish: :gem do
|
13
13
|
system "git tag -a v#{RailsSemanticLogger::VERSION} -m 'Tagging #{RailsSemanticLogger::VERSION}'"
|
14
|
-
system
|
14
|
+
system "git push --tags"
|
15
15
|
system "gem push rails_semantic_logger-#{RailsSemanticLogger::VERSION}.gem"
|
16
16
|
system "rm rails_semantic_logger-#{RailsSemanticLogger::VERSION}.gem"
|
17
17
|
end
|
18
18
|
|
19
19
|
Rake::TestTask.new(:test) do |t|
|
20
|
-
t.pattern =
|
20
|
+
t.pattern = "test/**/*_test.rb"
|
21
21
|
t.verbose = true
|
22
22
|
t.warning = false
|
23
23
|
end
|
24
24
|
|
25
25
|
# By default run tests against all appraisals
|
26
|
-
if !ENV[
|
27
|
-
require
|
26
|
+
if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
|
27
|
+
require "appraisal"
|
28
28
|
task default: :appraisal
|
29
29
|
else
|
30
30
|
task default: :test
|
@@ -1,25 +1,28 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "semantic_logger"
|
2
|
+
require "rails_semantic_logger/extensions/rails/server" if defined?(Rails::Server)
|
3
|
+
require "rails_semantic_logger/engine"
|
4
4
|
|
5
5
|
module RailsSemanticLogger
|
6
6
|
module ActionController
|
7
|
-
autoload :LogSubscriber,
|
7
|
+
autoload :LogSubscriber, "rails_semantic_logger/action_controller/log_subscriber"
|
8
8
|
end
|
9
9
|
module ActionView
|
10
|
-
autoload :LogSubscriber,
|
10
|
+
autoload :LogSubscriber, "rails_semantic_logger/action_view/log_subscriber"
|
11
|
+
end
|
12
|
+
module ActiveJob
|
13
|
+
autoload :LogSubscriber, "rails_semantic_logger/active_job/log_subscriber"
|
11
14
|
end
|
12
15
|
module ActiveRecord
|
13
|
-
autoload :LogSubscriber,
|
16
|
+
autoload :LogSubscriber, "rails_semantic_logger/active_record/log_subscriber"
|
14
17
|
end
|
15
18
|
module Rack
|
16
|
-
autoload :Logger,
|
19
|
+
autoload :Logger, "rails_semantic_logger/rack/logger"
|
17
20
|
end
|
18
21
|
module DelayedJob
|
19
|
-
autoload :Plugin,
|
22
|
+
autoload :Plugin, "rails_semantic_logger/delayed_job/plugin"
|
20
23
|
end
|
21
24
|
|
22
|
-
autoload :Options,
|
25
|
+
autoload :Options, "rails_semantic_logger/options"
|
23
26
|
|
24
27
|
# Swap an existing subscriber with a new one
|
25
28
|
def self.swap_subscriber(old_class, new_class, notifier)
|
@@ -30,14 +33,22 @@ module RailsSemanticLogger
|
|
30
33
|
end
|
31
34
|
|
32
35
|
def self.unattach(subscriber)
|
33
|
-
subscriber.
|
34
|
-
ActiveSupport::Notifications.notifier.listeners_for(
|
36
|
+
subscriber_patterns(subscriber).each do |pattern|
|
37
|
+
ActiveSupport::Notifications.notifier.listeners_for(pattern).each do |sub|
|
35
38
|
next unless sub.instance_variable_get(:@delegate) == subscriber
|
39
|
+
|
36
40
|
ActiveSupport::Notifications.unsubscribe(sub)
|
37
41
|
end
|
38
42
|
end
|
39
43
|
|
40
44
|
ActiveSupport::LogSubscriber.subscribers.delete(subscriber)
|
41
45
|
end
|
42
|
-
|
46
|
+
|
47
|
+
def self.subscriber_patterns(subscriber)
|
48
|
+
subscriber.patterns.respond_to?(:keys) ?
|
49
|
+
subscriber.patterns.keys :
|
50
|
+
subscriber.patterns
|
51
|
+
end
|
52
|
+
|
53
|
+
private_class_method :subscriber_patterns, :unattach
|
43
54
|
end
|
@@ -37,14 +37,21 @@ module RailsSemanticLogger
|
|
37
37
|
payload[key] = payload[key].to_f.round(2) if key.to_s =~ /(.*)_runtime/
|
38
38
|
end
|
39
39
|
|
40
|
+
# Rails 6+ includes allocation count
|
41
|
+
payload[:allocations] = event.allocations if event.respond_to?(:allocations)
|
42
|
+
|
40
43
|
payload[:status_message] = ::Rack::Utils::HTTP_STATUS_CODES[payload[:status]] if payload[:status].present?
|
44
|
+
|
41
45
|
# Causes excessive log output with Rails 5 RC1
|
42
46
|
payload.delete(:headers)
|
47
|
+
# Causes recursion in Rails 6.1.rc1
|
48
|
+
payload.delete(:request)
|
49
|
+
payload.delete(:response)
|
43
50
|
|
44
51
|
params = payload[:params]
|
45
52
|
if params
|
46
53
|
# When logging to JSON the entire tempfile is logged, so convert it to a string.
|
47
|
-
params[
|
54
|
+
params["file"] = params["file"].inspect if params["file"]
|
48
55
|
end
|
49
56
|
|
50
57
|
{
|
@@ -60,15 +67,15 @@ module RailsSemanticLogger
|
|
60
67
|
end
|
61
68
|
|
62
69
|
def send_file(event)
|
63
|
-
controller_logger(event).info(message:
|
70
|
+
controller_logger(event).info(message: "Sent file", payload: {path: event.payload[:path]}, duration: event.duration)
|
64
71
|
end
|
65
72
|
|
66
73
|
def redirect_to(event)
|
67
|
-
controller_logger(event).info(message:
|
74
|
+
controller_logger(event).info(message: "Redirected to", payload: {location: event.payload[:location]})
|
68
75
|
end
|
69
76
|
|
70
77
|
def send_data(event)
|
71
|
-
controller_logger(event).info(message:
|
78
|
+
controller_logger(event).info(message: "Sent data", payload: {file_name: event.payload[:filename]}, duration: event.duration)
|
72
79
|
end
|
73
80
|
|
74
81
|
def unpermitted_parameters(event)
|
@@ -106,7 +113,7 @@ module RailsSemanticLogger
|
|
106
113
|
end
|
107
114
|
|
108
115
|
def extract_path(path)
|
109
|
-
index = path.index(
|
116
|
+
index = path.index("?")
|
110
117
|
index ? path[0, index] : path
|
111
118
|
end
|
112
119
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require "active_support/log_subscriber"
|
2
2
|
|
3
3
|
module RailsSemanticLogger
|
4
4
|
module ActionView
|
5
5
|
# Output Semantic logs from Action View.
|
6
6
|
class LogSubscriber < ActiveSupport::LogSubscriber
|
7
|
-
VIEWS_PATTERN =
|
7
|
+
VIEWS_PATTERN = %r{^app/views/}.freeze
|
8
8
|
|
9
9
|
class << self
|
10
10
|
attr_reader :logger
|
@@ -19,14 +19,15 @@ module RailsSemanticLogger
|
|
19
19
|
def render_template(event)
|
20
20
|
return unless should_log?
|
21
21
|
|
22
|
-
payload
|
22
|
+
payload = {
|
23
23
|
template: from_rails_root(event.payload[:identifier])
|
24
24
|
}
|
25
25
|
payload[:within] = from_rails_root(event.payload[:layout]) if event.payload[:layout]
|
26
|
+
payload[:allocations] = event.allocations if event.respond_to?(:allocations)
|
26
27
|
|
27
28
|
logger.measure(
|
28
29
|
self.class.rendered_log_level,
|
29
|
-
|
30
|
+
"Rendered",
|
30
31
|
payload: payload,
|
31
32
|
duration: event.duration
|
32
33
|
)
|
@@ -35,15 +36,16 @@ module RailsSemanticLogger
|
|
35
36
|
def render_partial(event)
|
36
37
|
return unless should_log?
|
37
38
|
|
38
|
-
payload
|
39
|
+
payload = {
|
39
40
|
partial: from_rails_root(event.payload[:identifier])
|
40
41
|
}
|
41
42
|
payload[:within] = from_rails_root(event.payload[:layout]) if event.payload[:layout]
|
42
43
|
payload[:cache] = payload[:cache_hit] unless event.payload[:cache_hit].nil?
|
44
|
+
payload[:allocations] = event.allocations if event.respond_to?(:allocations)
|
43
45
|
|
44
46
|
logger.measure(
|
45
47
|
self.class.rendered_log_level,
|
46
|
-
|
48
|
+
"Rendered",
|
47
49
|
payload: payload,
|
48
50
|
duration: event.duration
|
49
51
|
)
|
@@ -52,28 +54,29 @@ module RailsSemanticLogger
|
|
52
54
|
def render_collection(event)
|
53
55
|
return unless should_log?
|
54
56
|
|
55
|
-
identifier = event.payload[:identifier] ||
|
57
|
+
identifier = event.payload[:identifier] || "templates"
|
56
58
|
|
57
|
-
payload
|
59
|
+
payload = {
|
58
60
|
template: from_rails_root(identifier),
|
59
61
|
count: event.payload[:count]
|
60
62
|
}
|
61
63
|
payload[:cache_hits] = payload[:cache_hits] if payload[:cache_hits]
|
64
|
+
payload[:allocations] = event.allocations if event.respond_to?(:allocations)
|
62
65
|
|
63
66
|
logger.measure(
|
64
67
|
self.class.rendered_log_level,
|
65
|
-
|
68
|
+
"Rendered",
|
66
69
|
payload: payload,
|
67
70
|
duration: event.duration
|
68
71
|
)
|
69
72
|
end
|
70
73
|
|
71
74
|
def start(name, id, payload)
|
72
|
-
if (name ==
|
75
|
+
if (name == "render_template.action_view") && should_log?
|
73
76
|
payload = {template: from_rails_root(payload[:identifier])}
|
74
77
|
payload[:within] = from_rails_root(payload[:layout]) if payload[:layout]
|
75
78
|
|
76
|
-
logger.send(self.class.rendered_log_level, message:
|
79
|
+
logger.send(self.class.rendered_log_level, message: "Rendering", payload: payload)
|
77
80
|
end
|
78
81
|
|
79
82
|
super
|
@@ -81,10 +84,10 @@ module RailsSemanticLogger
|
|
81
84
|
|
82
85
|
private
|
83
86
|
|
84
|
-
@logger = SemanticLogger[
|
87
|
+
@logger = SemanticLogger["ActionView"]
|
85
88
|
@rendered_log_level = :debug
|
86
89
|
|
87
|
-
EMPTY =
|
90
|
+
EMPTY = "".freeze
|
88
91
|
|
89
92
|
def should_log?
|
90
93
|
logger.send("#{self.class.rendered_log_level}?")
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require "active_job"
|
2
|
+
|
3
|
+
module RailsSemanticLogger
|
4
|
+
module ActiveJob
|
5
|
+
class LogSubscriber < ::ActiveSupport::LogSubscriber
|
6
|
+
def enqueue(event)
|
7
|
+
log_with_formatter event: event do |fmt|
|
8
|
+
"Enqueued #{fmt.job_info}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def enqueue_at(event)
|
13
|
+
log_with_formatter event: event do |fmt|
|
14
|
+
"Enqueued #{fmt.job_info} at #{fmt.scheduled_at}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform_start(event)
|
19
|
+
log_with_formatter event: event do |fmt|
|
20
|
+
"Performing #{fmt.job_info}"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def perform(event)
|
25
|
+
ex = event.payload[:exception_object]
|
26
|
+
if ex
|
27
|
+
logger.error ex
|
28
|
+
else
|
29
|
+
log_with_formatter event: event, log_duration: true do |fmt|
|
30
|
+
"Performed #{fmt.job_info} in #{event.duration.round(2)}ms"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
class EventFormatter
|
38
|
+
def initialize(event:, log_duration: false)
|
39
|
+
@event = event
|
40
|
+
@log_duration = log_duration
|
41
|
+
end
|
42
|
+
|
43
|
+
def job_info
|
44
|
+
"#{job.class.name} (Job ID: #{job.job_id}) to #{queue_name}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def payload
|
48
|
+
{}.tap do |h|
|
49
|
+
h[:event_name] = event.name
|
50
|
+
h[:adapter] = adapter_name
|
51
|
+
h[:queue] = job.queue_name
|
52
|
+
h[:job_class] = job.class.name
|
53
|
+
h[:job_id] = job.job_id
|
54
|
+
h[:provider_job_id] = job.try(:provider_job_id) # Not available in Rails 4.2
|
55
|
+
h[:duration] = event.duration.round(2) if log_duration?
|
56
|
+
h[:arguments] = formatted_args
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def queue_name
|
61
|
+
adapter_name + "(#{job.queue_name})"
|
62
|
+
end
|
63
|
+
|
64
|
+
def scheduled_at
|
65
|
+
Time.at(event.payload[:job].scheduled_at).utc
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
|
70
|
+
attr_reader :event
|
71
|
+
|
72
|
+
def job
|
73
|
+
event.payload[:job]
|
74
|
+
end
|
75
|
+
|
76
|
+
def adapter_name
|
77
|
+
event.payload[:adapter].class.name.demodulize.remove("Adapter")
|
78
|
+
end
|
79
|
+
|
80
|
+
def formatted_args
|
81
|
+
if defined?(job.class.log_arguments?) && !job.class.log_arguments?
|
82
|
+
""
|
83
|
+
else
|
84
|
+
JSON.pretty_generate(job.arguments.map { |arg| format(arg) })
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def format(arg)
|
89
|
+
case arg
|
90
|
+
when Hash
|
91
|
+
arg.transform_values { |value| format(value) }
|
92
|
+
when Array
|
93
|
+
arg.map { |value| format(value) }
|
94
|
+
when GlobalID::Identification
|
95
|
+
begin
|
96
|
+
arg.to_global_id
|
97
|
+
rescue StandardError
|
98
|
+
arg
|
99
|
+
end
|
100
|
+
else
|
101
|
+
arg
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def log_duration?
|
106
|
+
@log_duration
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def log_with_formatter(**kw_args)
|
111
|
+
fmt = EventFormatter.new(**kw_args)
|
112
|
+
msg = yield fmt
|
113
|
+
logger.info msg, fmt.payload
|
114
|
+
end
|
115
|
+
|
116
|
+
def logger
|
117
|
+
::ActiveJob::Base.logger
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -31,6 +31,7 @@ module RailsSemanticLogger
|
|
31
31
|
|
32
32
|
log_payload = {sql: payload[:sql]}
|
33
33
|
log_payload[:binds] = bind_values(payload) unless (payload[:binds] || []).empty?
|
34
|
+
log_payload[:allocations] = event.allocations if event.respond_to?(:allocations)
|
34
35
|
|
35
36
|
log = {
|
36
37
|
message: name,
|
@@ -48,11 +49,11 @@ module RailsSemanticLogger
|
|
48
49
|
|
49
50
|
private
|
50
51
|
|
51
|
-
@logger = SemanticLogger[
|
52
|
+
@logger = SemanticLogger["ActiveRecord"]
|
52
53
|
|
53
54
|
# When multiple values are received for a single bound field, it is converted into an array
|
54
55
|
def add_bind_value(binds, key, value)
|
55
|
-
key = key.downcase.to_sym
|
56
|
+
key = key.downcase.to_sym unless key.nil?
|
56
57
|
value = (Array(binds[key]) << value) if binds.key?(key)
|
57
58
|
binds[key] = value
|
58
59
|
end
|
@@ -115,12 +116,22 @@ module RailsSemanticLogger
|
|
115
116
|
binds
|
116
117
|
end
|
117
118
|
|
119
|
+
def bind_values_v6_1(payload)
|
120
|
+
binds = {}
|
121
|
+
casted_params = type_casted_binds(payload[:type_casted_binds])
|
122
|
+
payload[:binds].each_with_index do |attr, i|
|
123
|
+
attr_name, value = render_bind(attr, casted_params[i])
|
124
|
+
add_bind_value(binds, attr_name, value)
|
125
|
+
end
|
126
|
+
binds
|
127
|
+
end
|
128
|
+
|
118
129
|
def render_bind_v4_2(column, value)
|
119
130
|
if column
|
120
131
|
if column.binary?
|
121
132
|
# This specifically deals with the PG adapter that casts bytea columns into a Hash.
|
122
133
|
value = value[:value] if value.is_a?(Hash)
|
123
|
-
value = value ? "<#{value.bytesize} bytes of binary data>" :
|
134
|
+
value = value ? "<#{value.bytesize} bytes of binary data>" : "<NULL binary data>"
|
124
135
|
end
|
125
136
|
|
126
137
|
[column.name, value]
|
@@ -154,6 +165,21 @@ module RailsSemanticLogger
|
|
154
165
|
[attr&.name, value]
|
155
166
|
end
|
156
167
|
|
168
|
+
def render_bind_v6_1(attr, value)
|
169
|
+
case attr
|
170
|
+
when ActiveModel::Attribute
|
171
|
+
if attr.type.binary? && attr.value
|
172
|
+
value = "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
|
173
|
+
end
|
174
|
+
when Array
|
175
|
+
attr = attr.first
|
176
|
+
else
|
177
|
+
attr = nil
|
178
|
+
end
|
179
|
+
|
180
|
+
[attr&.name, value]
|
181
|
+
end
|
182
|
+
|
157
183
|
def type_casted_binds_v5_0_3(binds, casted_binds)
|
158
184
|
casted_binds || ::ActiveRecord::Base.connection.type_casted_binds(binds)
|
159
185
|
end
|
@@ -171,6 +197,10 @@ module RailsSemanticLogger
|
|
171
197
|
alias bind_values bind_values_v5_0_3
|
172
198
|
alias render_bind render_bind_v5_0_3
|
173
199
|
alias type_casted_binds type_casted_binds_v5_0_3
|
200
|
+
elsif Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR > 0 # ~> 6.1.0
|
201
|
+
alias bind_values bind_values_v6_1
|
202
|
+
alias render_bind render_bind_v6_1
|
203
|
+
alias type_casted_binds type_casted_binds_v5_1_5
|
174
204
|
elsif Rails::VERSION::MAJOR >= 5 # ~> 5.1.5 && ~> 5.0.7 && 6.x.x
|
175
205
|
alias bind_values bind_values_v5_1_5
|
176
206
|
alias render_bind render_bind_v5_0_3
|
@@ -1,6 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "rails"
|
2
|
+
require "action_controller/log_subscriber"
|
3
|
+
require "action_view/log_subscriber"
|
4
|
+
require "rails_semantic_logger/options"
|
4
5
|
|
5
6
|
module RailsSemanticLogger
|
6
7
|
class Engine < ::Rails::Engine
|
@@ -41,53 +42,54 @@ module RailsSemanticLogger
|
|
41
42
|
|
42
43
|
# Existing loggers are ignored because servers like trinidad supply their
|
43
44
|
# own file loggers which would result in duplicate logging to the same log file
|
44
|
-
Rails.logger = config.logger =
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
45
|
+
Rails.logger = config.logger =
|
46
|
+
begin
|
47
|
+
if config.rails_semantic_logger.add_file_appender
|
48
|
+
path = config.paths["log"].first
|
49
|
+
FileUtils.mkdir_p(File.dirname(path)) unless File.exist?(File.dirname(path))
|
50
|
+
|
51
|
+
# Add the log file to the list of appenders
|
52
|
+
# Use the colorized formatter if Rails colorized logs are enabled
|
53
|
+
ap_options = config.rails_semantic_logger.ap_options
|
54
|
+
formatter = config.rails_semantic_logger.format
|
55
|
+
formatter = {color: {ap: ap_options}} if (formatter == :default) && (config.colorize_logging != false)
|
56
|
+
|
57
|
+
# Set internal logger to log to file only, in case another appender experiences errors during writes
|
58
|
+
appender = SemanticLogger::Appender::File.new(
|
59
|
+
file_name: path,
|
60
|
+
level: config.log_level,
|
61
|
+
formatter: formatter
|
62
|
+
)
|
63
|
+
appender.name = "SemanticLogger"
|
64
|
+
SemanticLogger::Processor.logger = appender
|
65
|
+
|
66
|
+
# Check for previous file or stdout loggers
|
67
|
+
SemanticLogger.appenders.each { |app| app.formatter = formatter if app.is_a?(SemanticLogger::Appender::File) }
|
68
|
+
SemanticLogger.add_appender(file_name: path, formatter: formatter, filter: config.rails_semantic_logger.filter)
|
69
|
+
end
|
70
|
+
|
71
|
+
SemanticLogger[Rails]
|
72
|
+
rescue StandardError => e
|
73
|
+
# If not able to log to file, log to standard error with warning level only
|
74
|
+
SemanticLogger.default_level = :warn
|
75
|
+
|
76
|
+
SemanticLogger::Processor.logger = SemanticLogger::Appender::File.new(io: STDERR)
|
77
|
+
SemanticLogger.add_appender(io: STDERR)
|
78
|
+
|
79
|
+
logger = SemanticLogger[Rails]
|
80
|
+
logger.warn(
|
81
|
+
"Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " \
|
82
|
+
"The log level has been raised to WARN and the output directed to STDERR until the problem is fixed.",
|
83
|
+
e
|
60
84
|
)
|
61
|
-
|
62
|
-
SemanticLogger::Processor.logger = appender
|
63
|
-
|
64
|
-
# Check for previous file or stdout loggers
|
65
|
-
SemanticLogger.appenders.each { |app| app.formatter = formatter if app.is_a?(SemanticLogger::Appender::File) }
|
66
|
-
SemanticLogger.add_appender(file_name: path, formatter: formatter, filter: config.rails_semantic_logger.filter)
|
85
|
+
logger
|
67
86
|
end
|
68
87
|
|
69
|
-
SemanticLogger[Rails]
|
70
|
-
rescue StandardError => exc
|
71
|
-
# If not able to log to file, log to standard error with warning level only
|
72
|
-
SemanticLogger.default_level = :warn
|
73
|
-
|
74
|
-
SemanticLogger::Processor.logger = SemanticLogger::Appender::File.new(io: STDERR)
|
75
|
-
SemanticLogger.add_appender(io: STDERR)
|
76
|
-
|
77
|
-
logger = SemanticLogger[Rails]
|
78
|
-
logger.warn(
|
79
|
-
"Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " \
|
80
|
-
'The log level has been raised to WARN and the output directed to STDERR until the problem is fixed.',
|
81
|
-
exc
|
82
|
-
)
|
83
|
-
logger
|
84
|
-
end
|
85
|
-
|
86
88
|
# Replace Rails loggers
|
87
89
|
%i[active_record action_controller action_mailer action_view].each do |name|
|
88
90
|
ActiveSupport.on_load(name) { include SemanticLogger::Loggable }
|
89
91
|
end
|
90
|
-
ActiveSupport.on_load(:action_cable) { self.logger = SemanticLogger[
|
92
|
+
ActiveSupport.on_load(:action_cable) { self.logger = SemanticLogger["ActionCable"] }
|
91
93
|
end
|
92
94
|
|
93
95
|
# Before any initializers run, but after the gems have been loaded
|
@@ -100,18 +102,18 @@ module RailsSemanticLogger
|
|
100
102
|
end
|
101
103
|
|
102
104
|
# Replace the Mongo Loggers
|
103
|
-
Mongoid.logger
|
104
|
-
Moped.logger
|
105
|
-
Mongo::Logger.logger
|
105
|
+
Mongoid.logger = SemanticLogger[Mongoid] if defined?(Mongoid)
|
106
|
+
Moped.logger = SemanticLogger[Moped] if defined?(Moped)
|
107
|
+
Mongo::Logger.logger = SemanticLogger[Mongo] if defined?(Mongo::Logger)
|
106
108
|
|
107
109
|
# Replace the Resque Logger
|
108
|
-
Resque.logger
|
110
|
+
Resque.logger = SemanticLogger[Resque] if defined?(Resque) && Resque.respond_to?(:logger)
|
109
111
|
|
110
112
|
# Replace the Sidekiq logger
|
111
|
-
Sidekiq
|
113
|
+
Sidekiq.logger = SemanticLogger[Sidekiq] if defined?(Sidekiq)
|
112
114
|
|
113
115
|
# Replace the Sidetiq logger
|
114
|
-
Sidetiq.logger
|
116
|
+
Sidetiq.logger = SemanticLogger[Sidetiq] if defined?(Sidetiq)
|
115
117
|
|
116
118
|
# Replace the DelayedJob logger
|
117
119
|
if defined?(Delayed::Worker)
|
@@ -129,17 +131,36 @@ module RailsSemanticLogger
|
|
129
131
|
Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] } if defined?(Bugsnag)
|
130
132
|
|
131
133
|
# Rails Patches
|
132
|
-
require(
|
133
|
-
require(
|
134
|
-
require(
|
135
|
-
|
136
|
-
|
137
|
-
|
134
|
+
require("rails_semantic_logger/extensions/action_cable/tagged_logger_proxy") if defined?(ActionCable)
|
135
|
+
require("rails_semantic_logger/extensions/action_controller/live") if defined?(ActionController::Live)
|
136
|
+
require("rails_semantic_logger/extensions/action_dispatch/debug_exceptions") if defined?(ActionDispatch::DebugExceptions)
|
137
|
+
if defined?(ActionView::StreamingTemplateRenderer::Body)
|
138
|
+
require("rails_semantic_logger/extensions/action_view/streaming_template_renderer")
|
139
|
+
end
|
140
|
+
require("rails_semantic_logger/extensions/active_job/logging") if defined?(::ActiveJob)
|
141
|
+
require("rails_semantic_logger/extensions/active_model_serializers/logging") if defined?(ActiveModelSerializers)
|
138
142
|
|
139
143
|
if config.rails_semantic_logger.semantic
|
144
|
+
# Active Job
|
145
|
+
if defined?(::ActiveJob) && defined?(::ActiveJob::Logging::LogSubscriber)
|
146
|
+
RailsSemanticLogger.swap_subscriber(
|
147
|
+
::ActiveJob::Logging::LogSubscriber,
|
148
|
+
RailsSemanticLogger::ActiveJob::LogSubscriber,
|
149
|
+
:active_job
|
150
|
+
)
|
151
|
+
end
|
152
|
+
|
153
|
+
if defined?(::ActiveJob) && defined?(::ActiveJob::LogSubscriber)
|
154
|
+
RailsSemanticLogger.swap_subscriber(
|
155
|
+
::ActiveJob::LogSubscriber,
|
156
|
+
RailsSemanticLogger::ActiveJob::LogSubscriber,
|
157
|
+
:active_job
|
158
|
+
)
|
159
|
+
end
|
160
|
+
|
140
161
|
# Active Record
|
141
162
|
if defined?(::ActiveRecord)
|
142
|
-
require
|
163
|
+
require "active_record/log_subscriber"
|
143
164
|
|
144
165
|
RailsSemanticLogger.swap_subscriber(
|
145
166
|
::ActiveRecord::LogSubscriber,
|
@@ -189,7 +210,7 @@ module RailsSemanticLogger
|
|
189
210
|
Resque.after_fork { |_job| ::SemanticLogger.reopen } if defined?(Resque)
|
190
211
|
|
191
212
|
# Re-open appenders after Spring has forked a process
|
192
|
-
Spring.after_fork { |_job| ::SemanticLogger.reopen } if defined?(Spring)
|
213
|
+
Spring.after_fork { |_job| ::SemanticLogger.reopen } if defined?(Spring.after_fork)
|
193
214
|
end
|
194
215
|
end
|
195
216
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Patch ActiveJob logger
|
2
|
-
require
|
2
|
+
require "active_job/logging"
|
3
3
|
|
4
4
|
module ActiveJob
|
5
5
|
module Logging
|
@@ -10,126 +10,5 @@ module ActiveJob
|
|
10
10
|
def tag_logger(*tags, &block)
|
11
11
|
logger.tagged(*tags, &block)
|
12
12
|
end
|
13
|
-
|
14
|
-
class LogSubscriber < ActiveSupport::LogSubscriber
|
15
|
-
def enqueue(event)
|
16
|
-
log_with_formatter event: event do |fmt|
|
17
|
-
"Enqueued #{fmt.job_info}"
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def enqueue_at(event)
|
22
|
-
log_with_formatter event: event do |fmt|
|
23
|
-
"Enqueued #{fmt.job_info} at #{fmt.scheduled_at}"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def perform_start(event)
|
28
|
-
log_with_formatter event: event do |fmt|
|
29
|
-
"Performing #{fmt.job_info}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
def perform(event)
|
34
|
-
ex = event.payload[:exception_object]
|
35
|
-
if ex
|
36
|
-
logger.error ex
|
37
|
-
else
|
38
|
-
log_with_formatter event: event, log_duration: true do |fmt|
|
39
|
-
"Performed #{fmt.job_info} in #{event.duration.round(2)}ms"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
private
|
45
|
-
|
46
|
-
class EventFormatter
|
47
|
-
def initialize(event:, log_duration: false)
|
48
|
-
@event = event
|
49
|
-
@log_duration = log_duration
|
50
|
-
end
|
51
|
-
|
52
|
-
def job_info
|
53
|
-
"#{job.class.name} (Job ID: #{job.job_id}) to #{queue_name}"
|
54
|
-
end
|
55
|
-
|
56
|
-
def payload
|
57
|
-
{}.tap do |h|
|
58
|
-
h[:event_name] = event.name
|
59
|
-
h[:adapter] = adapter_name
|
60
|
-
h[:queue] = job.queue_name
|
61
|
-
h[:job_class] = job.class.name
|
62
|
-
h[:job_id] = job.job_id
|
63
|
-
h[:provider_job_id] = job.try(:provider_job_id) # Not available in Rails 4.2
|
64
|
-
h[:duration] = event.duration.round(2) if log_duration?
|
65
|
-
h[:arguments] = formatted_args
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def queue_name
|
70
|
-
adapter_name + "(#{job.queue_name})"
|
71
|
-
end
|
72
|
-
|
73
|
-
def scheduled_at
|
74
|
-
Time.at(event.payload[:job].scheduled_at).utc
|
75
|
-
end
|
76
|
-
|
77
|
-
private
|
78
|
-
|
79
|
-
attr_reader :event
|
80
|
-
|
81
|
-
def job
|
82
|
-
event.payload[:job]
|
83
|
-
end
|
84
|
-
|
85
|
-
def adapter_name
|
86
|
-
event.payload[:adapter].class.name.demodulize.remove('Adapter')
|
87
|
-
end
|
88
|
-
|
89
|
-
def formatted_args
|
90
|
-
JSON.pretty_generate(job.arguments.map { |arg| format(arg) })
|
91
|
-
end
|
92
|
-
|
93
|
-
def format(arg)
|
94
|
-
case arg
|
95
|
-
when Hash
|
96
|
-
arg.transform_values { |value| format(value) }
|
97
|
-
when Array
|
98
|
-
arg.map { |value| format(value) }
|
99
|
-
when GlobalID::Identification
|
100
|
-
begin
|
101
|
-
arg.to_global_id
|
102
|
-
rescue StandardError
|
103
|
-
arg
|
104
|
-
end
|
105
|
-
else
|
106
|
-
arg
|
107
|
-
end
|
108
|
-
end
|
109
|
-
|
110
|
-
def log_duration?
|
111
|
-
@log_duration
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
def log_with_formatter(**kw_args)
|
116
|
-
fmt = EventFormatter.new(**kw_args)
|
117
|
-
msg = yield fmt
|
118
|
-
logger.info msg, fmt.payload
|
119
|
-
end
|
120
|
-
|
121
|
-
def logger
|
122
|
-
ActiveJob::Base.logger
|
123
|
-
end
|
124
|
-
end
|
125
13
|
end
|
126
14
|
end
|
127
|
-
|
128
|
-
if defined?(ActiveSupport::Notifications)
|
129
|
-
ActiveSupport::Notifications.unsubscribe('perform_start.active_job')
|
130
|
-
ActiveSupport::Notifications.unsubscribe('perform.active_job')
|
131
|
-
ActiveSupport::Notifications.unsubscribe('enqueue_at.active_job')
|
132
|
-
ActiveSupport::Notifications.unsubscribe('enqueue.active_job')
|
133
|
-
|
134
|
-
ActiveJob::Logging::LogSubscriber.attach_to :active_job
|
135
|
-
end
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "active_support/core_ext/time/conversions"
|
2
|
+
require "active_support/core_ext/object/blank"
|
3
|
+
require "active_support/log_subscriber"
|
4
|
+
require "action_dispatch/http/request"
|
5
|
+
require "rack/body_proxy"
|
6
6
|
|
7
7
|
module RailsSemanticLogger
|
8
8
|
module Rack
|
@@ -31,12 +31,12 @@ module RailsSemanticLogger
|
|
31
31
|
|
32
32
|
private
|
33
33
|
|
34
|
-
@logger = SemanticLogger[
|
34
|
+
@logger = SemanticLogger["Rack"]
|
35
35
|
@started_request_log_level = :debug
|
36
36
|
|
37
37
|
def call_app(request, env)
|
38
38
|
instrumenter = ActiveSupport::Notifications.instrumenter
|
39
|
-
instrumenter.start
|
39
|
+
instrumenter.start "request.action_dispatch", request: request
|
40
40
|
|
41
41
|
logger.send(self.class.started_request_log_level) { started_request_message(request) }
|
42
42
|
|
@@ -50,7 +50,7 @@ module RailsSemanticLogger
|
|
50
50
|
|
51
51
|
def started_request_message(request)
|
52
52
|
{
|
53
|
-
message:
|
53
|
+
message: "Started",
|
54
54
|
payload: {
|
55
55
|
method: request.request_method,
|
56
56
|
path: request.filtered_path,
|
@@ -92,7 +92,7 @@ module RailsSemanticLogger
|
|
92
92
|
|
93
93
|
def finish(request)
|
94
94
|
instrumenter = ActiveSupport::Notifications.instrumenter
|
95
|
-
instrumenter.finish
|
95
|
+
instrumenter.finish "request.action_dispatch", request: request
|
96
96
|
end
|
97
97
|
|
98
98
|
def logger
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_semantic_logger
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reid Morrison
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: rack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: railties
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '3.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '3.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: semantic_logger
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,7 +52,7 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '4.4'
|
55
|
-
description:
|
55
|
+
description:
|
56
56
|
email:
|
57
57
|
- reidmo@gmail.com
|
58
58
|
executables: []
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- lib/rails_semantic_logger.rb
|
66
66
|
- lib/rails_semantic_logger/action_controller/log_subscriber.rb
|
67
67
|
- lib/rails_semantic_logger/action_view/log_subscriber.rb
|
68
|
+
- lib/rails_semantic_logger/active_job/log_subscriber.rb
|
68
69
|
- lib/rails_semantic_logger/active_record/log_subscriber.rb
|
69
70
|
- lib/rails_semantic_logger/delayed_job/plugin.rb
|
70
71
|
- lib/rails_semantic_logger/engine.rb
|
@@ -82,7 +83,7 @@ homepage: https://github.com/rocketjob/rails_semantic_logger
|
|
82
83
|
licenses:
|
83
84
|
- Apache-2.0
|
84
85
|
metadata: {}
|
85
|
-
post_install_message:
|
86
|
+
post_install_message:
|
86
87
|
rdoc_options: []
|
87
88
|
require_paths:
|
88
89
|
- lib
|
@@ -97,8 +98,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
97
98
|
- !ruby/object:Gem::Version
|
98
99
|
version: '0'
|
99
100
|
requirements: []
|
100
|
-
rubygems_version: 3.
|
101
|
-
signing_key:
|
101
|
+
rubygems_version: 3.2.3
|
102
|
+
signing_key:
|
102
103
|
specification_version: 4
|
103
104
|
summary: Feature rich logging framework that replaces the Rails logger.
|
104
105
|
test_files: []
|