diff --git a/.changesets/fix-issue-with-logger-not-supporting-a-formatter.md b/.changesets/fix-issue-with-logger-not-supporting-a-formatter.md new file mode 100644 index 000000000..465372f81 --- /dev/null +++ b/.changesets/fix-issue-with-logger-not-supporting-a-formatter.md @@ -0,0 +1,6 @@ +--- +bump: patch +type: fix +--- + +Fix an issue with loggers not supporting a formatter on Rails boot. This will prevent the AppSignal logger config from running into an error if the logger configuration is added to `config/application.rb` or one of the environments in `config/environments/`. diff --git a/lib/appsignal/logger.rb b/lib/appsignal/logger.rb index 258eb1dde..b0857312d 100644 --- a/lib/appsignal/logger.rb +++ b/lib/appsignal/logger.rb @@ -93,7 +93,9 @@ def initialize(group, level: INFO, format: AUTODETECT, attributes: {}) # @return [Proc] def formatter=(formatter) super - @loggers.each { |logger| logger.formatter = formatter } + @loggers.each do |logger| + logger.formatter = formatter if logger.respond_to?(:formatter=) + end end # We support the various methods in the Ruby diff --git a/spec/lib/appsignal/logger_spec.rb b/spec/lib/appsignal/logger_spec.rb index cc2b9163f..21da245b4 100644 --- a/spec/lib/appsignal/logger_spec.rb +++ b/spec/lib/appsignal/logger_spec.rb @@ -449,6 +449,40 @@ expect(other_device.string).to eq("") end + context "with a formatter" do + it "sets the formatter on broadcasted loggers that support it" do + other_device = StringIO.new + other_logger = ::Logger.new(other_device) + + logger.broadcast_to(other_logger) + + formatter = proc do |_level, _timestamp, _appname, message| + "custom: #{message}" + end + + logger.formatter = formatter + + expect(logger.formatter).to eq(formatter) + expect(other_logger.formatter).to eq(formatter) + end + + it "does not raise an error when a broadcasted logger does not support formatter=" do + logger_without_formatter = double("logger without formatter") + allow(logger_without_formatter).to receive(:respond_to?).with(:formatter=).and_return(false) + allow(logger_without_formatter).to receive(:add) + + logger.broadcast_to(logger_without_formatter) + + formatter = proc do |_level, _timestamp, _appname, message| + "custom: #{message}" + end + + # Does not raise an error + logger.formatter = formatter + expect(logger.formatter).to eq(formatter) + end + end + if DependencyHelper.rails_present? describe "wrapped in ActiveSupport::TaggedLogging" do let(:other_stream) { StringIO.new }