rails_semantic_logger 4.1.3 → 4.12.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.
Files changed (32) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +17 -10
  3. data/Rakefile +9 -9
  4. data/lib/rails_semantic_logger/action_controller/log_subscriber.rb +125 -0
  5. data/lib/rails_semantic_logger/action_mailer/log_subscriber.rb +135 -0
  6. data/lib/rails_semantic_logger/action_view/log_subscriber.rb +111 -0
  7. data/lib/rails_semantic_logger/active_job/log_subscriber.rb +126 -0
  8. data/lib/rails_semantic_logger/active_record/log_subscriber.rb +218 -0
  9. data/lib/rails_semantic_logger/delayed_job/plugin.rb +11 -0
  10. data/lib/rails_semantic_logger/engine.rb +189 -194
  11. data/lib/rails_semantic_logger/extensions/action_cable/tagged_logger_proxy.rb +1 -1
  12. data/lib/rails_semantic_logger/extensions/action_controller/live.rb +8 -4
  13. data/lib/rails_semantic_logger/extensions/action_dispatch/debug_exceptions.rb +11 -7
  14. data/lib/rails_semantic_logger/extensions/action_view/streaming_template_renderer.rb +10 -6
  15. data/lib/rails_semantic_logger/extensions/active_job/logging.rb +10 -6
  16. data/lib/rails_semantic_logger/extensions/active_model_serializers/logging.rb +12 -9
  17. data/lib/rails_semantic_logger/extensions/active_support/logger.rb +24 -0
  18. data/lib/rails_semantic_logger/extensions/active_support/tagged_logging.rb +8 -0
  19. data/lib/rails_semantic_logger/extensions/mongoid/config.rb +11 -0
  20. data/lib/rails_semantic_logger/extensions/rack/server.rb +12 -0
  21. data/lib/rails_semantic_logger/extensions/rails/server.rb +9 -5
  22. data/lib/rails_semantic_logger/options.rb +122 -0
  23. data/lib/rails_semantic_logger/rack/logger.rb +100 -0
  24. data/lib/rails_semantic_logger/version.rb +2 -2
  25. data/lib/rails_semantic_logger.rb +58 -3
  26. metadata +46 -24
  27. data/lib/rails_semantic_logger/extensions/action_controller/log_subscriber.rb +0 -107
  28. data/lib/rails_semantic_logger/extensions/action_controller/log_subscriber_processing.rb +0 -28
  29. data/lib/rails_semantic_logger/extensions/action_view/log_subscriber.rb +0 -12
  30. data/lib/rails_semantic_logger/extensions/active_record/log_subscriber.rb +0 -44
  31. data/lib/rails_semantic_logger/extensions/rails/rack/logger.rb +0 -63
  32. data/lib/rails_semantic_logger/extensions/rails/rack/logger_info_as_debug.rb +0 -30
