Unlike the traditional Rails logger, which produces human-readable text lines, the new event system generates structured data that is easier to filter, analyse, and send to external observability tools.
If you've ever dug through Rails log files trying to understand what happened across a series of requests, background jobs, or third-party integrations, this feature is a welcome improvement. It brings Rails logging into a more modern era, with proper event objects, tagging, context, and subscriber hooks.
This post explains what the new Structured Event Reporter does, how to use it, and why it makes debugging and monitoring Rails applications far more pleasant.
If you've ever dug through Rails log files trying to understand what happened across a series of requests, background jobs, or third-party integrations, this feature is a welcome improvement. It brings Rails logging into a more modern era, with proper event objects, tagging, context, and subscriber hooks.
This post explains what the new Structured Event Reporter does, how to use it, and why it makes debugging and monitoring Rails applications far more pleasant.
Why Rails Needed Structured Event Reporting
Rails' classic logger is simple and familiar, great for development and terminal output. But plain text logs have limitations:
- filtering them reliably is difficult
- different parts of the app log differently
- you often need complex parsing to extract data
- logs become messy in production environments
The new Structured Event Reporter solves this by giving Rails a unified way to record meaningful events along with their payloads. Instead of dumping arbitrary strings into the log, you emit structured events that subscribers can handle consistently.
Rails isn’t replacing the old logger, it’s giving developers a way to log richer, machine-readable events alongside it.
Rails isn’t replacing the old logger, it’s giving developers a way to log richer, machine-readable events alongside it.
The New API: Rails.event.notify
At the core of the new system is the notify method:
Rails.event.notify("user.signup", user_id: 123, email: "[email protected]")This emits a structured event with:
- a name, such as "user.signup"
- a payload of key/value data
Instead of manually formatting strings, you let Rails package the event for whatever subscriber is listening.
You can think of it as the logging equivalent of ActiveSupport::Notifications, but simpler and designed specifically for structured log data.
Adding Tags with Rails.event.tagged
Sometimes you want to categorise your logs, for example, marking events related to GraphQL, billing, or a background job.
Rails makes this easy:
Rails.event.tagged("graphql") do
Rails.event.notify("user.signup", user_id: 123, email: "[email protected]")
endAll events inside the block will include:
{ graphql: true }This is perfect for filtering in downstream log tools or APM dashboards.
Adding Global Context with Rails.event.set_context
Another common need is attaching shared metadata to every event, such as the current request ID, shop/account ID, or job ID.
Rails now supports this directly:
Rails.event.set_context(request_id: "abc123", shop_id: 456)
Rails.event.notify("order.completed", order_id: 890)Every emitted event will include:
context: { request_id: "abc123", shop_id: 456 }This avoids repeating the same metadata in every single logging call. It’s especially useful in:
- request cycles
- background job execution
- multi-tenant apps
- API gateways
- debugging distributed systems
Example: Tracking a Checkout Flow
Here’s how you might use structured events in a real e-commerce flow:
Rails.event.tagged("checkout") do
Rails.event.set_context(request_id: request.request_id)
Rails.event.notify("checkout.started", items: cart.items.count)
payment = Payments::Charge.call(cart)
Rails.event.notify("checkout.payment_success", total: payment.total, transaction_id: payment.id)
endThis gives you:
- clean event names
- searchable metadata
- traceability across the request
- tagging for simple filtering
Perfect for diagnosing problems in production.
How It Fits Into Rails 8.1
This feature is available in Rails 8.1 and it doesn’t replace the classic Rails logger or ActiveSupport::Notifications, but sits neatly alongside them, giving developers a clearer way to express what’s happening inside the application.
If you're thinking of adopting this feature, now’s a perfect time to check out our Rails 8.1 upgrade guide, which walks through how to safely migrate, test, and deploy the update in your app.
If you're thinking of adopting this feature, now’s a perfect time to check out our Rails 8.1 upgrade guide, which walks through how to safely migrate, test, and deploy the update in your app.