【问题标题】:How to get the line of code that triggers a query?如何获取触发查询的代码行?
【发布时间】:2012-06-10 07:13:20
【问题描述】:

rails 3.2 中有没有办法(gem、插件或其他东西)知道哪一行代码触发了数据库查询? 例如在我的日志中我有:

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

我如何知道触发查询的代码行? 谢谢...

【问题讨论】:

    标签: ruby-on-rails ruby activerecord logging


    【解决方案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?
    

    【讨论】:

    • 对我不起作用...它总是添加同一行:Your code in xxx/lib/query_trace.rb:20:in log_info_with_trace' 触发:`。看看我的解决方案。
    • 您将它与另一个 QueryTrace 答案结合在一起。您可以将xxx/lib/query_trace.rb 添加到EXCLUDE_CALLERS 常量或禁用它。
    【解决方案2】:

    我找到了这个解决方案:

    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!

    【讨论】:

    • 这个 Rails 版本是特定的吗?使用控制台找不到它与 ruby​​ 1.9.3、rails3.2.4 一起使用。我可以看到查询被触发,但不是代码行号。
    • 使用 rails 3.2.4 和 ruby​​ 1.9.3 为我工作...您需要添加 QueryTrace.enable!在一些初始化程序中......
    • 谢谢您,先生。这对我追踪一些 n+1 问题有很大帮助。
    • 现在看来这已经坏了。我得到的只是activesupport (3.2.9) lib/active_support/log_subscriber.rb:93:in `call'
    • 在 Rails 4.2.6 上为我工作
    【解决方案3】:

    使用active-record-query-trace gem:

    Gemfile:

    gem 'active_record_query_trace'
    

    然后是bundle,然后是config/environments/development.rb

    ActiveRecordQueryTrace.enabled = true
    

    【讨论】:

      【解决方案4】:

      Rails 5.2+

      将此添加到您的 config/environments/test.rb 或任何您想要放置线路的环境中。我正在 Rails 5 上进行测试。

        ActiveRecord::Base.verbose_query_logs = true
      

      你会得到文件和行。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-02
      • 2021-12-14
      • 2011-06-29
      • 2011-05-21
      • 2017-03-02
      相关资源
      最近更新 更多