@@ -0,0 +1,218 @@
1
+ module RailsSemanticLogger
2
+ module ActiveRecord
3
+ class LogSubscriber < ActiveSupport::LogSubscriber
4
+ IGNORE_PAYLOAD_NAMES = %w[SCHEMA EXPLAIN].freeze
5
+
6
+ class << self
7
+ attr_reader :logger
8
+ end
9
+
10
+ def self.runtime=(value)
11
+ ::ActiveRecord::RuntimeRegistry.sql_runtime = value
12
+ end
13
+
14
+ def self.runtime
15
+ ::ActiveRecord::RuntimeRegistry.sql_runtime ||= 0
16
+ end
17
+
18
+ def self.reset_runtime
19
+ rt = runtime
20
+ self.runtime = 0
21
+ rt
22
+ end
23
+
24
+ def sql(event)
25
+ self.class.runtime += event.duration
26
+ return unless logger.debug?
27
+
28
+ payload = event.payload
29
+ name = payload[:name]
30
+ return if IGNORE_PAYLOAD_NAMES.include?(name)
31
+
32
+ log_payload = {sql: payload[:sql]}
33
+ log_payload[:binds] = bind_values(payload) unless (payload[:binds] || []).empty?
34
+ log_payload[:allocations] = event.allocations if event.respond_to?(:allocations)
35
+ log_payload[:cached] = event.payload[:cached]
36
+
37
+ log = {
38
+ message: name,
39
+ payload: log_payload,
40
+ duration: event.duration
41
+ }
42
+
43
+ # Log the location of the query itself.
44
+ if logger.send(:level_index) >= SemanticLogger.backtrace_level_index
45
+ log[:backtrace] = SemanticLogger::Utils.strip_backtrace(caller)
46
+ end
47
+
48
+ logger.debug(log)
49
+ end
50
+
51
+ private
52
+
53
+ @logger = SemanticLogger["ActiveRecord"]
54
+
55
+ # When multiple values are received for a single bound field, it is converted into an array
56
+ def add_bind_value(binds, key, value)
57
+ key = key.downcase.to_sym unless key.nil?
58
+ value = (Array(binds[key]) << value) if binds.key?(key)
59
+ binds[key] = value
60
+ end
61
+
62
+ def logger
63
+ self.class.logger
64
+ end
65
+
66
+ #
67
+ # Rails 3,4,5 hell trying to get the bind values
68
+ #
69
+
70
+ def bind_values_v3(payload)
71
+ binds = {}
72
+ payload[:binds].each do |col, v|
73
+ if col
74
+ add_bind_value(binds, col.name, v)
75
+ else
76
+ binds[nil] = v
77
+ end
78
+ end
79
+ binds
80
+ end
81
+
82
+ def bind_values_v4(payload)
83
+ binds = {}
84
+ payload[:binds].each do |col, v|
85
+ attr_name, value = render_bind(col, v)
86
+ add_bind_value(binds, attr_name, value)
87
+ end
88
+ binds
89
+ end
90
+
91
+ def bind_values_v5_0_0(payload)
92
+ binds = {}
93
+ payload[:binds].each do |attr|
94
+ attr_name, value = render_bind(attr)
95
+ add_bind_value(binds, attr_name, value)
96
+ end
97
+ binds
98
+ end
99
+
100
+ def bind_values_v5_0_3(payload)
101
+ binds = {}
102
+ casted_params = type_casted_binds(payload[:binds], payload[:type_casted_binds])
103
+ payload[:binds].zip(casted_params).map do |attr, value|
104
+ attr_name, value = render_bind(attr, value)
105
+ add_bind_value(binds, attr_name, value)
106
+ end
107
+ binds
108
+ end
109
+
110
+ def bind_values_v5_1_5(payload)
111
+ binds = {}
112
+ casted_params = type_casted_binds(payload[:type_casted_binds])
113
+ payload[:binds].zip(casted_params).map do |attr, value|
114
+ attr_name, value = render_bind(attr, value)
115
+ add_bind_value(binds, attr_name, value)
116
+ end
117
+ binds
118
+ end
119
+
120
+ def bind_values_v6_1(payload)
121
+ binds = {}
122
+ casted_params = type_casted_binds(payload[:type_casted_binds])
123
+ payload[:binds].each_with_index do |attr, i|
124
+ attr_name, value = render_bind(attr, casted_params[i])
125
+ add_bind_value(binds, attr_name, value)
126
+ end
127
+ binds
128
+ end
129
+
130
+ def render_bind_v4_2(column, value)
131
+ if column
132
+ if column.binary?
133
+ # This specifically deals with the PG adapter that casts bytea columns into a Hash.
134
+ value = value[:value] if value.is_a?(Hash)
135
+ value = value ? "<#{value.bytesize} bytes of binary data>" : "<NULL binary data>"
136
+ end
137
+
138
+ [column.name, value]
139
+ else
140
+ [nil, value]
141
+ end
142
+ end
143
+
144
+ def render_bind_v5_0_0(attribute)
145
+ value =
146
+ if attribute.type.binary? && attribute.value
147
+ if attribute.value.is_a?(Hash)
148
+ "<#{attribute.value_for_database.to_s.bytesize} bytes of binary data>"
149
+ else
150
+ "<#{attribute.value.bytesize} bytes of binary data>"
151
+ end
152
+ else
153
+ attribute.value_for_database
154
+ end
155
+
156
+ [attribute.name, value]
157
+ end
158
+
159
+ def render_bind_v5_0_3(attr, value)
160
+ if attr.is_a?(Array)
161
+ attr = attr.first
162
+ elsif attr.type.binary? && attr.value
163
+ value = "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
164
+ end
165
+
166
+ [attr&.name, value]
167
+ end
168
+
169
+ def render_bind_v6_1(attr, value)
170
+ case attr
171
+ when ActiveModel::Attribute
172
+ if attr.type.binary? && attr.value
173
+ value = "<#{attr.value_for_database.to_s.bytesize} bytes of binary data>"
174
+ end
175
+ when Array
176
+ attr = attr.first
177
+ else
178
+ attr = nil
179
+ end
180
+
181
+ [attr&.name || :nil, value]
182
+ end
183
+
184
+ def type_casted_binds_v5_0_3(binds, casted_binds)
185
+ casted_binds || ::ActiveRecord::Base.connection.type_casted_binds(binds)
186
+ end
187
+
188
+ def type_casted_binds_v5_1_5(casted_binds)
189
+ casted_binds.respond_to?(:call) ? casted_binds.call : casted_binds
190
+ end
191
+
192
+ if Rails::VERSION::MAJOR == 5 && Rails::VERSION::MINOR.zero? && Rails::VERSION::TINY <= 2 # 5.0.0 - 5.0.2
193
+ alias bind_values bind_values_v5_0_0
194
+ alias render_bind render_bind_v5_0_0
195
+ elsif Rails::VERSION::MAJOR == 5 &&
196
+ ((Rails::VERSION::MINOR.zero? && Rails::VERSION::TINY <= 6) ||
197
+ (Rails::VERSION::MINOR == 1 && Rails::VERSION::TINY <= 4)) # 5.0.3 - 5.0.6 && 5.1.0 - 5.1.4
198
+ alias bind_values bind_values_v5_0_3
199
+ alias render_bind render_bind_v5_0_3
200
+ alias type_casted_binds type_casted_binds_v5_0_3
201
+ elsif (Rails::VERSION::MAJOR == 6 && Rails::VERSION::MINOR > 0) || # ~> 6.1.0
202
+ Rails::VERSION::MAJOR == 7
203
+ alias bind_values bind_values_v6_1
204
+ alias render_bind render_bind_v6_1
205
+ alias type_casted_binds type_casted_binds_v5_1_5
206
+ elsif Rails::VERSION::MAJOR >= 5 # ~> 5.1.5 && ~> 5.0.7 && 6.x.x
207
+ alias bind_values bind_values_v5_1_5
208
+ alias render_bind render_bind_v5_0_3
209
+ alias type_casted_binds type_casted_binds_v5_1_5
210
+ elsif Rails.version.to_i >= 4 # 4.x
211
+ alias bind_values bind_values_v4
212
+ alias render_bind render_bind_v4_2
213
+ else # 3.x
214
+ alias bind_values bind_values_v3
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,11 @@
1
+ module RailsSemanticLogger
2
+ module DelayedJob
3
+ class Plugin < Delayed::Plugin
4
+ callbacks do |lifecycle|
5
+ lifecycle.before(:execute) do |_job|
6
+ ::SemanticLogger.reopen
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,6 @@
1
+ require "rails"
2
+ require "rails_semantic_logger/options"
3
+
1
4
  module RailsSemanticLogger
