2018-07-23 22:29:31 -04:00
**DO NOT READ THIS FILE ON GITHUB, GUIDES ARE PUBLISHED ON https://guides.rubyonrails.org.**
2014-12-23 17:32:50 -05:00
2012-10-17 09:15:55 -04:00
Active Support Instrumentation
==============================
2018-05-08 22:48:07 -04:00
Active Support is a part of core Rails that provides Ruby language extensions, utilities, and other things. One of the things it includes is an instrumentation API that can be used inside an application to measure certain actions that occur within Ruby code, such as that inside a Rails application or the framework itself. It is not limited to Rails, however. It can be used independently in other Ruby scripts if it is so desired.
2012-10-17 09:15:55 -04:00
2012-11-29 17:25:02 -05:00
In this guide, you will learn how to use the instrumentation API inside of Active Support to measure events inside of Rails and other Ruby code.
After reading this guide, you will know:
2012-10-17 09:15:55 -04:00
2012-11-29 08:14:08 -05:00
* What instrumentation can provide.
2019-12-12 16:40:29 -05:00
* How to add a subscriber to a hook.
2012-11-29 08:14:08 -05:00
* The hooks inside the Rails framework for instrumentation.
2019-12-12 16:40:29 -05:00
* How to build a custom instrumentation implementation.
2012-10-17 09:15:55 -04:00
--------------------------------------------------------------------------------
Introduction to instrumentation
-------------------------------
2015-04-06 15:49:30 -04:00
The instrumentation API provided by Active Support allows developers to provide hooks which other developers may hook into. There are several of these within the [Rails framework ](#rails-framework-hooks ). With this API, developers can choose to be notified when certain events occur inside their application or another piece of Ruby code.
2012-10-17 09:15:55 -04:00
For example, there is a hook provided within Active Record that is called every time Active Record uses an SQL query on a database. This hook could be **subscribed** to, and used to track the number of queries during a certain action. There's another hook around the processing of an action of a controller. This could be used, for instance, to track how long a specific action has taken.
2019-12-12 16:40:29 -05:00
You are even able to [create your own events ](#creating-custom-events ) inside your application which you can later subscribe to.
Subscribing to an event
-----------------------
Subscribing to an event is easy. Use `ActiveSupport::Notifications.subscribe` with a block to
listen to any notification.
The block receives the following arguments:
* The name of the event
* Time when it started
* Time when it finished
* A unique ID for the instrumenter that fired the event
* The payload (described in future sections)
```ruby
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, started, finished, unique_id, data|
# your own custom stuff
Rails.logger.info "#{name} Received! (started: #{started}, finished: #{finished})" # process_action.action_controller Received (started: 2019-05-05 13:43:57 -0800, finished: 2019-05-05 13:43:58 -0800)
end
```
If you are concerned about the accuracy of `started` and `finished` to compute a precise elapsed time then use `ActiveSupport::Notifications.monotonic_subscribe` . The given block would receive the same arguments as above but the `started` and `finished` will have values with an accurate monotonic time instead of wall-clock time.
```ruby
ActiveSupport::Notifications.monotonic_subscribe "process_action.action_controller" do |name, started, finished, unique_id, data|
# your own custom stuff
Rails.logger.info "#{name} Received! (started: #{started}, finished: #{finished})" # process_action.action_controller Received (started: 1560978.425334, finished: 1560979.429234)
end
```
Defining all those block arguments each time can be tedious. You can easily create an `ActiveSupport::Notifications::Event`
from block arguments like this:
```ruby
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
event = ActiveSupport::Notifications::Event.new *args
event.name # => "process_action.action_controller"
event.duration # => 10 (in milliseconds)
event.payload # => {:extra=>information}
Rails.logger.info "#{event} Received!"
end
```
2020-09-30 14:54:04 -04:00
You may also pass a block that accepts only one argument, and it will receive an event object:
2019-12-12 16:40:29 -05:00
```ruby
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |event|
event.name # => "process_action.action_controller"
event.duration # => 10 (in milliseconds)
event.payload # => {:extra=>information}
Rails.logger.info "#{event} Received!"
end
```
Most times you only care about the data itself. Here is a shortcut to just get the data.
```ruby
ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
data = args.extract_options!
data # { extra: :information }
end
```
You may also subscribe to events matching a regular expression. This enables you to subscribe to
multiple events at once. Here's how to subscribe to everything from `ActionController` .
```ruby
ActiveSupport::Notifications.subscribe /action_controller/ do |*args|
# inspect all ActionController events
end
```
2012-10-17 09:15:55 -04:00
Rails framework hooks
---------------------
Within the Ruby on Rails framework, there are a number of hooks provided for common events. These are detailed below.
2021-07-27 10:38:16 -04:00
### Action Controller
2012-10-17 09:15:55 -04:00
2021-07-27 10:38:16 -04:00
#### write_fragment.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------ | ---------------- |
| `:key` | The complete key |
```ruby
{
2013-06-15 01:37:50 -04:00
key: 'posts/1-dashboard-view'
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### read_fragment.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------ | ---------------- |
| `:key` | The complete key |
```ruby
{
2013-06-15 01:37:50 -04:00
key: 'posts/1-dashboard-view'
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### expire_fragment.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------ | ---------------- |
| `:key` | The complete key |
```ruby
{
2013-06-15 01:37:50 -04:00
key: 'posts/1-dashboard-view'
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### exist_fragment?.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------ | ---------------- |
| `:key` | The complete key |
```ruby
{
2013-06-15 01:37:50 -04:00
key: 'posts/1-dashboard-view'
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### start_processing.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------------- | --------------------------------------------------------- |
| `:controller` | The controller name |
| `:action` | The action |
| `:params` | Hash of request parameters without any filtered parameter |
2016-03-12 19:36:45 -05:00
| `:headers` | Request headers |
2012-10-17 09:15:55 -04:00
| `:format` | html/js/json/xml etc |
| `:method` | HTTP request verb |
| `:path` | Request path |
```ruby
{
controller: "PostsController",
action: "new",
params: { "action" => "new", "controller" => "posts" },
2016-03-12 19:36:45 -05:00
headers: #< ActionDispatch::Http::Headers:0x0055a67a519b88 > ,
2012-10-17 09:15:55 -04:00
format: :html,
method: "GET",
path: "/posts/new"
}
```
2021-07-27 10:38:16 -04:00
#### process_action.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| --------------- | --------------------------------------------------------- |
| `:controller` | The controller name |
| `:action` | The action |
| `:params` | Hash of request parameters without any filtered parameter |
2016-03-12 19:36:45 -05:00
| `:headers` | Request headers |
2012-10-17 09:15:55 -04:00
| `:format` | html/js/json/xml etc |
| `:method` | HTTP request verb |
| `:path` | Request path |
2019-11-04 18:29:38 -05:00
| `:request` | The `ActionDispatch::Request` |
2021-09-06 09:31:32 -04:00
| `:response` | The `ActionDispatch::Response` |
2014-10-30 12:01:18 -04:00
| `:status` | HTTP status code |
2012-10-17 09:15:55 -04:00
| `:view_runtime` | Amount spent in view in ms |
2014-10-30 11:55:39 -04:00
| `:db_runtime` | Amount spent executing database queries in ms |
2012-10-17 09:15:55 -04:00
```ruby
{
controller: "PostsController",
action: "index",
params: {"action" => "index", "controller" => "posts"},
2016-03-12 19:36:45 -05:00
headers: #< ActionDispatch::Http::Headers:0x0055a67a519b88 > ,
2012-10-17 09:15:55 -04:00
format: :html,
method: "GET",
path: "/posts",
2019-11-04 18:29:38 -05:00
request: #< ActionDispatch::Request:0x00007ff1cb9bd7b8 > ,
2021-09-06 09:31:32 -04:00
response: #< ActionDispatch::Response:0x00007f8521841ec8 > ,
2012-10-17 09:15:55 -04:00
status: 200,
view_runtime: 46.848,
db_runtime: 0.157
}
```
2021-07-27 10:38:16 -04:00
#### send_file.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------- | ------------------------- |
| `:path` | Complete path to the file |
INFO. Additional keys may be added by the caller.
2021-07-27 10:38:16 -04:00
#### send_data.action_controller
2012-10-17 09:15:55 -04:00
2018-05-09 15:15:32 -04:00
`ActionController` does not add any specific information to the payload. All options are passed through to the payload.
2012-10-17 09:15:55 -04:00
2021-07-27 10:38:16 -04:00
#### redirect_to.action_controller
2012-10-17 09:15:55 -04:00
2019-11-22 15:06:46 -05:00
| Key | Value |
| ----------- | ----------------------------- |
| `:status` | HTTP response code |
| `:location` | URL to redirect to |
| `:request` | The `ActionDispatch::Request` |
2012-10-17 09:15:55 -04:00
```ruby
{
status: 302,
2019-11-22 15:06:46 -05:00
location: "http://localhost:3000/posts/new",
request: #< ActionDispatch::Request:0x00007ff1cb9bd7b8 >
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### halted_callback.action_controller
2012-10-17 09:15:55 -04:00
| Key | Value |
| --------- | ----------------------------- |
| `:filter` | Filter that halted the action |
```ruby
{
filter: ":halting_filter"
}
```
2021-07-27 10:38:16 -04:00
#### unpermitted_parameters.action_controller
2017-10-13 19:11:14 -04:00
2021-03-31 07:24:36 -04:00
| Key | Value |
| ------------- | --------------------------------------------------------------------- |
2021-06-17 06:29:48 -04:00
| `:keys` | The unpermitted keys |
2021-03-31 07:24:36 -04:00
| `:context` | Hash with the following keys: :controller, :action, :params, :request |
2017-10-13 19:11:14 -04:00
2021-07-27 10:38:16 -04:00
### Action Dispatch
2019-03-20 01:09:16 -04:00
2021-07-27 10:38:16 -04:00
#### process_middleware.action_dispatch
2019-03-20 01:09:16 -04:00
| Key | Value |
| ------------- | ---------------------- |
| `:middleware` | Name of the middleware |
2021-07-27 10:38:16 -04:00
### Action View
2012-10-17 09:15:55 -04:00
2021-07-27 10:38:16 -04:00
#### render_template.action_view
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------------- | --------------------- |
| `:identifier` | Full path to template |
| `:layout` | Applicable layout |
```ruby
{
identifier: "/Users/adam/projects/notifications/app/views/posts/index.html.erb",
layout: "layouts/application"
}
```
2021-07-27 10:38:16 -04:00
#### render_partial.action_view
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------------- | --------------------- |
| `:identifier` | Full path to template |
```ruby
{
2015-02-28 08:08:55 -05:00
identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### render_collection.action_view
2016-11-08 02:37:02 -05:00
2016-11-08 12:52:31 -05:00
| Key | Value |
| ------------- | ------------------------------------- |
| `:identifier` | Full path to template |
| `:count` | Size of collection |
| `:cache_hits` | Number of partials fetched from cache |
`:cache_hits` is only included if the collection is rendered with `cached: true` .
2016-11-08 02:37:02 -05:00
```ruby
{
identifier: "/Users/adam/projects/notifications/app/views/posts/_post.html.erb",
count: 3,
cache_hits: 0
}
```
2021-07-27 10:38:16 -04:00
### Active Record
2012-10-17 09:15:55 -04:00
2021-07-27 10:38:16 -04:00
#### sql.active_record
2012-10-17 09:15:55 -04:00
2018-12-14 07:55:30 -05:00
| Key | Value |
| -------------------- | ---------------------------------------- |
| `:sql` | SQL statement |
| `:name` | Name of the operation |
| `:connection` | Connection object |
| `:binds` | Bind parameters |
| `:type_casted_binds` | Typecasted bind parameters |
| `:statement_name` | SQL Statement name |
| `:cached` | `true` is added when cached queries used |
2012-10-17 09:15:55 -04:00
INFO. The adapters will add their own data as well.
```ruby
{
sql: "SELECT \"posts\".* FROM \"posts\" ",
name: "Post Load",
2018-12-14 07:55:30 -05:00
connection: #< ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x00007f9f7a838850 > ,
binds: [#< ActiveModel::Attribute::WithCastValue:0x00007fe19d15dc00 > ],
type_casted_binds: [11],
statement_name: nil
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### instantiation.active_record
2015-06-07 19:55:01 -04:00
| Key | Value |
| ---------------- | ----------------------------------------- |
| `:record_count` | Number of records that instantiated |
| `:class_name` | Record's class |
```ruby
{
record_count: 1,
class_name: "User"
}
```
2021-07-27 10:38:16 -04:00
### Action Mailer
2012-10-17 09:15:55 -04:00
2021-07-27 10:38:16 -04:00
#### deliver.action_mailer
2012-10-17 09:15:55 -04:00
2018-09-09 07:16:20 -04:00
| Key | Value |
| --------------------- | ---------------------------------------------------- |
| `:mailer` | Name of the mailer class |
| `:message_id` | ID of the message, generated by the Mail gem |
| `:subject` | Subject of the mail |
| `:to` | To address(es) of the mail |
| `:from` | From address of the mail |
| `:bcc` | BCC addresses of the mail |
| `:cc` | CC addresses of the mail |
| `:date` | Date of the mail |
| `:mail` | The encoded form of the mail |
| `:perform_deliveries` | Whether delivery of this message is performed or not |
2012-10-17 09:15:55 -04:00
```ruby
{
mailer: "Notification",
message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",
subject: "Rails Guides",
2017-09-23 22:25:15 -04:00
to: ["users@rails.com", "dhh@rails.com"],
2012-10-17 09:15:55 -04:00
from: ["me@rails.com"],
date: Sat, 10 Mar 2012 14:18:09 +0100,
2018-09-09 07:16:20 -04:00
mail: "...", # omitted for brevity
perform_deliveries: true
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### process.action_mailer
2017-10-13 09:26:13 -04:00
| Key | Value |
| ------------- | ------------------------ |
| `:mailer` | Name of the mailer class |
| `:action` | The action |
| `:args` | The arguments |
```ruby
{
mailer: "Notification",
action: "welcome_email",
args: []
}
```
2021-07-27 10:38:16 -04:00
### Active Support
2012-10-17 09:15:55 -04:00
2021-07-27 10:38:16 -04:00
#### cache_read.active_support
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------------------ | ------------------------------------------------- |
| `:key` | Key used in the store |
2020-10-22 04:53:07 -04:00
| `:store` | Name of the store class |
2012-10-17 09:15:55 -04:00
| `:hit` | If this read is a hit |
| `:super_operation` | :fetch is added when a read is used with `#fetch` |
2021-07-27 10:38:16 -04:00
#### cache_generate.active_support
2012-10-17 09:15:55 -04:00
This event is only used when `#fetch` is called with a block.
2020-10-22 04:53:07 -04:00
| Key | Value |
| -------- | ----------------------- |
| `:key` | Key used in the store |
| `:store` | Name of the store class |
2012-10-17 09:15:55 -04:00
INFO. Options passed to fetch will be merged with the payload when writing to the store
```ruby
{
2020-10-22 04:53:07 -04:00
key: "name-of-complicated-computation",
store: "ActiveSupport::Cache::MemCacheStore"
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### cache_fetch_hit.active_support
2012-10-17 09:15:55 -04:00
This event is only used when `#fetch` is called with a block.
2020-10-22 04:53:07 -04:00
| Key | Value |
| -------- | ----------------------- |
| `:key` | Key used in the store |
| `:store` | Name of the store class |
2012-10-17 09:15:55 -04:00
INFO. Options passed to fetch will be merged with the payload.
```ruby
{
2020-10-22 04:53:07 -04:00
key: "name-of-complicated-computation",
store: "ActiveSupport::Cache::MemCacheStore"
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### cache_write.active_support
2012-10-17 09:15:55 -04:00
2020-10-22 04:53:07 -04:00
| Key | Value |
| -------- | ----------------------- |
| `:key` | Key used in the store |
| `:store` | Name of the store class |
2012-10-17 09:15:55 -04:00
2014-05-21 16:00:55 -04:00
INFO. Cache stores may add their own keys
2012-10-17 09:15:55 -04:00
```ruby
{
2020-10-22 04:53:07 -04:00
key: "name-of-complicated-computation",
store: "ActiveSupport::Cache::MemCacheStore"
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### cache_delete.active_support
2012-10-17 09:15:55 -04:00
2020-10-22 04:53:07 -04:00
| Key | Value |
| -------- | ----------------------- |
| `:key` | Key used in the store |
| `:store` | Name of the store class |
2012-10-17 09:15:55 -04:00
```ruby
{
2020-10-22 04:53:07 -04:00
key: "name-of-complicated-computation",
store: "ActiveSupport::Cache::MemCacheStore"
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
#### cache_exist?.active_support
2012-10-17 09:15:55 -04:00
2020-10-22 04:53:07 -04:00
| Key | Value |
| -------- | ----------------------- |
| `:key` | Key used in the store |
| `:store` | Name of the store class |
2012-10-17 09:15:55 -04:00
```ruby
{
2020-10-22 04:53:07 -04:00
key: "name-of-complicated-computation",
store: "ActiveSupport::Cache::MemCacheStore"
2012-10-17 09:15:55 -04:00
}
```
2021-07-27 10:38:16 -04:00
### Active Job
2015-08-01 19:47:21 -04:00
2021-07-27 10:38:16 -04:00
#### enqueue_at.active_job
2015-08-01 19:47:21 -04:00
2015-08-24 07:33:32 -04:00
| Key | Value |
| ------------ | -------------------------------------- |
| `:adapter` | QueueAdapter object processing the job |
| `:job` | Job object |
2015-08-01 19:47:21 -04:00
2021-07-27 10:38:16 -04:00
#### enqueue.active_job
2015-08-01 19:47:21 -04:00
2015-08-24 07:33:32 -04:00
| Key | Value |
| ------------ | -------------------------------------- |
| `:adapter` | QueueAdapter object processing the job |
| `:job` | Job object |
2015-08-01 19:47:21 -04:00
2021-07-27 10:38:16 -04:00
#### enqueue_retry.active_job
2018-08-29 13:28:55 -04:00
| Key | Value |
| ------------ | -------------------------------------- |
| `:job` | Job object |
| `:adapter` | QueueAdapter object processing the job |
| `:error` | The error that caused the retry |
2018-09-16 10:27:05 -04:00
| `:wait` | The delay of the retry |
2018-08-29 13:28:55 -04:00
2021-07-27 10:38:16 -04:00
#### perform_start.active_job
2015-08-01 19:47:21 -04:00
2015-08-24 07:33:32 -04:00
| Key | Value |
| ------------ | -------------------------------------- |
| `:adapter` | QueueAdapter object processing the job |
| `:job` | Job object |
2015-08-01 19:47:21 -04:00
2021-07-27 10:38:16 -04:00
#### perform.active_job
2015-08-01 19:47:21 -04:00
2015-08-24 07:33:32 -04:00
| Key | Value |
| ------------ | -------------------------------------- |
| `:adapter` | QueueAdapter object processing the job |
| `:job` | Job object |
2015-08-01 19:47:21 -04:00
2021-07-27 10:38:16 -04:00
#### retry_stopped.active_job
2018-08-29 13:28:55 -04:00
| Key | Value |
| ------------ | -------------------------------------- |
| `:adapter` | QueueAdapter object processing the job |
| `:job` | Job object |
| `:error` | The error that caused the retry |
2021-07-27 10:38:16 -04:00
#### discard.active_job
2018-08-29 13:28:55 -04:00
| Key | Value |
| ------------ | -------------------------------------- |
| `:adapter` | QueueAdapter object processing the job |
| `:job` | Job object |
| `:error` | The error that caused the discard |
2021-07-27 10:38:16 -04:00
### Action Cable
2017-10-13 10:23:45 -04:00
2021-07-27 10:38:16 -04:00
#### perform_action.action_cable
2017-10-13 10:23:45 -04:00
| Key | Value |
| ---------------- | ------------------------- |
| `:channel_class` | Name of the channel class |
| `:action` | The action |
| `:data` | A hash of data |
2021-07-27 10:38:16 -04:00
#### transmit.action_cable
2017-10-13 10:23:45 -04:00
| Key | Value |
| ---------------- | ------------------------- |
| `:channel_class` | Name of the channel class |
| `:data` | A hash of data |
| `:via` | Via |
2021-07-27 10:38:16 -04:00
#### transmit_subscription_confirmation.action_cable
2017-10-13 10:23:45 -04:00
| Key | Value |
| ---------------- | ------------------------- |
| `:channel_class` | Name of the channel class |
2021-07-27 10:38:16 -04:00
#### transmit_subscription_rejection.action_cable
2017-10-13 10:23:45 -04:00
| Key | Value |
| ---------------- | ------------------------- |
| `:channel_class` | Name of the channel class |
2021-07-27 10:38:16 -04:00
#### broadcast.action_cable
2017-10-13 10:23:45 -04:00
| Key | Value |
| --------------- | -------------------- |
| `:broadcasting` | A named broadcasting |
| `:message` | A hash of message |
| `:coder` | The coder |
2021-07-27 10:38:16 -04:00
### Active Storage
2017-10-06 23:20:58 -04:00
2021-07-27 10:38:16 -04:00
#### service_upload.active_storage
2017-10-06 23:20:58 -04:00
| Key | Value |
| ------------ | ---------------------------- |
| `:key` | Secure token |
| `:service` | Name of the service |
| `:checksum` | Checksum to ensure integrity |
2021-07-27 10:38:16 -04:00
#### service_streaming_download.active_storage
2017-10-06 23:20:58 -04:00
| Key | Value |
| ------------ | ------------------- |
| `:key` | Secure token |
| `:service` | Name of the service |
2021-07-27 10:38:16 -04:00
#### service_download_chunk.active_storage
2019-04-17 13:25:46 -04:00
| Key | Value |
| ------------ | ------------------------------- |
| `:key` | Secure token |
| `:service` | Name of the service |
| `:range` | Byte range attempted to be read |
2021-07-27 10:38:16 -04:00
#### service_download.active_storage
2017-10-06 23:20:58 -04:00
| Key | Value |
| ------------ | ------------------- |
| `:key` | Secure token |
| `:service` | Name of the service |
2021-07-27 10:38:16 -04:00
#### service_delete.active_storage
2017-10-06 23:20:58 -04:00
| Key | Value |
| ------------ | ------------------- |
| `:key` | Secure token |
| `:service` | Name of the service |
2021-07-27 10:38:16 -04:00
#### service_delete_prefixed.active_storage
2017-12-11 13:16:59 -05:00
| Key | Value |
| ------------ | ------------------- |
| `:prefix` | Key prefix |
| `:service` | Name of the service |
2021-07-27 10:38:16 -04:00
#### service_exist.active_storage
2017-10-06 23:20:58 -04:00
| Key | Value |
| ------------ | --------------------------- |
| `:key` | Secure token |
| `:service` | Name of the service |
| `:exist` | File or blob exists or not |
2021-07-27 10:38:16 -04:00
#### service_url.active_storage
2017-10-06 23:20:58 -04:00
| Key | Value |
| ------------ | ------------------- |
| `:key` | Secure token |
| `:service` | Name of the service |
2019-04-01 08:29:37 -04:00
| `:url` | Generated URL |
2015-08-01 19:47:21 -04:00
2021-07-27 10:38:16 -04:00
#### service_update_metadata.active_storage
2019-04-17 13:25:46 -04:00
| Key | Value |
| --------------- | ------------------------------ |
| `:key` | Secure token |
| `:service` | Name of the service |
| `:content_type` | HTTP Content-Type field |
| `:disposition` | HTTP Content-Disposition field |
INFO. The only ActiveStorage service that provides this hook so far is GCS.
2021-07-27 10:38:16 -04:00
#### preview.active_storage
2019-04-17 13:25:46 -04:00
| Key | Value |
| ------------ | ------------------- |
| `:key` | Secure token |
2021-07-27 10:38:16 -04:00
#### transform.active_storage
2020-10-12 09:26:58 -04:00
2021-08-03 23:53:58 -04:00
#### analyze.active_storage
| Key | Value |
| ------------ | ------------------------------ |
| `:analyzer` | Name of analyzer e.g., ffprobe |
2021-07-27 10:38:16 -04:00
### Railties
2013-11-11 12:56:02 -05:00
2021-07-27 10:38:16 -04:00
#### load_config_initializer.railties
2013-11-11 12:56:02 -05:00
| Key | Value |
| -------------- | ----------------------------------------------------- |
| `:initializer` | Path to loaded initializer from `config/initializers` |
2021-07-27 10:38:16 -04:00
### Rails
2012-10-17 09:15:55 -04:00
2021-07-27 10:38:16 -04:00
#### deprecation.rails
2012-10-17 09:15:55 -04:00
| Key | Value |
| ------------ | ------------------------------- |
| `:message` | The deprecation warning |
| `:callstack` | Where the deprecation came from |
2020-07-18 12:00:35 -04:00
Exceptions
----------
If an exception happens during any instrumentation the payload will include
information about it.
| Key | Value |
| ------------------- | -------------------------------------------------------------- |
| `:exception` | An array of two elements. Exception class name and the message |
| `:exception_object` | The exception object |
2012-10-17 09:15:55 -04:00
Creating custom events
----------------------
Adding your own events is easy as well. `ActiveSupport::Notifications` will take care of
all the heavy lifting for you. Simply call `instrument` with a `name` , `payload` and a block.
The notification will be sent after the block returns. `ActiveSupport` will generate the start and end times
2018-12-17 03:25:55 -05:00
and add the instrumenter's unique ID. All data passed into the `instrument` call will make
2018-10-05 17:02:39 -04:00
it into the payload.
2012-10-17 09:15:55 -04:00
Here's an example:
```ruby
ActiveSupport::Notifications.instrument "my.custom.event", this: :data do
# do your custom stuff here
end
```
Now you can listen to this event with:
```ruby
ActiveSupport::Notifications.subscribe "my.custom.event" do |name, started, finished, unique_id, data|
2012-10-22 15:27:55 -04:00
puts data.inspect # {:this=>:data}
2012-10-17 09:15:55 -04:00
end
```
2019-03-22 13:20:32 -04:00
You also have the option to call instrument without passing a block. This lets you leverage the
instrumentation infrastructure for other messaging uses.
```ruby
ActiveSupport::Notifications.instrument "my.custom.event", this: :data
ActiveSupport::Notifications.subscribe "my.custom.event" do |name, started, finished, unique_id, data|
puts data.inspect # {:this=>:data}
end
```
2012-10-17 09:15:55 -04:00
You should follow Rails conventions when defining your own events. The format is: `event.library` .
2017-10-06 17:38:51 -04:00
If your application is sending Tweets, you should create an event named `tweet.twitter` .