From 0ff821afd1bf0dd683196d236759462183d0b70f Mon Sep 17 00:00:00 2001 From: Peter Solnica Date: Fri, 19 Sep 2025 14:09:12 +0000 Subject: [PATCH 1/2] Respect log_level --- .../spec/isolated/rails_logger_patch_spec.rb | 96 ++++++++++++++++++- sentry-ruby/lib/sentry/std_lib_logger.rb | 3 + .../spec/isolated/std_lib_logger_spec.rb | 70 ++++++++++++++ 3 files changed, 164 insertions(+), 5 deletions(-) diff --git a/sentry-rails/spec/isolated/rails_logger_patch_spec.rb b/sentry-rails/spec/isolated/rails_logger_patch_spec.rb index 00b9bb5a3..97a2cbc28 100644 --- a/sentry-rails/spec/isolated/rails_logger_patch_spec.rb +++ b/sentry-rails/spec/isolated/rails_logger_patch_spec.rb @@ -15,20 +15,23 @@ RSpec.describe "Rails.logger with :logger patch" do include Sentry::TestHelper - # Set up a real Rails app with logger - let(:log_output) { StringIO.new } - let(:app) do - make_basic_app do |config| + let!(:app) do + make_basic_app do |config, app| config.enable_logs = true config.enabled_patches = [:logger] config.max_log_events = 10 config.sdk_logger = Logger.new(nil) + + app.config.log_level = log_level end end + let(:log_level) { ::Logger::DEBUG } + let(:log_output) { StringIO.new } + before do - app Rails.logger = Logger.new(log_output) + Rails.logger.level = log_level end context "when :logger patch is enabled" do @@ -115,6 +118,89 @@ log_messages = sentry_logs.map { |log| log[:body] } expect(log_messages).to include("12345") end + + context "when Rails logger level is configured to warn" do + let(:log_level) { ::Logger::WARN } + + it "does not send debug logs to Sentry when Rails logger level is warn" do + expect { + Rails.logger.debug("Debug message should not be sent") + }.not_to output.to_stdout + + Sentry.get_current_client.log_event_buffer.flush + + log_messages = sentry_logs.map { |log| log[:body] } + expect(log_messages).not_to include("Debug message should not be sent") + end + + it "does not send info logs to Sentry when Rails logger level is warn" do + expect { + Rails.logger.info("Info message should not be sent") + }.not_to output.to_stdout + + Sentry.get_current_client.log_event_buffer.flush + + log_messages = sentry_logs.map { |log| log[:body] } + expect(log_messages).not_to include("Info message should not be sent") + end + + it "sends warn logs to Sentry when Rails logger level is warn" do + Rails.logger.warn("Warn message should be sent") + + Sentry.get_current_client.log_event_buffer.flush + + expect(sentry_logs).not_to be_empty + + log_messages = sentry_logs.map { |log| log[:body] } + expect(log_messages).to include("Warn message should be sent") + + warn_log = sentry_logs.find { |log| log[:body] == "Warn message should be sent" } + expect(warn_log[:level]).to eq("warn") + end + + it "sends error logs to Sentry when Rails logger level is warn" do + Rails.logger.error("Error message should be sent") + + Sentry.get_current_client.log_event_buffer.flush + + expect(sentry_logs).not_to be_empty + + log_messages = sentry_logs.map { |log| log[:body] } + expect(log_messages).to include("Error message should be sent") + + error_log = sentry_logs.find { |log| log[:body] == "Error message should be sent" } + expect(error_log[:level]).to eq("error") + end + end + + context "when Rails logger level is configured to error" do + let(:log_level) { ::Logger::ERROR } + + it "does not send warn logs to Sentry when Rails logger level is error" do + expect { + Rails.logger.warn("Warn message should not be sent") + }.not_to output.to_stdout + + Sentry.get_current_client.log_event_buffer.flush + + log_messages = sentry_logs.map { |log| log[:body] } + expect(log_messages).not_to include("Warn message should not be sent") + end + + it "sends error logs to Sentry when Rails logger level is error" do + Rails.logger.error("Error message should be sent") + + Sentry.get_current_client.log_event_buffer.flush + + expect(sentry_logs).not_to be_empty + + log_messages = sentry_logs.map { |log| log[:body] } + expect(log_messages).to include("Error message should be sent") + + error_log = sentry_logs.find { |log| log[:body] == "Error message should be sent" } + expect(error_log[:level]).to eq("error") + end + end end context "when Rails.logger is a BroadcastLogger", skip: !defined?(ActiveSupport::BroadcastLogger) do diff --git a/sentry-ruby/lib/sentry/std_lib_logger.rb b/sentry-ruby/lib/sentry/std_lib_logger.rb index b851e9763..ba4e3f71f 100644 --- a/sentry-ruby/lib/sentry/std_lib_logger.rb +++ b/sentry-ruby/lib/sentry/std_lib_logger.rb @@ -17,6 +17,9 @@ def add(severity, message = nil, progname = nil, &block) return unless Sentry.initialized? && Sentry.get_current_hub + # Only process logs that meet or exceed the logger's level + return result if severity < level + # exclude sentry SDK logs -- to prevent recursive log action, # do not process internal logs again if message.nil? && progname != Sentry::Logger::PROGNAME diff --git a/sentry-ruby/spec/isolated/std_lib_logger_spec.rb b/sentry-ruby/spec/isolated/std_lib_logger_spec.rb index 9d07d60d7..700657a65 100644 --- a/sentry-ruby/spec/isolated/std_lib_logger_spec.rb +++ b/sentry-ruby/spec/isolated/std_lib_logger_spec.rb @@ -60,5 +60,75 @@ end end end + + context "when logger level is set to warn" do + before do + logger.level = ::Logger::WARN + end + + it "should not send debug logs to Sentry when logger level is warn" do + expect { + logger.debug("Debug message") + }.to_not output.to_stdout + + expect(sentry_logs).to be_empty + end + + it "should not send info logs to Sentry when logger level is warn" do + expect { + logger.info("Info message") + }.to_not output.to_stdout + + expect(sentry_logs).to be_empty + end + + it "should send warn logs to Sentry when logger level is warn" do + logger.warn("Warn message") + + expect(sentry_logs).to_not be_empty + log_event = sentry_logs.last + expect(log_event[:level]).to eql("warn") + expect(log_event[:body]).to eql("Warn message") + end + + it "should send error logs to Sentry when logger level is warn" do + logger.error("Error message") + + expect(sentry_logs).to_not be_empty + log_event = sentry_logs.last + expect(log_event[:level]).to eql("error") + expect(log_event[:body]).to eql("Error message") + end + end + + context "when logger level is set to error" do + before do + logger.level = ::Logger::ERROR + end + + it "should not send warn logs to Sentry when logger level is error" do + logger.warn("Warn message") + + expect(sentry_logs).to be_empty + end + + it "should send error logs to Sentry when logger level is error" do + logger.error("Error message") + + expect(sentry_logs).to_not be_empty + log_event = sentry_logs.last + expect(log_event[:level]).to eql("error") + expect(log_event[:body]).to eql("Error message") + end + + it "should send fatal logs to Sentry when logger level is error" do + logger.fatal("Fatal message") + + expect(sentry_logs).to_not be_empty + log_event = sentry_logs.last + expect(log_event[:level]).to eql("fatal") + expect(log_event[:body]).to eql("Fatal message") + end + end end end From 776ffac36899e2f0d637970ec8247c23935b451c Mon Sep 17 00:00:00 2001 From: Peter Solnica Date: Fri, 19 Sep 2025 14:32:03 +0000 Subject: [PATCH 2/2] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b344c13dd..b71c760af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ### Bug Fixes - Skip including `sentry.message.template` in the log event attributes if there are no interpolation parameters provided ([#2700](https://github.com/getsentry/sentry-ruby/pull/2700)) +- Respect `log_level` when logging via `:std_lib_logger` patch ([#2709](https://github.com/getsentry/sentry-ruby/pull/2709)) ## 5.27.0