v7.0.0
更多資訊請前往 rubyonrails.org: 更多在 Ruby on Rails

Active Support 儀表

Active Support 是核心 Rails 的一部分,它提供 Ruby 語言擴充套件、實用程式和其他東西。它包含的其中一件事是一個檢測 API,可以在應用程式內部使用它來測量發生在 Ruby 程式碼中的某些 actions,例如在 Rails 應用程式或框架本身內部。然而,它不僅限於 Rails。如果需要,它可以在其他 Ruby 指令碼中獨立使用。

在本指南中,您將學習如何使用 Active Support 內部的檢測 API 來測量 Rails 和其他 Ruby 程式碼內部的事件。

閱讀本指南後,您將瞭解:

1 儀器簡介

Active Support 提供的檢測 API 允許開發人員提供其他開發人員可以掛鉤的掛載機制。 Rails 框架 中有幾個。使用此 API,開發人員可以選擇在他們的應用程式或另一段 Ruby 程式碼中發生某些事件時收到通知。

例如,在 Active Record 中提供了一個掛載機制,每次 Active Record 在資料庫上使用 SQL 查詢時都會呼叫該掛載機制。這個掛載機制可以被訂閱,並用於跟蹤某個 action 期間的查詢數量。圍繞 controller 的 action 的處理還有另一個掛載機制。例如,這可以用於跟蹤特定 action 花費了多長時間。

您甚至可以在您的應用程式中建立您自己的事件,您可以稍後訂閱。

2 訂閱事件

訂閱事件很容易。將 ActiveSupport::Notifications.subscribe 與塊一起使用 收聽任何通知。

該塊接收以下引數:

  • 事件名稱
  • 開始的時間
  • 完成時間
  • 觸發事件的檢測器的唯一 ID
  • 有效載荷(在以後的部分中描述)
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

如果您擔心 startedfinished 計算精確經過時間的準確性,請使用 ActiveSupport::Notifications.monotonic_subscribe。給定的塊將接收與上述相同的引數,但 startedfinished 將具有 values 具有準確的單調時間而不是掛鐘時間。

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

每次定義所有這些塊引數可能很乏味。您可以輕鬆建立 ActiveSupport::Notifications::Event 從像這樣的塊引數:

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

你也可以傳遞一個只接受一個引數的塊,它會接收一個事件物件:

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

大多數時候你只關心資料本身。這是獲取資料的快捷方式。

ActiveSupport::Notifications.subscribe "process_action.action_controller" do |*args|
  data = args.extract_options!
  data # { extra: :information }
end

您還可以訂閱與正則表示式匹配的事件。這使您能夠訂閱 一次多個事件。以下是從 ActionController 訂閱所有內容的方法。

ActiveSupport::Notifications.subscribe /action_controller/ do |*args|
  # inspect all ActionController events
end

3 Rails 框架掛載機制

在 Ruby on Rails 框架中,為常見事件提供了許多掛載機制。下面詳細介紹了這些。

3.1 Action Controller

