默認情況下,Rails logger會在執行後顯示SQL。有時 - 主要是查詢需要很長時間 - 我想配置記錄器在執行之前輸出SQL。然後它可以在數據庫響應後添加後續日誌。如何在事件發生之前記錄Rails查詢?
基本思路是這樣的:
10:01:01 POST Load Executing "SELECT * from posts;'
10:01:03 POST Load 1712ms
如何Rails的配置,打破SQL日誌分爲2步這樣嗎?
默認情況下,Rails logger會在執行後顯示SQL。有時 - 主要是查詢需要很長時間 - 我想配置記錄器在執行之前輸出SQL。然後它可以在數據庫響應後添加後續日誌。如何在事件發生之前記錄Rails查詢?
基本思路是這樣的:
10:01:01 POST Load Executing "SELECT * from posts;'
10:01:03 POST Load 1712ms
如何Rails的配置,打破SQL日誌分爲2步這樣嗎?
在執行之前,沒有標準的方式可以配置記錄器輸出SQL查詢。
但是,您仍然可以通過擴展ActiveRecord::LogSubscriber類以這種方式記錄查詢。現在
# initializers/extensions/active_record_logger.rb
module Extensions
module ActiveRecordLogger
IGNORE_PAYLOAD_NAMES = ActiveRecord::LogSubscriber::IGNORE_PAYLOAD_NAMES
# ActiveRecord::LogSubscriber doesn't implement this method.
# This method will be invoked before event starts processing.
# It's exactly we are looking for!
def start(name, id, payload)
super
return unless logger.debug?
return if IGNORE_PAYLOAD_NAMES.include?(payload[:name])
name = payload[:name]
sql = payload[:sql]
name = color(name, nil, true)
sql = color(sql, nil, true)
debug "STARTING #{name} #{sql}"
end
end
end
ActiveRecord::LogSubscriber.include Extensions::ActiveRecordLogger
你會得到的查詢日誌之前執行。例如,查詢
User.find 1
會產生
STARTING User Load SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 1]]
#<User id: 1, username: "dimakura", created_at: "2015-09-08 13:16:42", updated_at: "2015-09-08 13:16:42">
我認爲您正在尋找explain導軌方法。所以,你需要實現類似的東西:
@query = Some.model.query
Rails.logger @query.explain
ActiveRecord::Base.silence do
@query.load
end
Rails.logger "Finished"
當然,你可以添加定時器,原因,異常處理et.c.