2
5
  class Engine < ::Rails::Engine
3
6
  # Make the SemanticLogger config available in the Rails application config
@@ -16,92 +19,7 @@ module RailsSemanticLogger
16
19
  # end
17
20
  config.semantic_logger = ::SemanticLogger
18
21
 
19
- config.rails_semantic_logger = ActiveSupport::OrderedOptions.new
20
-
21
- # Convert Action Controller and Active Record text messages to semantic data
22
- # Rails -- Started -- { :ip => "127.0.0.1", :method => "GET", :path => "/dashboards/inquiry_recent_activity" }
23
- # 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 = true
25
-
26
- # Change Rack started message to debug so that it does not appear in production
27
- config.rails_semantic_logger.started = false
28
-
29
- # Change Processing message to debug so that it does not appear in production
30
- config.rails_semantic_logger.processing = false
31
-
32
- # Change Action View render log messages to debug so that they do not appear in production
33
- # ActionView::Base -- Rendered data/search/_user.html.haml (46.7ms)
34
- config.rails_semantic_logger.rendered = false
35
-
36
- # Override the Awesome Print options for logging Hash data as text:
37
- #
38
- # Any valid AwesomePrint option for rendering data.
39
- # The defaults can changed be creating a `~/.aprc` file.
40
- # See: https://github.com/michaeldv/awesome_print
41
- #
42
- # Note: The option :multiline is set to false if not supplied.
43
- # Note: Has no effect if Awesome Print is not installed.
44
- config.rails_semantic_logger.ap_options = {multiline: false}
45
-
46
- # Whether to automatically add an environment specific log file appender.
47
- # For Example: 'log/development.log'
48
- #
49
- # Note:
50
- # When Semantic Logger fails to log to an appender it logs the error to an
51
- # internal logger, which by default writes to STDERR.
52
- # Example, change the default internal logger to log to stdout:
53
- # SemanticLogger::Processor.logger = SemanticLogger::Appender::File.new(io: STDOUT, level: :warn)
54
- config.rails_semantic_logger.add_file_appender = true
55
-
56
- # Silence asset logging
57
- config.rails_semantic_logger.quiet_assets = false
58
-
59
- # Override the output format for the primary Rails log file.
60
- #
61
- # Valid options:
62
- # * :default
63
- # Plain text output with no color.
64
- # * :color
65
- # Plain text output with color.
66
- # * :json
67
- # JSON output format.
68
- # * class
69
- #
70
- # * Proc
71
- # A block that will be called to format the output.
72
- # It is supplied with the `log` entry and should return the formatted data.
73
- #
74
- # Note:
75
- # * `:default` is automatically changed to `:color` if `config.colorize_logging` is `true`.
76
- #
77
- # JSON Example, in `application.rb`:
78
- #
79
- # config.rails_semantic_logger.format = :json
80
- #
81
- # Custom Example, create `app/lib/my_formatter.rb`:
82
- #
83
- # # My Custom colorized formatter
84
- # class MyFormatter < SemanticLogger::Formatters::Color
85
- # # Return the complete log level name in uppercase
86
- # def level
87
- # "#{color}log.level.upcase#{color_map.clear}"
88
- # end
89
- # end
90
- #
91
- # # In application.rb:
92
- # config.rails_semantic_logger.format = MyFormatter.new
93
- config.rails_semantic_logger.format = :default
94
-
95
- # DEPRECATED
96
- # Instead, supply a Hash to config.log_tags
97
- config.rails_semantic_logger.named_tags = nil
98
-
99
- # Add a filter to the file logger [Regexp|Proc]
100
- # RegExp: Only include log messages where the class name matches the supplied
101
- # regular expression. All other messages will be ignored.
102
- # Proc: Only include log messages where the supplied Proc returns true.
103
- # The Proc must return true or false.
104
- config.rails_semantic_logger.filter = nil
22
+ config.rails_semantic_logger = RailsSemanticLogger::Options.new
105
23
 
