2012-06-06 29 views
16

在rails 3.2中有沒有一種方法(一種gem,一個插件或其他)來知道哪一行代碼觸發數據庫查詢? 例如,在我的日誌我有:如何獲取觸發查詢的代碼行?

User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 5 LIMIT 1 

我怎麼能知道的觸發查詢代碼行? Thx ...

回答

21

我發現這個解決方案:

module QueryTrace 
    def self.enable! 
    ::ActiveRecord::LogSubscriber.send(:include, self) 
    end 

    def self.append_features(klass) 
    super 
    klass.class_eval do 
     unless method_defined?(:log_info_without_trace) 
     alias_method :log_info_without_trace, :sql 
     alias_method :sql, :log_info_with_trace 
     end 
    end 
    end 

    def log_info_with_trace(event) 
    log_info_without_trace(event) 
    trace_log = Rails.backtrace_cleaner.clean(caller).first 
    if trace_log && event.payload[:name] != 'SCHEMA' 
     logger.debug(" \\_ \e[33mCalled from:\e[0m " + trace_log) 
    end 
    end 
end 

在一些初始化加QueryTrace.enable!

+0

是這個rails版本特有的嗎?無法找到它與紅寶石1.9.3,rails3.2.4,使用控制檯工作。我可以看到查詢被解僱,但沒有代碼行號。 –

+0

使用rails 3.2.4和ruby 1.9.3爲我工作...您需要添加QueryTrace.enable!在一些初始化器... – Pioz

+1

謝謝你,親切的先生。這對我追蹤一些n + 1問題是一個巨大的幫助。 – antinome

-1

你可以猴子補丁BufferedLogger做你想做的。把這個文件在你的config/initializers路徑:

require 'active_support/buffered_logger' 

class ActiveSupport::BufferedLogger 

    def add(severity, message = nil, progname = nil, &block) 
    add_debugging_details(severity) 
    @log.add(severity, message, progname, &block) 
    end 

    private 

    EXCLUDE_CALLERS = Gem.paths.path.clone << 'script/rails' << RbConfig::CONFIG['rubylibdir'] << __FILE__ 

    def add_debugging_details(severity) 
    caller_in_app = caller.select do |line| 
     EXCLUDE_CALLERS.detect { |gem_path| line.starts_with?(gem_path) }.nil? 
    end 

    return if caller_in_app.empty? 

    @log.add(severity, "Your code in \e[1;33m#{caller_in_app.first}\e[0;0m triggered:") 
    end 

end if Rails.env.development? 
+0

不起作用形成我...把它添加總是同一行:在XXX/lib目錄/ query_trace.rb'你的代碼:20:在'log_info_with_trace」觸發: '。看看我的解決方案。 – Pioz

+0

您將它與其他'QueryTrace'答案組合在一起。您可以將'xxx/lib/query_trace.rb'添加到'EXCLUDE_CALLERS'常量或將其禁用。 –

1

使用active-record-query-trace寶石:

Gemfile

gem 'active_record_query_trace' 

然後bundle,然後在config/environments/development.rb

ActiveRecordQueryTrace.enabled = true 
相關問題