Skip to content

Conversation

solnic
Copy link
Collaborator

@solnic solnic commented Aug 27, 2025

Adds log subscribers for common Rails components.

Screenshots

Screenshot 2025-08-25 at 10 57 03 Screenshot 2025-08-25 at 10 56 58 Screenshot 2025-08-25 at 10 56 51

Closes #2605

@solnic solnic force-pushed the 2605-rails-active-support-log-subscribers branch 4 times, most recently from e2de725 to 10b1acd Compare August 27, 2025 11:07
@solnic solnic force-pushed the 2605-rails-active-support-log-subscribers branch 2 times, most recently from e9a1bb4 to 6a8cea8 Compare August 27, 2025 15:42
@solnic solnic force-pushed the 2605-rails-active-support-log-subscribers branch from 6a8cea8 to be03827 Compare August 27, 2025 15:49
Copy link

codecov bot commented Aug 27, 2025

Codecov Report

❌ Patch coverage is 93.09309% with 23 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.21%. Comparing base (337a4ca) to head (be03827).

Files with missing lines Patch % Lines
...ls/log_subscribers/action_controller_subscriber.rb 91.83% 4 Missing ⚠️
...try/rails/log_subscribers/active_job_subscriber.rb 92.72% 4 Missing ⚠️
.../rails/log_subscribers/active_record_subscriber.rb 93.84% 4 Missing ⚠️
sentry-ruby/lib/sentry/configuration.rb 50.00% 3 Missing ⚠️
sentry-rails/lib/sentry/rails/configuration.rb 86.66% 2 Missing ⚠️
...entry-rails/lib/sentry/rails/structured_logging.rb 88.88% 2 Missing ⚠️
sentry-ruby/lib/sentry/test_helper.rb 66.66% 2 Missing ⚠️
.../rails/log_subscribers/action_mailer_subscriber.rb 96.87% 1 Missing ⚠️
sentry-ruby/lib/sentry-ruby.rb 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2690      +/-   ##
==========================================
- Coverage   97.44%   97.21%   -0.23%     
==========================================
  Files         136      144       +8     
  Lines        5317     5645     +328     
==========================================
+ Hits         5181     5488     +307     
- Misses        136      157      +21     
Components Coverage Δ
sentry-ruby 97.70% <90.16%> (-0.07%) ⬇️
sentry-rails 95.42% <93.75%> (-0.69%) ⬇️
sentry-sidekiq 96.57% <ø> (ø)
sentry-resque 94.44% <ø> (ø)
sentry-delayed_job 94.68% <ø> (ø)
sentry-opentelemetry 99.31% <ø> (ø)
Files with missing lines Coverage Δ
sentry-rails/lib/sentry/rails.rb 100.00% <100.00%> (ø)
sentry-rails/lib/sentry/rails/log_subscriber.rb 100.00% <100.00%> (ø)
...b/sentry/rails/log_subscribers/parameter_filter.rb 100.00% <100.00%> (ø)
sentry-rails/lib/sentry/rails/railtie.rb 98.83% <100.00%> (+0.05%) ⬆️
sentry-ruby/lib/sentry/debug_structured_logger.rb 100.00% <100.00%> (ø)
.../rails/log_subscribers/action_mailer_subscriber.rb 96.87% <96.87%> (ø)
sentry-ruby/lib/sentry-ruby.rb 98.73% <75.00%> (-0.41%) ⬇️
sentry-rails/lib/sentry/rails/configuration.rb 96.55% <86.66%> (-3.45%) ⬇️
...entry-rails/lib/sentry/rails/structured_logging.rb 88.88% <88.88%> (ø)
sentry-ruby/lib/sentry/test_helper.rb 95.83% <66.66%> (-4.17%) ⬇️
... and 4 more

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@solnic solnic requested a review from sl0thentr0py August 27, 2025 18:28
@solnic solnic marked this pull request as ready for review August 27, 2025 18:31
Copy link
Member

