0

对于每个请求,我都会在日志中得到这个:

Completed 200 OK in 854ms (Views: 1.0ms | ActiveRecord: 17.0ms)

是否有可能让它也包括查询的数量?
就像是:

Completed 200 OK in 854ms (Views: 1.0ms | ActiveRecord: 17.0ms | Queries: 10)

理想情况下,我希望所有“缓存”的也显示在该计数中。即,即使“缓存”使我免于访问数据库的“N+1”查询,我仍然想知道我有问题。

我很喜欢猴子补丁/手动编辑一些东西,因为我真的想要这个只是为了我的开发盒。

(如果这可以文明地制作,以便我可以在生产中使用它,那就更好了,但如果没有,我可以在自己的机器上手动修改 Rails)

谢谢!
丹尼尔

4

1 回答 1

2

我知道ThinkingSphinx gem 做了类似的事情,将运行 Sphinx 查询所花费的时间添加到日志中的摘要中。您可能可以做类似的事情(也许通过制作自己的 gem,因为我敢打赌其他人会喜欢这个功能)来显示查询的数量。我并没有真正仔细研究它是如何工作的,但看起来对 ActionController 和 LogSubscriber 的修改是负责任的:

lib/thinking_sphinx/action_controller.rb:

module ThinkingSphinx
  module ActionController
    extend ActiveSupport::Concern

    protected

    attr_internal :query_runtime

    def cleanup_view_runtime
      log_subscriber = ThinkingSphinx::ActiveRecord::LogSubscriber
      query_runtime_pre_render = log_subscriber.reset_runtime
      runtime = super
      query_runtime_post_render = log_subscriber.reset_runtime
      self.query_runtime = query_runtime_pre_render + query_runtime_post_render
      runtime - query_runtime_post_render
    end

    def append_info_to_payload(payload)
      super
      payload[:query_runtime] = query_runtime
    end

    module ClassMethods
      def log_process_action(payload)
        messages, query_runtime = super, payload[:query_runtime]
        messages << ("Sphinx: %.1fms" % query_runtime.to_f) if query_runtime
        messages
      end
    end
  end
end

lib/thinking_sphinx/active_record/log_subscriber.rb:

require 'active_support/log_subscriber'

module ThinkingSphinx
  module ActiveRecord
    class LogSubscriber < ActiveSupport::LogSubscriber
      def self.runtime=(value)
        Thread.current['thinking_sphinx_query_runtime'] = value
      end

      def self.runtime
        Thread.current['thinking_sphinx_query_runtime'] ||= 0
      end

      def self.reset_runtime
        rt, self.runtime = runtime, 0
        rt
      end

      def initialize
        super
        @odd_or_even = false
      end

      def query(event)
        self.class.runtime += event.duration
        return unless logger.debug?

        identifier = color('Sphinx Query (%.1fms)' % event.duration, GREEN, true)
        query = event.payload[:query]
        query = color query, nil, true if odd?

        debug "  #{identifier}  #{query}"
      end

      def message(event)
        return unless logger.debug?

        identifier = color 'Sphinx', GREEN, true
        message = event.payload[:message]
        message = color message, nil, true if odd?

        debug "  #{identifier}  #{message}"
      end

      def odd?
        @odd_or_even = !@odd_or_even
      end

      def logger
        return @logger if defined? @logger
        self.logger = ::ActiveRecord::Base.logger
      end

      def logger=(logger)
        @logger = logger
      end

      attach_to :thinking_sphinx
    end
  end
end

我希望这有帮助。

于 2012-11-07T15:28:39.327 回答