How to listen to Rails events

Event handling is a important aspect of modern Rails applications. Understanding how to properly listen and respond to system events can significantly enhance your application's observability and maintainability. In this article, we'll explore the power of ActiveSupport::Notifications in Rails.

Understanding ActiveSupport::Notifications

ActiveSupport::Notifications provides a powerful instrumentation API that allows you to listen to various events occurring within your Rails application. This system is extensively used by Rails internally and can be leveraged for custom event handling.

Listening to Built-in Rails Events

Let's start with a common use case - monitoring Active Record transactions:

# somewhere in config/initializers/abcd.rb
ActiveSupport::Notifications.subscribe("transaction.active_record") do |event|
  outcome = event.payload[:outcome]
  connection = event.payload[:connection]
  Rails.logger.info "Connection: #{connection}"
  Rails.logger.info "Outcome: #{outcome}" # can be :commit, :rollback, :restart, or :incomplete
  TransactionRecorder.call(event) # your custom handler
end

This code snippet demonstrates how to subscribe to Active Record transaction events. The outcome can be :commit:rollback:restart, or :incomplete, providing valuable insights into your database operations.

Creating Custom Events

Beyond built-in events, you can create your own custom events:

# subscribe to event
ActiveSupport::Notifications.subscribe "user.created" do |event|
  puts "Listening events - user.created"
  p event.payload # => {:name=>"My name", :id=>123}
  puts "Duration: #{event.duration}" # Duration: 1501.18

  YourSpecialLoggerCatcher.call(event)
end

# emit
ActiveSupport::Notifications.instrument "user.created", { name: "My name", id: 123 } do |event|
  puts "Emit - user.created event"
  sleep 1.5
end

We are creating a listener for user.createdevent that can be handled differently (for example by your custom class YourSpeciaLoggerCatcher.call). Then we can use our emit code to send some data, which can be transferred by using payload property of event. This is how we can handle transferring data between them with ease.

Summary

ActiveSupport::Notifications provides a robust event system for Rails applications, enabling both system event monitoring and custom event handling. This powerful feature helps in building more observable and maintainable applications.

Happy eventing!