You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过ActiveSupport事件暴露Rails各API请求的ActiveRecord查询数?

实现Rails请求ActiveRecord查询数的事件化暴露

完全可以做到把查询数注入process_action.action_controller事件的负载中,无需依赖第三方gem的日志输出,下面是具体实现方案:

核心思路

  1. 利用sql.active_record事件统计每个请求周期内的SQL查询次数(可按需排除缓存查询、Schema查询)
  2. 将查询数通过线程安全的方式存储(避免跨请求污染)
  3. 订阅process_action.action_controller事件,把统计的查询数追加到事件负载里

具体实现代码

方式1:无需额外gem,用Thread.current实现

在config/initializers/query_count_instrumentation.rb中添加以下代码:

# 统计SQL查询次数
ActiveSupport::Notifications.subscribe('sql.active_record') do |_name, _start, _finish, _id, payload|
  # 按需排除缓存查询、Schema查询,可根据业务调整
  next if payload[:cached] || payload[:name] == 'SCHEMA'

  current_count = Thread.current[:ar_query_count] || 0
  Thread.current[:ar_query_count] = current_count + 1
end

# 清理线程变量,避免跨请求污染
Rails.application.config.after_initialize do
  ActionController::Base.around_action do |_controller, block|
    Thread.current[:ar_query_count] = 0
    block.call
  ensure
    Thread.current[:ar_query_count] = nil
  end
end

# 将查询数注入process_action事件负载
ActiveSupport::Notifications.subscribe('process_action.action_controller') do |_name, _start, _finish, _id, payload|
  payload[:query_count] = Thread.current[:ar_query_count] || 0
end

方式2:用request_store提升线程安全性(推荐)

如果担心Thread.current在复杂场景下的线程安全问题,可以使用request_storegem:

  1. 先添加gem到Gemfile:
gem 'request_store'
  1. 执行bundle install后,创建初始化文件config/initializers/query_count_instrumentation.rb:
# 统计SQL查询次数
ActiveSupport::Notifications.subscribe('sql.active_record') do |_name, _start, _finish, _id, payload|
  next if payload[:cached] || payload[:name] == 'SCHEMA'

  RequestStore.store[:ar_query_count] ||= 0
  RequestStore.store[:ar_query_count] += 1
end

# 将查询数注入process_action事件负载
ActiveSupport::Notifications.subscribe('process_action.action_controller') do |_name, _start, _finish, _id, payload|
  payload[:query_count] = RequestStore.store[:ar_query_count] || 0
end

验证方法

你可以在任意地方订阅process_action.action_controller事件来获取查询数,比如在初始化文件中添加测试代码:

ActiveSupport::Notifications.subscribe('process_action.action_controller') do |_name, _start, _finish, _id, payload|
  puts "请求路径: #{payload[:path]} | 查询次数: #{payload[:query_count]} | 响应状态: #{payload[:status]}"
end

启动Rails服务后,发起API请求就能看到控制台输出包含查询数的事件数据。

内容的提问来源于stack exchange,提问作者Pattu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 02:25:15