106
24
  # Initialize SemanticLogger. In a Rails environment it will automatically
107
25
  # insert itself above the configured rails logger to add support for its
@@ -111,153 +29,230 @@ module RailsSemanticLogger
111
29
  Rails::Application::Bootstrap.initializers.delete_if { |i| i.name == :initialize_logger }
112
30
 
113
31
  initializer :initialize_logger, group: :all do
114
- config = Rails.application.config
32
+ config = Rails.application.config
115
33
 
116
34
  # Set the default log level based on the Rails config
117
35
  SemanticLogger.default_level = config.log_level
118
36
 
37
+ if defined?(Rails::Rack::Logger) && config.rails_semantic_logger.semantic
38
+ config.middleware.swap(Rails::Rack::Logger, RailsSemanticLogger::Rack::Logger, config.log_tags)
39
+ end
40
+
119
41
  # Existing loggers are ignored because servers like trinidad supply their
120
42
  # own file loggers which would result in duplicate logging to the same log file
121
- Rails.logger = config.logger = begin
122
- if config.rails_semantic_logger.add_file_appender
123
- path = config.paths['log'].first
124
- FileUtils.mkdir_p(File.dirname(path)) unless File.exist?(File.dirname(path))
125
-
126
- # Add the log file to the list of appenders
127
- # Use the colorized formatter if Rails colorized logs are enabled
128
- ap_options = config.rails_semantic_logger.ap_options
129
- formatter = config.rails_semantic_logger.format
130
- formatter = {color: {ap: ap_options}} if (formatter == :default) && (config.colorize_logging != false)
131
-
132
- # Set internal logger to log to file only, in case another appender experiences errors during writes
133
- appender = SemanticLogger::Appender::File.new(file_name: path, level: config.log_level, formatter: formatter)
134
- appender.name = 'SemanticLogger'
135
- SemanticLogger::Processor.logger = appender
136
-
137
- # Check for previous file or stdout loggers
138
- if SemanticLogger::VERSION.to_f >= 4.2
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) }
43
+ Rails.logger = config.logger =
44
+ begin
45
+ if config.rails_semantic_logger.add_file_appender
46
+ path = config.paths["log"].first
47
+ FileUtils.mkdir_p(File.dirname(path)) unless File.exist?(File.dirname(path))
48
+
49
+ # Add the log file to the list of appenders
50
+ # Use the colorized formatter if Rails colorized logs are enabled
51
+ ap_options = config.rails_semantic_logger.ap_options
52
+ formatter = config.rails_semantic_logger.format
53
+ formatter = {color: {ap: ap_options}} if (formatter == :default) && (config.colorize_logging != false)
54
+
55
+ # Set internal logger to log to file only, in case another appender experiences errors during writes
56
+ appender = SemanticLogger::Appender::File.new(path, formatter: formatter)
57
+ appender.name = "SemanticLogger"
58
+ SemanticLogger::Processor.logger = appender
59
+
60
+ # Check for previous file or stdout loggers
61
+ SemanticLogger.appenders.each do |app|
62
+ next unless app.is_a?(SemanticLogger::Appender::File) || app.is_a?(SemanticLogger::Appender::IO)
63
+
64
+ app.formatter = formatter
65
+ end
66
+ SemanticLogger.add_appender(file_name: path, formatter: formatter, filter: config.rails_semantic_logger.filter)
142
67
  end
