Skip to content

Commit

Permalink
Handle Rails logger setting
Browse files Browse the repository at this point in the history
  • Loading branch information
jrothrock committed Sep 6, 2024
1 parent 56dd746 commit 01e577c
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
9 changes: 5 additions & 4 deletions lib/scout_apm/logging/loggers/capture.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,21 @@ def create_proxy_log_dir!
Utils.ensure_directory_exists(context.config.value('logs_proxy_log_dir'))
end

def add_logging_patches!
def add_logging_patches! # rubocop:disable Metrics/AbcSize
require_relative './patches/rails_logger' if ::Rails.gem_version < Gem::Version.new('7.1')
# We can't swap out the logger similar to that of Rails and Sidekiq, as
# the TaggedLogging logger is dynamically generated.
return unless Rails.logger.respond_to?(:tagged)
return unless ::Rails.logger.respond_to?(:tagged)

::ActiveSupport::TaggedLogging.prepend(Patches::TaggedLogging)

# Re-extend TaggedLogging to verify the patch is be applied.
# This appears to be an issue in Ruby 2.7 with the broadcast logger.
ruby_version = Gem::Version.new(RUBY_VERSION)
isruby27 = (ruby_version >= Gem::Version.new('2.7') && ruby_version < Gem::Version.new('3.0'))
return unless isruby27 && Rails.logger.respond_to?(:broadcasts)
return unless isruby27 && ::Rails.logger.respond_to?(:broadcasts)

Rails.logger.broadcasts.each do |logger|
::Rails.logger.broadcasts.each do |logger|
logger.extend ::ActiveSupport::TaggedLogging
end
end
Expand Down
17 changes: 17 additions & 0 deletions lib/scout_apm/logging/loggers/patches/rails_logger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

# A patch to Rails to allow swapping out the logger for the held logger in the proxy.
module Rails
class << self
def logger=(new_logger)
@logger.tap do |rails_logger|
if rails_logger.respond_to?(:is_scout_proxy_logger?)
old_logger = rails_logger.instance_variable_get(:@loggers).first
rails_logger.swap_scout_loggers!(old_logger, new_logger)
else
@logger = new_logger
end
end
end
end
end
9 changes: 8 additions & 1 deletion lib/scout_apm/logging/loggers/proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@ def add_scout_loggers(logger)
@loggers << logger
end

def remove_scout_loggers(logger)
def remove_scout_loggers!(logger)
@loggers.reject! { |inst_log| inst_log == logger }

@loggers
end

def swap_scout_loggers!(old_logger, new_logger)
logger_index = @loggers.index(old_logger)
return unless logger_index

@loggers[logger_index] = new_logger
end

# We don't want other libraries to change the formatter of the logger we create.
def formatter=(formatter)
@loggers.first.formatter = formatter
Expand Down
2 changes: 1 addition & 1 deletion lib/scout_apm_logging.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module Logging
if defined?(Rails) && defined?(Rails::Railtie)
# If we are in a Rails environment, setup the monitor daemon manager.
class RailTie < ::Rails::Railtie
initializer 'scout_apm_logging.monitor' do
initializer 'scout_apm_logging.monitor', after: :initialize_logger, before: :initialize_cache do
context = ScoutApm::Logging::MonitorManager.instance.context

Loggers::Capture.new(context).setup!
Expand Down

0 comments on commit 01e577c

Please sign in to comment.