CodexBloom - Programming Q&A Platform

Trouble with ActiveSupport::Notifications and Custom Metrics in Rails 7.1

πŸ‘€ Views: 87 πŸ’¬ Answers: 1 πŸ“… Created: 2025-08-30
rails activesupport performance Ruby

Hey everyone, I'm running into an issue that's driving me crazy..... I'm trying to implement custom metrics in my Rails 7.1 application using `ActiveSupport::Notifications`, but I'm facing some unexpected behavior. I set up a subscriber to listen for `process_action.action_controller` events, but the metrics I'm collecting seem inaccurate and sometimes even duplicate. Here's the code I used to define the subscriber: ```ruby # app/initializers/metrics_subscriber.rb ActiveSupport::Notifications.subscribe('process_action.action_controller') do |name, start, finish, id, payload| duration = (finish - start) * 1000 # Convert to milliseconds Rails.logger.info "#{payload[:controller]}##{payload[:action]} took #{duration}ms" # Here I'm simulating metric collection MyMetricsCollector.record(payload[:controller], payload[:action], duration) end ``` I've also implemented a simple method to record metrics, but it seems to trigger multiple times for the same request, especially when there are redirects involved. For example, when I test a controller action that redirects, I'm seeing this log output multiple times: ``` Controller#action took 150ms Controller#action took 150ms Controller#action took 150ms ``` I've tried adding a condition to filter out duplicate notifications, like checking the `id` parameter, but that doesn't seem to work as expected. Here’s how I attempted that: ```ruby ActiveSupport::Notifications.subscribe('process_action.action_controller') do |name, start, finish, id, payload| next if @last_id == id # Check for duplicates @last_id = id duration = (finish - start) * 1000 MyMetricsCollector.record(payload[:controller], payload[:action], duration) end ``` However, this still gives me multiple logs when I make an action that causes redirects. I’m not sure if I’m misunderstanding how notifications work or if there's something else at play. Any insights or solutions to ensure I'm only capturing metrics for the final action of a request would be appreciated. For context: I'm using Ruby on Ubuntu. Thanks in advance! My team is using Ruby for this application.