143
- SemanticLogger.add_appender(file_name: path, formatter: formatter, filter: config.rails_semantic_logger.filter)
144
- end
145
68
 
146
- SemanticLogger[Rails]
147
- rescue StandardError => exc
148
- # If not able to log to file, log to standard error with warning level only
149
- SemanticLogger.default_level = :warn
150
-
151
- SemanticLogger::Processor.logger = SemanticLogger::Appender::File.new(io: STDERR)
152
- SemanticLogger.add_appender(io: STDERR)
153
-
154
- logger = SemanticLogger[Rails]
155
- logger.warn(
156
- "Rails Error: Unable to access log file. Please ensure that #{path} exists and is chmod 0666. " +
157
- "The log level has been raised to WARN and the output directed to STDERR until the problem is fixed.",
158
- exc
159
- )
160
- logger
161
- end
69
+ SemanticLogger[Rails]
70
+ rescue StandardError => e
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::IO.new($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
+ e
82
+ )
83
+ logger
84
+ end
162
85
 
163
86
  # Replace Rails loggers
164
- [:active_record, :action_controller, :action_mailer, :action_view].each do |name|
87
+ %i[active_record action_controller action_mailer action_view].each do |name|
165
88
  ActiveSupport.on_load(name) { include SemanticLogger::Loggable }
