diff --git a/CHANGELOG.md b/CHANGELOG.md index defe54f2b..69f0d1d41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## Unreleased +### Features + +- Auto-enable Rails structured logging when `enable_logs` is true ([#2721](https://github.com/getsentry/sentry-ruby/pull/2721)) + ### Internal - Fix leftover `config.logger` call in `graphql` patch ([#2722](https://github.com/getsentry/sentry-ruby/2722) diff --git a/sentry-rails/lib/sentry/rails/configuration.rb b/sentry-rails/lib/sentry/rails/configuration.rb index 70f975cf7..7b27a9152 100644 --- a/sentry-rails/lib/sentry/rails/configuration.rb +++ b/sentry-rails/lib/sentry/rails/configuration.rb @@ -13,7 +13,7 @@ module Sentry class Configuration attr_reader :rails - add_post_initialization_callback do + after(:initialize) do @rails = Sentry::Rails::Configuration.new @excluded_exceptions = @excluded_exceptions.concat(Sentry::Rails::IGNORE_DEFAULT) @@ -33,6 +33,10 @@ class Configuration end end end + + after(:configured) do + rails.structured_logging.enabled = enable_logs if rails.structured_logging.enabled.nil? + end end module Rails @@ -202,9 +206,15 @@ class StructuredLoggingConfiguration }.freeze def initialize - @enabled = false + @enabled = nil @subscribers = DEFAULT_SUBSCRIBERS.dup end + + # Returns true if structured logging should be enabled. + # @return [Boolean] + def enabled? + enabled + end end end end diff --git a/sentry-rails/lib/sentry/rails/railtie.rb b/sentry-rails/lib/sentry/rails/railtie.rb index 0691fa277..b514df3cd 100644 --- a/sentry-rails/lib/sentry/rails/railtie.rb +++ b/sentry-rails/lib/sentry/rails/railtie.rb @@ -140,7 +140,7 @@ def activate_tracing end def activate_structured_logging - if Sentry.configuration.rails.structured_logging.enabled && Sentry.configuration.enable_logs + if Sentry.configuration.rails.structured_logging.enabled? && Sentry.configuration.enable_logs Sentry::Rails::StructuredLogging.attach(Sentry.configuration.rails.structured_logging) end end diff --git a/sentry-rails/spec/sentry/rails/configuration_spec.rb b/sentry-rails/spec/sentry/rails/configuration_spec.rb index adf08a635..58b38353c 100644 --- a/sentry-rails/spec/sentry/rails/configuration_spec.rb +++ b/sentry-rails/spec/sentry/rails/configuration_spec.rb @@ -74,7 +74,7 @@ class MySubscriber; end config.rails.structured_logging.enabled = true end - expect(config.structured_logging.enabled).to be(true) + expect(config.structured_logging.enabled?).to be(true) expect(config.structured_logging.subscribers).to be_a(Hash) end @@ -83,10 +83,35 @@ class MySubscriber; end config.rails.structured_logging.enabled = false end - expect(config.structured_logging.enabled).to be(false) + expect(config.structured_logging.enabled?).to be(false) expect(config.structured_logging.subscribers).to be_a(Hash) end + it "auto-enables when enable_logs is true and not explicitly set" do + make_basic_app do |config| + config.enable_logs = true + end + + expect(config.structured_logging.enabled?).to be(true) + end + + it "remains disabled when enable_logs is false" do + make_basic_app do |config| + config.enable_logs = false + end + + expect(config.structured_logging.enabled?).to be(false) + end + + it "respects explicit disable even when enable_logs is true" do + make_basic_app do |config| + config.rails.structured_logging.enabled = false + config.enable_logs = true + end + + expect(config.structured_logging.enabled?).to be(false) + end + it "allows customizing subscribers" do class TestSubscriber; end diff --git a/sentry-rails/spec/sentry/rails/log_subscriber_spec.rb b/sentry-rails/spec/sentry/rails/log_subscriber_spec.rb index 94e095ec7..7b0844a09 100644 --- a/sentry-rails/spec/sentry/rails/log_subscriber_spec.rb +++ b/sentry-rails/spec/sentry/rails/log_subscriber_spec.rb @@ -45,6 +45,8 @@ def error_test_event(event) make_basic_app do |config| config.enable_logs = true config.structured_logging.logger_class = Sentry::DebugStructuredLogger + # Disable default structured logging subscribers to avoid interference + config.rails.structured_logging.enabled = false end end @@ -123,8 +125,8 @@ def error_test_event(event) duration = log_event["attributes"]["duration_ms"] expect(duration).to be_a(Float) - expect(duration).to be >= 40.0 - expect(duration).to be < 100.0 + expect(duration).to be >= 10.0 + expect(duration).to be < 200.0 expect(duration.round(2)).to eq(duration) end end diff --git a/sentry-rails/spec/sentry/rails/structured_logging_spec.rb b/sentry-rails/spec/sentry/rails/structured_logging_spec.rb index b414d86e0..0c7aae44e 100644 --- a/sentry-rails/spec/sentry/rails/structured_logging_spec.rb +++ b/sentry-rails/spec/sentry/rails/structured_logging_spec.rb @@ -40,4 +40,28 @@ expect(sentry_logs).to be_empty end end + + context "when enable_logs is true and structured logging is auto-enabled" do + before do + make_basic_app do |config| + config.enable_logs = true + end + end + + it "captures structured logs automatically" do + get "/posts" + + Post.first + + Sentry.get_current_client.flush + + expect(sentry_logs).not_to be_empty + + rails_log_events = sentry_logs.select { |log| + log.dig(:attributes, "sentry.origin", :value) == "auto.logger.rails.log_subscriber" + } + + expect(rails_log_events).not_to be_empty + end + end end