rails_semantic_logger 4.2.1 → 4.3.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 +3 -6
- data/Rakefile +2 -2
- data/lib/rails_semantic_logger.rb +35 -0
- data/lib/rails_semantic_logger/action_controller/log_subscriber.rb +108 -0
- data/lib/rails_semantic_logger/action_view/log_subscriber.rb +108 -0
- data/lib/rails_semantic_logger/active_record/log_subscriber.rb +186 -0
- data/lib/rails_semantic_logger/delayed_job/plugin.rb +11 -0
- data/lib/rails_semantic_logger/engine.rb +80 -70
- data/lib/rails_semantic_logger/extensions/action_controller/live.rb +5 -3
- data/lib/rails_semantic_logger/extensions/action_dispatch/debug_exceptions.rb +8 -6
- data/lib/rails_semantic_logger/extensions/action_view/streaming_template_renderer.rb +8 -5
- data/lib/rails_semantic_logger/extensions/active_job/logging.rb +8 -5
- data/lib/rails_semantic_logger/extensions/active_model_serializers/logging.rb +11 -8
- data/lib/rails_semantic_logger/extensions/rails/server.rb +2 -2
- data/lib/rails_semantic_logger/rack/logger.rb +103 -0
- data/lib/rails_semantic_logger/version.rb +2 -2
- metadata +13 -14
- data/lib/rails_semantic_logger/extensions/action_controller/log_subscriber.rb +0 -111
- data/lib/rails_semantic_logger/extensions/action_controller/log_subscriber_processing.rb +0 -28
- data/lib/rails_semantic_logger/extensions/action_view/log_subscriber.rb +0 -12
- data/lib/rails_semantic_logger/extensions/active_record/log_subscriber.rb +0 -102
- data/lib/rails_semantic_logger/extensions/rails/rack/logger.rb +0 -63
- data/lib/rails_semantic_logger/extensions/rails/rack/logger_info_as_debug.rb +0 -30
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'active_record/log_subscriber'
|
2
|
+
require 'action_controller/log_subscriber'
|
3
|
+
|
1
4
|
module RailsSemanticLogger
|
2
5
|
class Engine < ::Rails::Engine
|
3
6
|
# Make the SemanticLogger config available in the Rails application config
|
@@ -16,22 +19,22 @@ module RailsSemanticLogger
|
|
16
19
|
# end
|
17
20
|
config.semantic_logger = ::SemanticLogger
|
18
21
|
|
19
|
-
config.rails_semantic_logger
|
22
|
+
config.rails_semantic_logger = ActiveSupport::OrderedOptions.new
|
20
23
|
|
21
24
|
# Convert Action Controller and Active Record text messages to semantic data
|
22
25
|
# Rails -- Started -- { :ip => "127.0.0.1", :method => "GET", :path => "/dashboards/inquiry_recent_activity" }
|
23
26
|
# UserController -- Completed #index -- { :action => "index", :db_runtime => 54.64, :format => "HTML", :method => "GET", :mongo_runtime => 0.0, :path => "/users", :status => 200, :status_message => "OK", :view_runtime => 709.88 }
|
24
|
-
config.rails_semantic_logger.semantic
|
27
|
+
config.rails_semantic_logger.semantic = true
|
25
28
|
|
26
29
|
# Change Rack started message to debug so that it does not appear in production
|
27
|
-
config.rails_semantic_logger.started
|
30
|
+
config.rails_semantic_logger.started = false
|
28
31
|
|
29
32
|
# Change Processing message to debug so that it does not appear in production
|
30
|
-
config.rails_semantic_logger.processing
|
33
|
+
config.rails_semantic_logger.processing = false
|
31
34
|
|
32
35
|
# Change Action View render log messages to debug so that they do not appear in production
|
33
36
|
# ActionView::Base -- Rendered data/search/_user.html.haml (46.7ms)
|
34
|
-
config.rails_semantic_logger.rendered
|
37
|
+
config.rails_semantic_logger.rendered = false
|
35
38
|
|
36
39
|
# Override the Awesome Print options for logging Hash data as text:
|
37
40
|
#
|
@@ -41,7 +44,7 @@ module RailsSemanticLogger
|
|
41
44
|
#
|
42
45
|
# Note: The option :multiline is set to false if not supplied.
|
43
46
|
# Note: Has no effect if Awesome Print is not installed.
|
44
|
-
config.rails_semantic_logger.ap_options
|
47
|
+
config.rails_semantic_logger.ap_options = {multiline: false}
|
45
48
|
|
46
49
|
# Whether to automatically add an environment specific log file appender.
|
47
50
|
# For Example: 'log/development.log'
|
@@ -54,7 +57,7 @@ module RailsSemanticLogger
|
|
54
57
|
config.rails_semantic_logger.add_file_appender = true
|
55
58
|
|
56
59
|
# Silence asset logging
|
57
|
-
config.rails_semantic_logger.quiet_assets
|
60
|
+
config.rails_semantic_logger.quiet_assets = false
|
58
61
|
|
59
62
|
# Override the output format for the primary Rails log file.
|
60
63
|
#
|
@@ -90,18 +93,18 @@ module RailsSemanticLogger
|
|
90
93
|
#
|
91
94
|
# # In application.rb:
|
92
95
|
# config.rails_semantic_logger.format = MyFormatter.new
|
93
|
-
config.rails_semantic_logger.format
|
96
|
+
config.rails_semantic_logger.format = :default
|
94
97
|
|
95
98
|
# DEPRECATED
|
96
99
|
# Instead, supply a Hash to config.log_tags
|
97
|
-
config.rails_semantic_logger.named_tags
|
100
|
+
config.rails_semantic_logger.named_tags = nil
|
98
101
|
|
99
102
|
# Add a filter to the file logger [Regexp|Proc]
|
100
103
|
# RegExp: Only include log messages where the class name matches the supplied
|
101
104
|
# regular expression. All other messages will be ignored.
|
102
105
|
# Proc: Only include log messages where the supplied Proc returns true.
|
103
106
|
# The Proc must return true or false.
|
104
|
-
config.rails_semantic_logger.filter
|
107
|
+
config.rails_semantic_logger.filter = nil
|
105
108
|
|
106
109
|
# Initialize SemanticLogger. In a Rails environment it will automatically
|
107
110
|
# insert itself above the configured rails logger to add support for its
|
@@ -111,14 +114,18 @@ module RailsSemanticLogger
|
|
111
114
|
Rails::Application::Bootstrap.initializers.delete_if { |i| i.name == :initialize_logger }
|
112
115
|
|
113
116
|
initializer :initialize_logger, group: :all do
|
114
|
-
config
|
117
|
+
config = Rails.application.config
|
115
118
|
|
116
119
|
# Set the default log level based on the Rails config
|
117
120
|
SemanticLogger.default_level = config.log_level
|
118
121
|
|
122
|
+
if defined?(Rails::Rack::Logger) && config.rails_semantic_logger.semantic
|
123
|
+
config.middleware.swap(Rails::Rack::Logger, RailsSemanticLogger::Rack::Logger, config.log_tags)
|
124
|
+
end
|
125
|
+
|
119
126
|
# Existing loggers are ignored because servers like trinidad supply their
|
120
127
|
# own file loggers which would result in duplicate logging to the same log file
|
121
|
-
Rails.logger
|
128
|
+
Rails.logger = config.logger = begin
|
122
129
|
if config.rails_semantic_logger.add_file_appender
|
123
130
|
path = config.paths['log'].first
|
124
131
|
FileUtils.mkdir_p(File.dirname(path)) unless File.exist?(File.dirname(path))
|
@@ -130,16 +137,16 @@ module RailsSemanticLogger
|
|
130
137
|
formatter = {color: {ap: ap_options}} if (formatter == :default) && (config.colorize_logging != false)
|
131
138
|
|
132
139
|
# Set internal logger to log to file only, in case another appender experiences errors during writes
|
133
|
-
appender
|
140
|
+
appender = SemanticLogger::Appender::File.new(
|
141
|
+
file_name: path,
|
142
|
+
level: config.log_level,
|
143
|
+
formatter: formatter
|
144
|
+
)
|
134
145
|
appender.name = 'SemanticLogger'
|
135
146
|
SemanticLogger::Processor.logger = appender
|
136
147
|
|
137
148
|
# Check for previous file or stdout loggers
|
138
|
-
if SemanticLogger::
|
139
|
-
SemanticLogger.appenders.each { |appender| appender.formatter = formatter if appender.is_a?(SemanticLogger::Appender::File) }
|
140
|
-
elsif config.colorize_logging == false
|
141
|
-
SemanticLogger.appenders.each { |appender| appender.formatter = SemanticLogger::Formatters::Default.new if appender.is_a?(SemanticLogger::Appender::File) }
|
142
|
-
end
|
149
|
+
SemanticLogger.appenders.each { |app| app.formatter = formatter if app.is_a?(SemanticLogger::Appender::File) }
|
143
150
|
SemanticLogger.add_appender(file_name: path, formatter: formatter, filter: config.rails_semantic_logger.filter)
|
144
151
|
end
|
145
152
|
|
@@ -153,54 +160,29 @@ module RailsSemanticLogger
|
|
153
160
|
|
154
161
|
logger = SemanticLogger[Rails]
|
155
162
|
logger.warn(
|
156
|
-
"Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. "
|
157
|
-
|
163
|
+
"Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " \
|
164
|
+
'The log level has been raised to WARN and the output directed to STDERR until the problem is fixed.',
|
158
165
|
exc
|
159
166
|
)
|
160
167
|
logger
|
161
168
|
end
|
162
169
|
|
163
170
|
# Replace Rails loggers
|
164
|
-
[
|
171
|
+
%i[active_record action_controller action_mailer action_view].each do |name|
|
165
172
|
ActiveSupport.on_load(name) { include SemanticLogger::Loggable }
|
166
173
|
end
|
167
174
|
ActiveSupport.on_load(:action_cable) { self.logger = SemanticLogger['ActionCable'] }
|
168
175
|
end
|
169
176
|
|
170
|
-
#
|
171
|
-
config.
|
172
|
-
|
173
|
-
|
174
|
-
assets_regex = %r(\A/{0,2}#{config.assets.prefix})
|
175
|
-
if Rails.version.to_i >= 5
|
176
|
-
Rails::Rack::Logger.logger.filter = -> log { log.payload[:path] !~ assets_regex if log.payload }
|
177
|
-
else
|
178
|
-
# Also strips the empty log lines
|
179
|
-
Rails::Rack::Logger.logger.filter = -> log { log.payload.nil? ? (log.message != '') : (log.payload[:path] !~ assets_regex) }
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
|
-
# Passenger provides the :starting_worker_process event for executing
|
184
|
-
# code after it has forked, so we use that and reconnect immediately.
|
185
|
-
if defined?(PhusionPassenger)
|
186
|
-
PhusionPassenger.on_event(:starting_worker_process) do |forked|
|
187
|
-
::SemanticLogger.reopen if forked
|
188
|
-
end
|
189
|
-
end
|
190
|
-
|
191
|
-
# Re-open appenders after Resque has forked a worker
|
192
|
-
if defined?(Resque)
|
193
|
-
Resque.after_fork { |job| ::SemanticLogger.reopen }
|
194
|
-
end
|
177
|
+
# Before any initializers run, but after the gems have been loaded
|
178
|
+
config.before_initialize do
|
179
|
+
if config.respond_to?(:assets) && defined?(Rails::Rack::Logger) && config.rails_semantic_logger.semantic
|
180
|
+
config.rails_semantic_logger.quiet_assets = true if config.assets.quiet
|
195
181
|
|
196
|
-
|
197
|
-
|
198
|
-
Spring.after_fork { |job| ::SemanticLogger.reopen }
|
182
|
+
# Otherwise Sprockets can't find the Rails::Rack::Logger middleware
|
183
|
+
config.assets.quiet = false
|
199
184
|
end
|
200
|
-
end
|
201
185
|
|
202
|
-
# Before any initializers run, but after the gems have been loaded
|
203
|
-
config.before_initialize do
|
204
186
|
# Replace the Mongo Loggers
|
205
187
|
Mongoid.logger = SemanticLogger[Mongoid] if defined?(Mongoid)
|
206
188
|
Moped.logger = SemanticLogger[Moped] if defined?(Moped)
|
@@ -216,15 +198,13 @@ module RailsSemanticLogger
|
|
216
198
|
Sidetiq.logger = SemanticLogger[Sidetiq] if defined?(Sidetiq)
|
217
199
|
|
218
200
|
# Replace the DelayedJob logger
|
219
|
-
|
201
|
+
if defined?(Delayed::Worker)
|
202
|
+
Delayed::Worker.logger = SemanticLogger[Delayed::Worker]
|
203
|
+
Delayed::Worker.plugins << RailsSemanticLogger::DelayedJob::Plugin
|
204
|
+
end
|
220
205
|
|
221
206
|
# Replace the Bugsnag logger
|
222
207
|
Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] } if defined?(Bugsnag)
|
223
|
-
|
224
|
-
# Backward compatibility
|
225
|
-
if config.rails_semantic_logger.named_tags
|
226
|
-
config.log_tags = config.rails_semantic_logger.named_tags
|
227
|
-
end
|
228
208
|
end
|
229
209
|
|
230
210
|
# After any initializers run, but after the gems have been loaded
|
@@ -241,23 +221,53 @@ module RailsSemanticLogger
|
|
241
221
|
require('rails_semantic_logger/extensions/active_model_serializers/logging') if defined?(ActiveModelSerializers)
|
242
222
|
|
243
223
|
if config.rails_semantic_logger.semantic
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
224
|
+
# Active Record
|
225
|
+
RailsSemanticLogger.swap_subscriber(
|
226
|
+
::ActiveRecord::LogSubscriber,
|
227
|
+
RailsSemanticLogger::ActiveRecord::LogSubscriber,
|
228
|
+
:active_record
|
229
|
+
)
|
248
230
|
|
249
|
-
|
250
|
-
|
251
|
-
|
231
|
+
# Rack
|
232
|
+
RailsSemanticLogger::Rack::Logger.started_request_log_level = :info if config.rails_semantic_logger.started
|
233
|
+
|
234
|
+
# Silence asset logging by applying a filter to the Rails logger itself, not any of the appenders.
|
235
|
+
if config.rails_semantic_logger.quiet_assets && config.assets.prefix
|
236
|
+
assets_regex = %r(\A/{0,2}#{config.assets.prefix})
|
237
|
+
RailsSemanticLogger::Rack::Logger.logger.filter = ->(log) { log.payload[:path] !~ assets_regex if log.payload }
|
238
|
+
end
|
239
|
+
|
240
|
+
# Action View
|
241
|
+
RailsSemanticLogger::ActionView::LogSubscriber.rendered_log_level = :info if config.rails_semantic_logger.rendered
|
242
|
+
RailsSemanticLogger.swap_subscriber(
|
243
|
+
::ActionView::LogSubscriber,
|
244
|
+
RailsSemanticLogger::ActionView::LogSubscriber,
|
245
|
+
:action_view
|
246
|
+
)
|
252
247
|
|
253
|
-
|
254
|
-
|
248
|
+
# Action Controller
|
249
|
+
RailsSemanticLogger.swap_subscriber(
|
250
|
+
::ActionController::LogSubscriber,
|
251
|
+
RailsSemanticLogger::ActionController::LogSubscriber,
|
252
|
+
:action_controller
|
253
|
+
)
|
255
254
|
end
|
256
255
|
|
257
|
-
|
258
|
-
|
256
|
+
#
|
257
|
+
# Forking Frameworks
|
258
|
+
#
|
259
|
+
|
260
|
+
# Passenger provides the :starting_worker_process event for executing
|
261
|
+
# code after it has forked, so we use that and reconnect immediately.
|
262
|
+
if defined?(PhusionPassenger)
|
263
|
+
PhusionPassenger.on_event(:starting_worker_process) { |forked| ::SemanticLogger.reopen if forked }
|
259
264
|
end
|
260
|
-
end
|
261
265
|
|
266
|
+
# Re-open appenders after Resque has forked a worker
|
267
|
+
Resque.after_fork { |_job| ::SemanticLogger.reopen } if defined?(Resque)
|
268
|
+
|
269
|
+
# Re-open appenders after Spring has forked a process
|
270
|
+
Spring.after_fork { |_job| ::SemanticLogger.reopen } if defined?(Spring)
|
271
|
+
end
|
262
272
|
end
|
263
273
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
# Log actual exceptions, not a string representation
|
2
2
|
ActionController::Live
|
3
|
-
module ActionController
|
4
|
-
|
5
|
-
|
3
|
+
module ActionController
|
4
|
+
module Live
|
5
|
+
def log_error(exception)
|
6
|
+
logger.fatal(exception)
|
7
|
+
end
|
6
8
|
end
|
7
9
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# Log actual exceptions, not a string representation
|
2
2
|
ActionDispatch::DebugExceptions
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
module ActionDispatch
|
4
|
+
class DebugExceptions
|
5
|
+
private
|
6
|
+
|
7
|
+
def log_error(_request, wrapper)
|
8
|
+
ActiveSupport::Deprecation.silence do
|
9
|
+
ActionController::Base.logger.fatal(wrapper.exception)
|
10
|
+
end
|
8
11
|
end
|
9
12
|
end
|
10
13
|
end
|
11
|
-
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# Log actual exceptions, not a string representation
|
2
2
|
ActionView::StreamingTemplateRenderer
|
3
3
|
|
4
|
-
|
5
|
-
class
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
module ActionView
|
5
|
+
class StreamingTemplateRenderer
|
6
|
+
class Body
|
7
|
+
private
|
8
|
+
|
9
|
+
def log_error(exception)
|
10
|
+
ActionView::Base.logger.fatal(exception)
|
11
|
+
end
|
9
12
|
end
|
10
13
|
end
|
11
14
|
end
|
@@ -1,11 +1,14 @@
|
|
1
1
|
# Patch ActiveJob logger
|
2
2
|
require 'active_job/logging'
|
3
3
|
|
4
|
-
module ActiveJob
|
5
|
-
|
4
|
+
module ActiveJob
|
5
|
+
module Logging
|
6
|
+
include SemanticLogger::Loggable
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
private
|
9
|
+
|
10
|
+
def tag_logger(*tags, &block)
|
11
|
+
logger.tagged(*tags, &block)
|
12
|
+
end
|
10
13
|
end
|
11
14
|
end
|
@@ -1,15 +1,18 @@
|
|
1
1
|
# Patch ActiveModelSerializers logger
|
2
2
|
require 'active_model_serializers/logging'
|
3
3
|
|
4
|
-
module ActiveModelSerializers
|
5
|
-
|
4
|
+
module ActiveModelSerializers
|
5
|
+
module Logging
|
6
|
+
include SemanticLogger::Loggable
|
6
7
|
|
7
|
-
|
8
|
-
|
9
|
-
|
8
|
+
private
|
9
|
+
|
10
|
+
def tag_logger(*tags, &block)
|
11
|
+
logger.tagged(*tags, &block)
|
12
|
+
end
|
10
13
|
end
|
11
|
-
end
|
12
14
|
|
13
|
-
class
|
14
|
-
|
15
|
+
class SerializableResource
|
16
|
+
include SemanticLogger::Loggable
|
17
|
+
end
|
15
18
|
end
|
@@ -0,0 +1,103 @@
|
|
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
|
+
|
7
|
+
module RailsSemanticLogger
|
8
|
+
module Rack
|
9
|
+
class Logger < ActiveSupport::LogSubscriber
|
10
|
+
class << self
|
11
|
+
attr_reader :logger
|
12
|
+
attr_accessor :started_request_log_level
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(app, taggers = nil)
|
16
|
+
@app = app
|
17
|
+
@taggers = taggers || []
|
18
|
+
end
|
19
|
+
|
20
|
+
def call(env)
|
21
|
+
request = ActionDispatch::Request.new(env)
|
22
|
+
|
23
|
+
# Check for named tags (Hash)
|
24
|
+
if @taggers && !@taggers.empty?
|
25
|
+
tags = @taggers.is_a?(Hash) ? compute_named_tags(request) : compute_tags(request)
|
26
|
+
logger.tagged(tags) { call_app(request, env) }
|
27
|
+
else
|
28
|
+
call_app(request, env)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
@logger = SemanticLogger['Rack']
|
35
|
+
@started_request_log_level = :debug
|
36
|
+
|
37
|
+
def call_app(request, env)
|
38
|
+
instrumenter = ActiveSupport::Notifications.instrumenter
|
39
|
+
instrumenter.start 'request.action_dispatch', request: request
|
40
|
+
|
41
|
+
logger.send(self.class.started_request_log_level) { started_request_message(request) }
|
42
|
+
|
43
|
+
status, headers, body = @app.call(env)
|
44
|
+
body = ::Rack::BodyProxy.new(body) { finish(request) }
|
45
|
+
[status, headers, body]
|
46
|
+
rescue Exception
|
47
|
+
finish(request)
|
48
|
+
raise
|
49
|
+
end
|
50
|
+
|
51
|
+
def started_request_message(request)
|
52
|
+
{
|
53
|
+
message: 'Started',
|
54
|
+
payload: {
|
55
|
+
method: request.request_method,
|
56
|
+
path: request.filtered_path,
|
57
|
+
ip: request.ip
|
58
|
+
}
|
59
|
+
}
|
60
|
+
end
|
61
|
+
|
62
|
+
def compute_tags(request)
|
63
|
+
@taggers.collect do |tag|
|
64
|
+
case tag
|
65
|
+
when Proc
|
66
|
+
tag.call(request)
|
67
|
+
when Symbol
|
68
|
+
request.send(tag)
|
69
|
+
else
|
70
|
+
tag
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
# Leave out any named tags with a nil value
|
76
|
+
def compute_named_tags(request)
|
77
|
+
tagged = {}
|
78
|
+
@taggers.each_pair do |tag, value|
|
79
|
+
resolved =
|
80
|
+
case value
|
81
|
+
when Proc
|
82
|
+
value.call(request)
|
83
|
+
when Symbol
|
84
|
+
request.send(value)
|
85
|
+
else
|
86
|
+
value
|
87
|
+
end
|
88
|
+
tagged[tag] = resolved unless resolved.nil?
|
89
|
+
end
|
90
|
+
tagged
|
91
|
+
end
|
92
|
+
|
93
|
+
def finish(request)
|
94
|
+
instrumenter = ActiveSupport::Notifications.instrumenter
|
95
|
+
instrumenter.finish 'request.action_dispatch', request: request
|
96
|
+
end
|
97
|
+
|
98
|
+
def logger
|
99
|
+
self.class.logger
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|