166
89
  end
167
- ActiveSupport.on_load(:action_cable) { self.logger = SemanticLogger['ActionCable'] }
90
+ ActiveSupport.on_load(:action_cable) { self.logger = SemanticLogger["ActionCable"] }
168
91
  end
169
92
 
170
- # Support fork frameworks
171
- config.after_initialize do
172
- # Silence asset logging by applying a filter to the Rails logger itself, not any of the appenders.
173
- if config.rails_semantic_logger.quiet_assets && config.assets.prefix #&& defined?(Rails::Rack::Logger)
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
93
+ # Before any initializers run, but after the gems have been loaded
94
+ config.before_initialize do
95
+ if config.respond_to?(:assets) && defined?(Rails::Rack::Logger) && config.rails_semantic_logger.semantic
96
+ config.rails_semantic_logger.quiet_assets = true if config.assets.quiet
195
97
 
196
- # Re-open appenders after Spring has forked a process
197
- if defined?(Spring)
198
- Spring.after_fork { |job| ::SemanticLogger.reopen }
98
+ # Otherwise Sprockets can't find the Rails::Rack::Logger middleware
99
+ config.assets.quiet = false
199
100
  end
200
- end
201
101
 
202
- # Before any initializers run, but after the gems have been loaded
203
- config.before_initialize do
204
102
  # Replace the Mongo Loggers
205
- Mongoid.logger = SemanticLogger[Mongoid] if defined?(Mongoid)
206
- Moped.logger = SemanticLogger[Moped] if defined?(Moped)
207
- Mongo::Logger.logger = SemanticLogger[Mongo] if defined?(Mongo::Logger)
103
+ Mongoid.logger = SemanticLogger[Mongoid] if defined?(Mongoid)
104
+ Moped.logger = SemanticLogger[Moped] if defined?(Moped)
105
+ Mongo::Logger.logger = SemanticLogger[Mongo] if defined?(Mongo::Logger)
208
106
 
209
107
  # Replace the Resque Logger
210
- Resque.logger = SemanticLogger[Resque] if defined?(Resque) && Resque.respond_to?(:logger)
108
+ Resque.logger = SemanticLogger[Resque] if defined?(Resque) && Resque.respond_to?(:logger=)
211
109
 
212
110
  # Replace the Sidekiq logger
213
- Sidekiq::Logging.logger = SemanticLogger[Sidekiq] if defined?(Sidekiq)
111
+ if defined?(Sidekiq)
112
+ if Sidekiq.respond_to?(:logger=)
113
+ Sidekiq.logger = SemanticLogger[Sidekiq]
114
+ elsif Sidekiq::VERSION[0..1] == '7.'
115
+ method = Sidekiq.server? ? :configure_server : :configure_client
116
+ Sidekiq.public_send(method) { |cfg| cfg.logger = SemanticLogger[Sidekiq] }
117
+ end
118
+ end
214
119
 
215
120
  # Replace the Sidetiq logger
216
- Sidetiq.logger = SemanticLogger[Sidetiq] if defined?(Sidetiq)
121
+ Sidetiq.logger = SemanticLogger[Sidetiq] if defined?(Sidetiq) && Sidetiq.respond_to?(:logger=)
122
+
123
+ # Replace the DelayedJob logger
124
+ if defined?(Delayed::Worker)
125
+ Delayed::Worker.logger = SemanticLogger[Delayed::Worker]
126
+ Delayed::Worker.plugins << RailsSemanticLogger::DelayedJob::Plugin
127
+ end
217
128
 
218
129
  # Replace the Bugsnag logger
219
130
  Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] } if defined?(Bugsnag)
220
131
 
