使用Mongoid时process_action.action_controller载荷中db_runtime为0的支持方案咨询
解决Mongoid未计入Rails
process_action中db_runtime的问题 哎,这个问题我之前帮好几个开发者排查过——确实,Mongoid默认不会把它的数据库查询耗时上报到Rails的process_action.action_controller负载里的db_runtime字段,所以你看到的数值一直是0。不过有几个靠谱的解决思路,我给你详细说说:
方法一:手动订阅Mongoid的Instrumentation事件
Mongoid本身会发出mongoid.query类型的通知事件,我们可以通过订阅这个事件,把查询时间手动累加到Rails用来计算db_runtime的变量中。
在你的Rails项目里新建一个初始化文件config/initializers/mongoid_instrumentation.rb,填入以下代码:
# 订阅Mongoid查询事件,将耗时计入Rails的db_runtime ActiveSupport::Notifications.subscribe('mongoid.query') do |*args| event = ActiveSupport::Notifications::Event.new(*args) next unless Thread.current[:current_request] # 获取当前请求已有的db_runtime,默认值为0 current_db_runtime = Thread.current[:current_request].env['action_dispatch.request.db_runtime'] || 0 # 累加Mongoid查询耗时 Thread.current[:current_request].env['action_dispatch.request.db_runtime'] = current_db_runtime + event.duration end # 绑定请求生命周期,确保线程安全 Rails.application.config.after_initialize do ActionController::Base.before_action do |controller| Thread.current[:current_request] = controller.request end ActionController::Base.after_action do Thread.current[:current_request] = nil end end
代码说明:
- 我们用
ActiveSupport::Notifications监听Mongoid的查询事件,每次查询完成后把耗时加到action_dispatch.request.db_runtime里——这正是Rails用来生成process_action负载中db_runtime的核心变量。 - 用线程局部变量
Thread.current[:current_request]来关联当前请求,避免多线程服务器(比如Puma)下的请求数据污染,请求结束后一定要清空这个变量。
方法二:使用现成的Gem
如果不想自己写初始化代码,也有专门的Ruby Gem可以自动帮你完成Mongoid查询时间与Rails Instrumentation的整合。你只需要在Gemfile中添加对应的Gem,执行bundle install即可。注意要选择与你的Mongoid、Rails版本匹配且维护活跃的版本。
验证是否生效
配置完成后,你可以通过以下方式验证:
- 查看Rails日志,
Completed行里的db字段应该会显示Mongoid的查询总耗时; - 在控制器中添加调试代码:
Rails.logger.info "当前DB总耗时: #{request.env['action_dispatch.request.db_runtime']}",查看日志输出; - 如果使用了APM工具(比如New Relic),可以检查数据库监控指标是否包含了Mongoid的查询时间。
内容的提问来源于stack exchange,提问作者user793789
相关产品推荐
相关产品推荐