@sl0thentr0py sl0thentr0py left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mainly left comments on

  • overhead
  • configuration api

some more high level feedback:
I would have much preferred this to be a simple proxy of just passing through to our logger whatever rails emits. Instead, now we have special loggers for each component. I will not block this if you are ok with maintaining all this extra code (I do not like maintaining a lot of code, my personal preference.)

Further, there is now a lot of duplication of logic between

  • breadcrumbs
  • logger
  • tracing

To reiterate from a business point of view, Logging is mainly a high volume trace connected feed of events, whereas Tracing is a much more curated instrumentation experience and they both have their place. The way this PR is makes Logging very similar to Performance.

@@ -2,6 +2,8 @@

module Sentry
module TestHelper
module_function
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sl0thentr0py makes it possible to call methods as class methods too, or include them as RSpec example helpers. Very handy IMO.

@@ -63,6 +62,14 @@ def teardown_sentry_test
Sentry::Scope.global_event_processors.clear
end

def clear_sentry_events
if Sentry.initialized? && Sentry.configuration.enable_logs
[Sentry.get_current_client.transport, Sentry.logger].each do |obj|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will only clear the transport if enable_logs is on

# File path for DebugStructuredLogger to log events to. If not set, defaults to a temporary file.
# This is useful for debugging and testing structured logging.
# @return [String, nil]
attr_accessor :sdk_debug_structured_logger_log_file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like that we are polluting the main configuration namespace with this debug stuff, would prefer they be passed as init arguments to DebugStructuredLogger.new and instead of structured_logger_class we just have structured_logger where you can pass in your own instance.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sl0thentr0py are you OK with cleaning that up in a separate PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes sure

EMPTY_HASH = {}.freeze

if ::Rails.version.to_f >= 6.0
def self.backend
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these do not need to be methods, just make a class variable

@@ -3,6 +3,8 @@
### Feature

- Propagated sampling rates as specified in [Traces](https://develop.sentry.dev/sdk/telemetry/traces/#propagated-random-value) docs ([#2671](https://github.com/getsentry/sentry-ruby/pull/2671))
- Support for Rails ActiveSupport log subscribers ([#2690](https://github.com/getsentry/sentry-ruby/pull/2690))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need a detailed changelog entry for how to use this stuff


def initialize
@enabled = false
@subscribers = {}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when enabled is set to true, we should populate a set of sane subscribers by default

end

if ::Rails.version.to_f >= 6.1
def extract_db_config_from_connection(connection)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging is supposed to be extremely low overhead because the volume is very high. If any of these branches are potentially expensive or incur an extra db connection, I would err on the side of leaving this data out in those cases instead of trying to be too smart to find it.

So basically, just take it simply if it exists otherwise let it not be there.

We already have a full fledged tracing product and if people want complete instrumentation, they are supposed to use Performance and not just Logging.

obj.clear if obj.respond_to?(:clear)
end
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Test Pollution: Sentry Transport Not Always Cleared

The clear_sentry_events method now clears the Sentry transport only when enable_logs is true. This can lead to test pollution, as the transport stores all captured events, not just logs, and should be cleared unconditionally during test teardown for proper isolation.

Fix in Cursor Fix in Web

File.readlines(log_file).map do |line|
JSON.parse(line)
end
end
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Log Initialization and Parsing Errors

The logged_events method can raise Errno::ENOENT if the log file hasn't been created yet, as initialize_log_file only makes the directory. It also risks JSON::ParserError if the log file contains invalid JSON, potentially causing crashes.

Fix in Cursor Fix in Web

# @param event [ActiveSupport::Notifications::Event] The controller action event
def process_action(event)
payload = event.payload
duration = event.time.round(2)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Incorrect Event Duration Calculation

The ActionControllerSubscriber uses event.time to calculate the event duration, but event.time is the event's start timestamp. This results in incorrect duration values being logged for process_action.action_controller events.

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for ActiveSupport instrumentation in Sentry::Logging
2 participants