3.1.1 write_fragment.action_controller
Key Value
:key 完整的key
{
  key: 'posts/1-dashboard-view'
}
3.1.2 read_fragment.action_controller
Key Value
:key 完整的key
{
  key: 'posts/1-dashboard-view'
}
3.1.3 expire_fragment.action_controller
Key Value
:key 完整的key
{
  key: 'posts/1-dashboard-view'
}
3.1.4 存在片段?.actioncontroller
Key Value
:key 完整的key
{
  key: 'posts/1-dashboard-view'
}
3.1.5 write_page.action_controller
Key Value
:path 完整路徑
{
  path: '/users/1'
}
3.1.6 expire_page.action_controller
Key Value
:path 完整路徑
{
  path: '/users/1'
}
3.1.7 start_processing.action_controller
Key Value
:controller controller 名稱
:action action
:params 沒有任何過濾引數的請求引數的雜湊值
:headers 請求頭
:format html/js/json/xml 等
:method HTTP 請求動詞
:path 請求路徑
{
  controller: "PostsController",
  action: "new",
  params: { "action" => "new", "controller" => "posts" },
  headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
  format: :html,
  method: "GET",
  path: "/posts/new"
}
3.1.8 程序action.actioncontroller
Key Value
:controller controller 名稱
:action action
:params 沒有任何過濾引數的請求引數的雜湊值
:headers 請求頭
:format html/js/json/xml 等
:method HTTP 請求動詞
:path 請求路徑
:request ActionDispatch::Request
:response ActionDispatch::Response
:status HTTP 狀態碼
:view_runtime view 中花費的金額(以毫秒為單位)
:db_runtime 以毫秒為單位執行資料庫查詢所花費的金額
{
  controller: "PostsController",
  action: "index",
  params: {"action" => "index", "controller" => "posts"},
  headers: #<ActionDispatch::Http::Headers:0x0055a67a519b88>,
  format: :html,
  method: "GET",
  path: "/posts",
  request: #<ActionDispatch::Request:0x00007ff1cb9bd7b8>,
  response: #<ActionDispatch::Response:0x00007f8521841ec8>,
  status: 200,
  view_runtime: 46.848,
  db_runtime: 0.157
}
3.1.9 send_file.action_controller
Key Value
:path 檔案的完整路徑

資訊。呼叫者可以新增額外的 keys。

3.1.10 send_data.action_controller

ActionController 不會向有效負載新增任何特定資訊。所有選項都傳遞給有效負載。

3.1.11 redirect_to.action_controller
Key Value
:status HTTP 回應程式碼
:location 重定向到的 URL
:request ActionDispatch::Request
{
  status: 302,
  location: "http://localhost:3000/posts/new",
  request: #<ActionDispatch::Request:0x00007ff1cb9bd7b8>
}
3.1.12 停止callback.actioncontroller
Key Value
:filter 停止 action 的過濾器
{
  filter: ":halting_filter"
}
3.1.13 unpermitted_pa​​rameters.action_controller
Key Value
:keys 未經許可的keys
:context 使用以下 keys 雜湊: :controller, :action, :params, :request

3.2 Action 排程

3.2.1 process_middleware.action_dispatch
Key Value
:middleware 中介軟體名稱

3.3 Action View

3.3.1 render_template.action_view
Key Value
:identifier 模板的完整路徑
:layout 適用佈局
{
  identifier: "/Users/adam/projects/notifications/app/views/posts/index.html.erb",
  layout: "layouts/application"
}
3.3.2 render_partial.action_view
Key Value
:identifier 模板的完整路徑
{
  identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"
}
3.3.3 render_collection.action_view
Key Value
:identifier 模板的完整路徑
:count 收藏尺寸
:cache_hits 從快取中獲取的部分數

:cache_hits 僅在使用 cached: true 呈現集合時才包括在內。

{
  identifier: "/Users/adam/projects/notifications/app/views/posts/_post.html.erb",
  count: 3,
  cache_hits: 0
}

3.4 Active Record

3.4.1 sql.active_record
Key Value
:sql SQL 語句
:name 操作名稱
:connection 連線物件
:binds 繫結引數
:type_casted_binds 型別轉換繫結引數
:statement_name SQL 語句名稱
:cached 使用快取查詢時新增 true

資訊。介面卡也會新增它們自己的資料。