221
- # Set the logger for concurrent-ruby
222
- Concurrent.global_logger = SemanticLogger[Concurrent] if defined?(Concurrent)
132
+ # Set the IOStreams PGP logger
133
+ IOStreams::Pgp.logger = SemanticLogger["IOStreams::Pgp"] if defined?(IOStreams)
134
+ end
135
+
136
+ # After any initializers run, but after the gems have been loaded
137
+ config.after_initialize do
138
+ config = Rails.application.config
139
+
140
+ # Replace the Bugsnag logger
141
+ Bugsnag.configure { |bugsnag_config| bugsnag_config.logger = SemanticLogger[Bugsnag] } if defined?(Bugsnag)
223
142
 
224
143
  # Rails Patches
225
- require('rails_semantic_logger/extensions/action_cable/tagged_logger_proxy') if defined?(ActionCable)
226
- require('rails_semantic_logger/extensions/action_controller/live') if defined?(ActionController::Live)
227
- require('rails_semantic_logger/extensions/action_dispatch/debug_exceptions') if defined?(ActionDispatch::DebugExceptions)
228
- require('rails_semantic_logger/extensions/action_view/streaming_template_renderer') if defined?(ActionView::StreamingTemplateRenderer::Body)
229
- require('rails_semantic_logger/extensions/active_job/logging') if defined?(ActiveJob)
230
- require('rails_semantic_logger/extensions/active_model_serializers/logging') if defined?(ActiveModelSerializers)
144
+ require("rails_semantic_logger/extensions/action_cable/tagged_logger_proxy") if defined?(::ActionCable)
145
+ require("rails_semantic_logger/extensions/action_controller/live") if defined?(::ActionController::Live)
146
+ require("rails_semantic_logger/extensions/action_dispatch/debug_exceptions") if defined?(::ActionDispatch::DebugExceptions)
147
+ if defined?(::ActionView::StreamingTemplateRenderer::Body)
148
+ require("rails_semantic_logger/extensions/action_view/streaming_template_renderer")
149
+ end
150
+ require("rails_semantic_logger/extensions/active_job/logging") if defined?(::ActiveJob)
151
+ require("rails_semantic_logger/extensions/active_model_serializers/logging") if defined?(::ActiveModelSerializers)
231
152
 
232
153
  if config.rails_semantic_logger.semantic
233
- require('rails_semantic_logger/extensions/rails/rack/logger') if defined?(Rails::Rack::Logger)
234
- require('rails_semantic_logger/extensions/action_controller/log_subscriber') if defined?(ActionController)
235
- require('rails_semantic_logger/extensions/active_record/log_subscriber') if defined?(ActiveRecord::LogSubscriber)
236
- end
154
+ # Active Job
155
+ if defined?(::ActiveJob) && defined?(::ActiveJob::Logging::LogSubscriber)
156
+ RailsSemanticLogger.swap_subscriber(
157
+ ::ActiveJob::Logging::LogSubscriber,
158
+ RailsSemanticLogger::ActiveJob::LogSubscriber,
159
+ :active_job
160
+ )
161
+ end
237
162
 
238
- unless config.rails_semantic_logger.started
239
- require('rails_semantic_logger/extensions/rails/rack/logger_info_as_debug') if defined?(Rails::Rack::Logger)
240
- end
163
+ if defined?(::ActiveJob) && defined?(::ActiveJob::LogSubscriber)
164
+ RailsSemanticLogger.swap_subscriber(
165
+ ::ActiveJob::LogSubscriber,
166
+ RailsSemanticLogger::ActiveJob::LogSubscriber,
167
+ :active_job
168
+ )
169
+ end
241
170
 
