Active Support 提供的檢測 API 允許開發人員提供其他開發人員可以掛鉤的掛載機制。 Rails 框架 中有幾個。使用此 API,開發人員可以選擇在他們的應用程式或另一段 Ruby 程式碼中發生某些事件時收到通知。
例如,在 Active Record 中提供了一個掛載機制,每次 Active Record 在資料庫上使用 SQL 查詢時都會呼叫該掛載機制。這個掛載機制可以被訂閱 ,並用於跟蹤某個 action 期間的查詢數量。圍繞 controller 的 action 的處理還有另一個掛載機制。例如,這可以用於跟蹤特定 action 花費了多長時間。
您甚至可以在您的應用程式中建立您自己的事件 ,您可以稍後訂閱。
訂閱事件很容易。將 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
Copy
如果您擔心 started
和 finished
計算精確經過時間的準確性,請使用 ActiveSupport::Notifications.monotonic_subscribe
。給定的塊將接收與上述相同的引數,但 started
和 finished
將具有 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
Copy
每次定義所有這些塊引數可能很乏味。您可以輕鬆建立 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
Copy
你也可以傳遞一個只接受一個引數的塊,它會接收一個事件物件:
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
Copy
大多數時候你只關心資料本身。這是獲取資料的快捷方式。
ActiveSupport :: Notifications . subscribe "process_action.action_controller" do |* args |
data = args . extract_options!
data # { extra: :information }
end
Copy
您還可以訂閱與正則表示式匹配的事件。這使您能夠訂閱
一次多個事件。以下是從 ActionController
訂閱所有內容的方法。
ActiveSupport :: Notifications . subscribe /action_controller/ d o |* args |
# inspect all ActionController events
end
Copy
在 Ruby on Rails 框架中,為常見事件提供了許多掛載機制。下面詳細介紹了這些。
{
key: 'posts/1-dashboard-view'
}
Copy
{
key: 'posts/1-dashboard-view'
}
Copy
{
key: 'posts/1-dashboard-view'
}
Copy
{
key: 'posts/1-dashboard-view'
}
Copy
{
path: '/users/1'
}
Copy
{
path: '/users/1'
}
Copy
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"
}
Copy
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
}
Copy
資訊。呼叫者可以新增額外的 keys。
ActionController
不會向有效負載新增任何特定資訊。所有選項都傳遞給有效負載。
Key
Value
:status
HTTP 回應程式碼
:location
重定向到的 URL
:request
ActionDispatch::Request
{
status: 302 ,
location: "http://localhost:3000/posts/new" ,
request: #<ActionDispatch::Request:0x00007ff1cb9bd7b8>
}
Copy
Key
Value
:filter
停止 action 的過濾器
{
filter: ":halting_filter"
}
Copy
Key
Value
:keys
未經許可的keys
:context
使用以下 keys 雜湊: :controller, :action, :params, :request
Key
Value
:middleware
中介軟體名稱
Key
Value
:identifier
模板的完整路徑
:layout
適用佈局
{
identifier: "/Users/adam/projects/notifications/app/views/posts/index.html.erb" ,
layout: "layouts/application"
}
Copy
Key
Value
:identifier
模板的完整路徑
{
identifier: "/Users/adam/projects/notifications/app/views/posts/_form.html.erb"
}
Copy
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
}
Copy
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
}
Copy
Key
Value
:record_count
實例化的記錄數
:class_name
記錄類
{
record_count: 1 ,
class_name: "User"
}
Copy
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
}
Copy
Key
Value
:mailer
郵件程式類的名稱
:action
action
:args
論據
{
mailer: "Notification" ,
action: "welcome_email" ,
args: []
}
Copy
Key
Value
:key
店內使用的Key
:store
商店類名稱
:hit
如果此閱讀很受歡迎
:super_operation
:fetch 與 #fetch
一起使用讀取時新增
此事件僅在使用塊呼叫 #fetch
時使用。
Key
Value
:key
店內使用的Key
:store
商店類名稱
資訊。傳遞給 fetch 的選項將在寫入儲存時與有效負載合併
{
key: "name-of-complicated-computation" ,
store: "ActiveSupport::Cache::MemCacheStore"
}
Copy
此事件僅在使用塊呼叫 #fetch
時使用。
Key
Value
:key
店內使用的Key
:store
商店類名稱
資訊。傳遞給 fetch 的選項將與有效負載合併。
{
key: "name-of-complicated-computation" ,
store: "ActiveSupport::Cache::MemCacheStore"
}
Copy
Key
Value
:key
店內使用的Key
:store
商店類名稱
資訊。快取儲存可以新增自己的 keys
{
key: "name-of-complicated-computation" ,
store: "ActiveSupport::Cache::MemCacheStore"
}
Copy
Key
Value
:key
店內使用的Key
:store
商店類名稱
{
key: "name-of-complicated-computation" ,
store: "ActiveSupport::Cache::MemCacheStore"
}
Copy
Key
Value
:key
店內使用的Key
:store
商店類名稱
{
key: "name-of-complicated-computation" ,
store: "ActiveSupport::Cache::MemCacheStore"
}
Copy
Key
Value
:adapter
處理作業的 QueueAdapter 物件
:job
工作物件
Key
Value
:adapter
處理作業的 QueueAdapter 物件
:job
工作物件
Key
Value
:job
工作物件
:adapter
處理作業的 QueueAdapter 物件
:error
導致重試的錯誤
:wait
重試的延遲
Key
Value
:adapter
處理作業的 QueueAdapter 物件
:job
工作物件
Key
Value
:adapter
處理作業的 QueueAdapter 物件
:job
工作物件
Key
Value
:adapter
處理作業的 QueueAdapter 物件
:job
工作物件
:error
導致重試的錯誤
Key
Value
:adapter
處理作業的 QueueAdapter 物件
:job
工作物件
:error
導致丟棄的錯誤
Key
Value
:channel_class
通道類名稱
:action
action
:data
資料雜湊
Key
Value
:channel_class
通道類名稱
:data
資料雜湊
:via
透過
Key
Value
:channel_class
通道類名稱
Key
Value
:channel_class
通道類名稱
Key
Value
:broadcasting
一個命名廣播
:message
訊息雜湊
:coder
編碼器
Key
Value
:key
保護token
:service
服務名稱
:checksum
校驗和以確保完整性
Key
Value
:key
保護token
:service
服務名稱
Key
Value
:key
保護token
:service
服務名稱
:range
試圖讀取的位元組範圍
Key
Value
:key
保護token
:service
服務名稱
Key
Value
:key
保護token
:service
服務名稱
Key
Value
:prefix
Key 字首
:service
服務名稱
Key
Value
:key
保護token
:service
服務名稱
:exist
檔案或 blob 是否存在
Key
Value
:key
保護token
:service
服務名稱
:url
生成的網址
Key
Value
:key
保護token
:service
服務名稱
:content_type
HTTP 內容型別欄位
:disposition
HTTP Content-Disposition 欄位
資訊。到目前為止,唯一提供此掛載機制的 ActiveStorage 服務是 GCS。
Key
Value
:analyzer
分析器的名稱,例如 ffprobe
Key
Value
:initializer
從 config/initializers
載入初始化程式的路徑
Key
Value
:message
棄用警告
:callstack
棄用從何而來
如果在任何檢測期間發生異常,有效負載將包括
關於它的資訊。
Key
Value
:exception
兩個元素的陣列。異常類名和訊息
:exception_object
異常物件
新增您自己的事件也很容易。 ActiveSupport::Notifications
會照顧
為您完成所有繁重的工作。只需使用 name
、payload
和一個塊呼叫 instrument
。
該通知將在塊返回後傳送。 ActiveSupport
將生成開始和結束時間
並新增檢測器的唯一 ID。傳入 instrument
呼叫的所有資料將使
它進入有效載荷。
下面是一個例子:
ActiveSupport :: Notifications . instrument "my.custom.event" , this: :data do
# do your custom stuff here
end
Copy
現在您可以透過以下方式收聽此事件:
ActiveSupport :: Notifications . subscribe "my.custom.event" do | name , started , finished , unique_id , data |
puts data . inspect # {:this=>:data}
end
Copy
您還可以選擇在不傳遞塊的情況下呼叫儀器。這讓您可以利用
用於其他訊息傳遞用途的檢測基礎設施。
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
Copy
在定義自己的事件時,您應該遵循 Rails 約定。格式為:event.library
。
如果您的應用程式正在傳送推文,您應該建立一個名為 tweet.twitter
的事件。
回饋
我們鼓勵您幫助提高本指南的品質。
如果您發現任何拼寫錯誤或資訊錯誤,請提供回饋。
要開始回饋,您可以閱讀我們的 回饋 部分。
您還可能會發現不完整的內容或不是最新的內容。
請務必為 main 新增任何遺漏的文件。假設是
非穩定版指南(edge guides) 請先驗證問題是否已經在主分支上解決。
請前往 Ruby on Rails 指南寫作準則 查看寫作風格和慣例。
如果由於某種原因您發現要修復的內容但無法自行修補,請您 提出 issue 。
關於 Ruby on Rails 的任何類型的討論歡迎提供任何文件至 rubyonrails-docs 討論區 。