{
  sql: "SELECT \"posts\".* FROM \"posts\" ",
  name: "Post Load",
  connection: #<ActiveRecord::ConnectionAdapters::SQLite3Adapter:0x00007f9f7a838850>,
  binds: [#<ActiveModel::Attribute::WithCastValue:0x00007fe19d15dc00>],
  type_casted_binds: [11],
  statement_name: nil
}
3.4.2 實例化.active_record
Key Value
:record_count 實例化的記錄數
:class_name 記錄類
{
  record_count: 1,
  class_name: "User"
}

3.5 Action Mailer

3.5.1 投遞。action_mailer
Key Value
:mailer 郵件程式類的名稱
:message_id 郵件 ID,由 Mail gem 生成
:subject 郵件主題
:to 到郵件地址
:from 來自郵件地址
:bcc 郵件的密件抄送地址
:cc 郵件的抄送地址
:date 郵件日期
:mail 郵件的編碼形式
:perform_deliveries 是否執行此訊息的傳遞
{
  mailer: "Notification",
  message_id: "4f5b5491f1774_181b23fc3d4434d38138e5@mba.local.mail",
  subject: "Rails Guides",
  to: ["users@rails.com", "dhh@rails.com"],
  from: ["me@rails.com"],
  date: Sat, 10 Mar 2012 14:18:09 +0100,
  mail: "...", # omitted for brevity
  perform_deliveries: true
}
3.5.2 程序.action_mailer
Key Value
:mailer 郵件程式類的名稱
:action action
:args 論據
{
  mailer: "Notification",
  action: "welcome_email",
  args: []
}

3.6 Active Support

3.6.1 cache_read.active_support
Key Value
:key 店內使用的Key
:store 商店類名稱
:hit 如果此閱讀很受歡迎
:super_operation :fetch 與 #fetch 一起使用讀取時新增
3.6.2 cache_generate.active_support

此事件僅在使用塊呼叫 #fetch 時使用。

Key Value
:key 店內使用的Key
:store 商店類名稱

資訊。傳遞給 fetch 的選項將在寫入儲存時與有效負載合併

{
  key: "name-of-complicated-computation",
  store: "ActiveSupport::Cache::MemCacheStore"
}
3.6.3 cache_fetch_hit.active_support

此事件僅在使用塊呼叫 #fetch 時使用。

Key Value
:key 店內使用的Key
:store 商店類名稱

資訊。傳遞給 fetch 的選項將與有效負載合併。

{
  key: "name-of-complicated-computation",
  store: "ActiveSupport::Cache::MemCacheStore"
}
3.6.4 cache_write.active_support
Key Value
:key 店內使用的Key
:store 商店類名稱

資訊。快取儲存可以新增自己的 keys

{
  key: "name-of-complicated-computation",
  store: "ActiveSupport::Cache::MemCacheStore"
}
3.6.5 cache_delete.active_support
Key Value
:key 店內使用的Key
:store 商店類名稱
{
  key: "name-of-complicated-computation",
  store: "ActiveSupport::Cache::MemCacheStore"
}
3.6.6 cache_exist?.active_support
Key Value
:key 店內使用的Key
:store 商店類名稱
{
  key: "name-of-complicated-computation",
  store: "ActiveSupport::Cache::MemCacheStore"
}

3.7 Active Job

3.7.1 enqueue_at.active_job
Key Value
:adapter 處理作業的 QueueAdapter 物件
:job 工作物件
3.7.2 enqueue.active_job
Key Value
:adapter 處理作業的 QueueAdapter 物件
:job 工作物件
3.7.3 enqueue_retry.active_job
Key Value
:job 工作物件
:adapter 處理作業的 QueueAdapter 物件
:error 導致重試的錯誤
:wait 重試的延遲
3.7.4 perform_start.active_job
Key Value
:adapter 處理作業的 QueueAdapter 物件
:job 工作物件
3.7.5 perform.active_job
Key Value
:adapter 處理作業的 QueueAdapter 物件
:job 工作物件
3.7.6 retry_stopped.active_job
Key Value
:adapter 處理作業的 QueueAdapter 物件
:job 工作物件
:error 導致重試的錯誤
3.7.7 discard.active_job
Key Value
:adapter 處理作業的 QueueAdapter 物件
:job 工作物件
:error 導致丟棄的錯誤

3.8 Action Cable

3.8.1 perform_action.action_cable
Key Value
:channel_class 通道類名稱
:action action
:data 資料雜湊
3.8.2 傳輸.action_cable
Key Value
:channel_class 通道類名稱
:data 資料雜湊
:via 透過
3.8.3 transmit_subscription_confirmation.action_cable
Key Value
:channel_class 通道類名稱
3.8.4 transmit_subscription_rejection.action_cable
Key Value
:channel_class 通道類名稱
3.8.5 廣播。action_cable
Key Value
:broadcasting 一個命名廣播
:message 訊息雜湊
:coder 編碼器

3.9 Active Storage

3.9.1 service_upload.active_storage
Key Value
:key 保護token
:service 服務名稱
:checksum 校驗和以確保完整性
3.9.2 service_streaming_download.active_storage
Key Value
:key 保護token
:service 服務名稱
3.9.3 service_download_chunk.active_storage
Key Value
:key 保護token
:service 服務名稱
:range 試圖讀取的位元組範圍
3.9.4 service_download.active_storage
Key Value
:key 保護token
:service 服務名稱
3.9.5 service_delete.active_storage
Key Value
:key 保護token
:service 服務名稱
3.9.6 service_delete_prefixed.active_storage
Key Value
:prefix Key 字首
:service 服務名稱
3.9.7 service_exist.active_storage
Key Value
:key 保護token
:service 服務名稱
:exist 檔案或 blob 是否存在
3.9.8 service_url.active_storage
Key Value
:key 保護token
:service 服務名稱
:url 生成的網址
3.9.9 service_update_metadata.active_storage
Key Value
:key 保護token
:service 服務名稱
:content_type HTTP 內容型別欄位
:disposition HTTP Content-Disposition 欄位

資訊。到目前為止,唯一提供此掛載機制的 ActiveStorage 服務是 GCS。

3.9.10 preview.active_storage
Key Value
:key 保護token
3.9.11 transform.active_storage
3.9.12 analyze.active_storage
Key Value
:analyzer 分析器的名稱,例如 ffprobe

3.10 Rails

3.10.1 load_config_initializer.railties
Key Value
:initializer config/initializers 載入初始化程式的路徑

3.11 導軌

3.11.1 deprecation.rails
Key Value
:message 棄用警告
:callstack 棄用從何而來

4 例外

如果在任何檢測期間發生異常,有效負載將包括 關於它的資訊。

Key Value
:exception 兩個元素的陣列。異常類名和訊息
:exception_object 異常物件

5 建立自定義事件

新增您自己的事件也很容易。 ActiveSupport::Notifications 會照顧 為您完成所有繁重的工作。只需使用 namepayload 和一個塊呼叫 instrument。 該通知將在塊返回後傳送。 ActiveSupport 將生成開始和結束時間 並新增檢測器的唯一 ID。傳入 instrument 呼叫的所有資料將使 它進入有效載荷。

下面是一個例子:

ActiveSupport::Notifications.instrument "my.custom.event", this: :data do
  # do your custom stuff here
end

現在您可以透過以下方式收聽此事件:

ActiveSupport::Notifications.subscribe "my.custom.event" do |name, started, finished, unique_id, data|
  puts data.inspect # {:this=>:data}
end

您還可以選擇在不傳遞塊的情況下呼叫儀器。這讓您可以利用 用於其他訊息傳遞用途的檢測基礎設施。

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

在定義自己的事件時,您應該遵循 Rails 約定。格式為:event.library。 如果您的應用程式正在傳送推文,您應該建立一個名為 tweet.twitter 的事件。

回饋

我們鼓勵您幫助提高本指南的品質。

如果您發現任何拼寫錯誤或資訊錯誤,請提供回饋。 要開始回饋,您可以閱讀我們的 回饋 部分。

您還可能會發現不完整的內容或不是最新的內容。 請務必為 main 新增任何遺漏的文件。假設是 非穩定版指南(edge guides) 請先驗證問題是否已經在主分支上解決。 請前往 Ruby on Rails 指南寫作準則 查看寫作風格和慣例。

如果由於某種原因您發現要修復的內容但無法自行修補,請您 提出 issue

關於 Ruby on Rails 的任何類型的討論歡迎提供任何文件至 rubyonrails-docs 討論區