From 01e577c3cb21d3ec3710aeb4cc6409b19d2729b7 Mon Sep 17 00:00:00 2001 From: Jack Rothrock Date: Thu, 5 Sep 2024 17:25:39 -0600 Subject: [PATCH] Handle Rails logger setting --- lib/scout_apm/logging/loggers/capture.rb | 9 +++++---- .../logging/loggers/patches/rails_logger.rb | 17 +++++++++++++++++ lib/scout_apm/logging/loggers/proxy.rb | 9 ++++++++- lib/scout_apm_logging.rb | 2 +- 4 files changed, 31 insertions(+), 6 deletions(-) create mode 100644 lib/scout_apm/logging/loggers/patches/rails_logger.rb diff --git a/lib/scout_apm/logging/loggers/capture.rb b/lib/scout_apm/logging/loggers/capture.rb index 370239c..29448f9 100644 --- a/lib/scout_apm/logging/loggers/capture.rb +++ b/lib/scout_apm/logging/loggers/capture.rb @@ -42,10 +42,11 @@ 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) @@ -53,9 +54,9 @@ def add_logging_patches! # 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 diff --git a/lib/scout_apm/logging/loggers/patches/rails_logger.rb b/lib/scout_apm/logging/loggers/patches/rails_logger.rb new file mode 100644 index 0000000..b67eb3d --- /dev/null +++ b/lib/scout_apm/logging/loggers/patches/rails_logger.rb @@ -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 diff --git a/lib/scout_apm/logging/loggers/proxy.rb b/lib/scout_apm/logging/loggers/proxy.rb index 4eae8c3..f561085 100644 --- a/lib/scout_apm/logging/loggers/proxy.rb +++ b/lib/scout_apm/logging/loggers/proxy.rb @@ -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 diff --git a/lib/scout_apm_logging.rb b/lib/scout_apm_logging.rb index b46fb9e..029d24d 100644 --- a/lib/scout_apm_logging.rb +++ b/lib/scout_apm_logging.rb @@ -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!