242
- unless config.rails_semantic_logger.rendered
243
- require('rails_semantic_logger/extensions/action_view/log_subscriber') if defined?(ActionView::LogSubscriber)
244
- end
171
+ # Active Record
172
+ if defined?(::ActiveRecord)
173
+ require "active_record/log_subscriber"
174
+
175
+ RailsSemanticLogger.swap_subscriber(
176
+ ::ActiveRecord::LogSubscriber,
177
+ RailsSemanticLogger::ActiveRecord::LogSubscriber,
178
+ :active_record
179
+ )
180
+ end
181
+
182
+ # Rack
183
+ RailsSemanticLogger::Rack::Logger.started_request_log_level = :info if config.rails_semantic_logger.started
184
+
185
+ # Silence asset logging by applying a filter to the Rails logger itself, not any of the appenders.
186
+ if config.rails_semantic_logger.quiet_assets && config.assets.prefix
187
+ assets_root = config.relative_url_root.to_s + config.assets.prefix
188
+ assets_regex = %r(\A/{0,2}#{assets_root})
189
+ RailsSemanticLogger::Rack::Logger.logger.filter = ->(log) { log.payload[:path] !~ assets_regex if log.payload }
190
+ end
191
+
192
+ # Action View
193
+ if defined?(::ActionView)
194
+ require "action_view/log_subscriber"
195
+
196
+ RailsSemanticLogger::ActionView::LogSubscriber.rendered_log_level = :info if config.rails_semantic_logger.rendered
197
+ RailsSemanticLogger.swap_subscriber(
198
+ ::ActionView::LogSubscriber,
199
+ RailsSemanticLogger::ActionView::LogSubscriber,
200
+ :action_view
201
+ )
202
+ end
245
203
 
246
- if config.rails_semantic_logger.processing
247
- require('rails_semantic_logger/extensions/action_controller/log_subscriber_processing') if defined?(ActionView::LogSubscriber)
204
+ # Action Controller
205
+ if defined?(::ActionController)
206
+ require "action_controller/log_subscriber"
207
+
208
+ RailsSemanticLogger.swap_subscriber(
209
+ ::ActionController::LogSubscriber,
210
+ RailsSemanticLogger::ActionController::LogSubscriber,
211
+ :action_controller
212
+ )
213
+ end
214
+
215
+ # Action Mailer
216
+ if defined?(::ActionMailer)
217
+ require "action_mailer/log_subscriber"
218
+
219
+ RailsSemanticLogger.swap_subscriber(
220
+ ::ActionMailer::LogSubscriber,
221
+ RailsSemanticLogger::ActionMailer::LogSubscriber,
222
+ :action_mailer
223
+ )
224
+ end
248
225
  end
249
226
 
250
- # Backward compatibility
251
- if config.rails_semantic_logger.named_tags
252
- config.log_tags = config.rails_semantic_logger.named_tags
227
+ #
228
+ # Forking Frameworks
229
+ #
230
+
231
+ # Passenger provides the :starting_worker_process event for executing
232
+ # code after it has forked, so we use that and reconnect immediately.
233
+ if defined?(PhusionPassenger)
234
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
235
+ SemanticLogger.reopen if forked
236
+ end
253
237
  end
254
- end
255
238
 
256
- # After any initializers run, but after the gems have been loaded
257
- config.after_initialize do
258
- # Replace the Bugsnag logger
259
- Bugsnag.configure { |config| config.logger = SemanticLogger[Bugsnag] } if defined?(Bugsnag)
260
- end
239
+ # Re-open appenders after Resque has forked a worker
240
+ Resque.after_fork { |_job| ::SemanticLogger.reopen } if defined?(Resque)
261
241
 
242
+ # Re-open appenders after Spring has forked a process
243
+ Spring.after_fork { |_job| ::SemanticLogger.reopen } if defined?(Spring.after_fork)
244
+
245
+ console do |_app|
246
+ # Don't use a background thread for logging
247
+ SemanticLogger.sync!
248
+ # Add a stderr logger when running inside a Rails console unless one has already been added.
249
+ if config.rails_semantic_logger.console_logger && !SemanticLogger.appenders.console_output?
250
+ SemanticLogger.add_appender(io: STDERR, formatter: :color)
251
+ end
252
+
253
+ # Include method names on log entries in the console
254
+ SemanticLogger.backtrace_level = SemanticLogger.default_level
255
+ end
256
+ end
262
257
  end
263
258
  end
@@ -1,4 +1,4 @@
1
- ActionCable::Connection::TaggedLoggerProxy
1
+ require "action_cable/connection/tagged_logger_proxy"
2
2
 
3
3
  module ActionCable
4
4
  module Connection