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

如何在Rails中将ActiveSupport监控指标暴露为HTTP响应头?

将ActiveSupport Instrumentation指标暴露为HTTP响应头

首先看你提供的性能日志示例:

(78.3ms) ItemsController -- Completed #active -- { :view_runtime => 10.46, :db_runtime => 6.76, :controller => "ItemsController", :action => "active", :format => "*/*", :method => "GET", :path => "/active", :status => 200, :status_message => "OK" }

需求说明

想找简便方法,把日志里的view_runtime、db_runtime这两个ActiveSupport Instrumentation指标,直接暴露为HTTP响应头。

使用场景:预发布/测试环境查看日志流程繁琐(需VPN + SSH + cat/grep/tail命令),且环境使用频率高,难以快速定位目标日志。若这些指标能在AJAX请求的Web检查器中直接查看,可大幅提升调试效率。

已知New Relic,但认为它对该简单任务过于冗余,暂不考虑使用。

解决方案

方法1:全局控制器钩子(最简单)

在app/controllers/application_controller.rb中添加全局after_action,直接将指标写入响应头:

class ApplicationController < ActionController::Base
  after_action :inject_performance_headers

  private

  def inject_performance_headers
    # 仅在预发布/测试/开发环境开启,避免影响生产环境
    return unless Rails.env.staging? || Rails.env.test? || Rails.env.development?

    response.headers['X-View-Runtime'] = view_runtime.round(2).to_s if view_runtime
    response.headers['X-DB-Runtime'] = db_runtime.round(2).to_s if db_runtime
  end
end

配置完成后,所有请求的响应都会带上X-View-Runtime和X-DB-Runtime自定义头,直接在浏览器开发者工具的「网络」面板就能查看。

方法2:自定义中间件(更底层)

如果不想修改控制器,可通过中间件实现:

  1. 在app/middleware/performance_headers_middleware.rb创建中间件文件:
class PerformanceHeadersMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    status, headers, response = @app.call(env)

    # 仅在指定环境生效
    return [status, headers, response] unless Rails.env.staging? || Rails.env.test? || Rails.env.development?

    request = ActionDispatch::Request.new(env)
    # 从控制器实例中获取性能指标
    if request.controller_instance&.respond_to?(:view_runtime) && request.controller_instance&.respond_to?(:db_runtime)
      headers['X-View-Runtime'] = request.controller_instance.view_runtime.round(2).to_s
      headers['X-DB-Runtime'] = request.controller_instance.db_runtime.round(2).to_s
    end

    [status, headers, response]
  end
end
  1. 在config/application.rb中注册中间件:
module YourAppName
  class Application < Rails::Application
    # ...其他配置
    config.middleware.use PerformanceHeadersMiddleware
  end
end

方法3:ActiveSupport订阅器(更灵活)

如果需要捕获更多Instrumentation指标,可利用ActiveSupport的订阅机制:

# 在config/initializers/performance_headers.rb中添加
ActiveSupport::Notifications.subscribe('process_action.action_controller') do |name, start, finish, id, payload|
  # 仅在指定环境执行
  next unless Rails.env.staging? || Rails.env.test? || Rails.env.development?

  response = Thread.current[:current_response]
  return unless response

  response.headers['X-View-Runtime'] = payload[:view_runtime]&.round(2)&.to_s
  response.headers['X-DB-Runtime'] = payload[:db_runtime]&.round(2)&.to_s
end

# 同时在ApplicationController中绑定当前响应到线程变量
class ApplicationController < ActionController::Base
  around_action :set_current_response

  private

  def set_current_response
    Thread.current[:current_response] = response
    yield
  ensure
    Thread.current[:current_response] = nil
  end
end

注意事项

  • 务必仅在非生产环境开启,避免内部指标暴露给外部用户,同时减少不必要的性能开销。
  • 可根据需求自定义响应头名称,比如改为X-Perf-View、X-Perf-DB等更简洁的命名。
  • 若个别控制器不需要这些头,可在对应控制器中用skip_after_action :inject_performance_headers(对应方法1)跳过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 11:51:32