由于您只想自定义查询名称以用于监控目的,所以我认为您只需更改方法query name
中的ActiveRecord::ConnectionAdapters#log
,此方法是记录执行的 sql 查询的一个日志,包括query name
.
这是我的解决方案:
# lib/active_record/base.rb
# note that MUST be base.rb
# otherwise you need to add initializer to extend Rails core
#
module ActiveRecord
module ConnectionAdapters
class AbstractAdapter
attr_accessor :log_tag
private
alias old_log log
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
if name != 'SCHEMA'
name = @log_tag
@log_tag = nil # reset
end
old_log(sql, name, binds, type_casted_binds, statement_name) do
yield
end
end
end
end
module QueryMethods
def log_tag(tag_name) # class method
spawn.log_tag(tag_name)
self
end
end
module Querying
delegate :log_tag, to: :all
end
class Relation
def log_tag(tag_name) # instance method
conn = klass.connection
conn.log_tag = tag_name
self
end
end
end
演示
Task.log_tag("DEMO").group(:status).count
# DEMO (0.7ms) SELECT COUNT(*) AS count_all, "tasks"."status" AS tasks_status FROM "tasks" GROUP BY "tasks"."status"
Task.where(status: 6).log_tag("SIX").first(20)
# SIX (0.8ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."status" = ? ORDER BY "tasks"."id" ASC LIMIT ?
Task.where(status: 6).first(20)
# (0.8ms) SELECT "tasks".* FROM "tasks" WHERE "tasks"."status" = ? ORDER BY "tasks"."id" ASC LIMIT ?
笔记
如果您想query name
针对特定查询进行修复,您可以使用带有键的散列是整个特定 sql 字符串(或整个 sql 的散列,例如 Rails 核心缓存查询的方式:)query_signature = ActiveSupport::Digest.hexdigest(to_sql)
,值是query name
您想要的。
# set up before hand
ActiveRecord::ConnectionAdapters::LogTags[Product.where...to_sql] = "DEMO"
# AbstractAdapter
LogTags = Hash.new
def log(sql, name...)
name = LogTags[sql]
# ...
end