将调用者应用程序堆栈跟踪与每个SQL查询一起记录

问题描述 投票:2回答:2

我遇到了在我的项目中搜索一些sql查询的根源的问题。

要对其进行故障排除,我想将应用程序调用程序堆栈与每个触发的查询一起记录。

我没有开箱即用的搜索解决方案,因此我决定自己制作可靠且可重复使用的解决方案。

通过跟踪堆栈我发现所有查询都通过Mysql2Adapter.execute方法的地方(我的意思是当然是mysql的情况)

我在rails初始化器dir中覆盖了这个方法,带有调用者堆栈日志的monkey patch列在下面:

module ActiveRecord
  module ConnectionAdapters
    class Mysql2Adapter < AbstractAdapter
      def execute(sql, name = nil)
        @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone
        if name == :skip_logging
          @connection.query(sql)
        else
          # caller logging 
          log_stack
          # EO
          log(sql, name) { @connection.query(sql) }
        end
      rescue ActiveRecord::StatementInvalid => exception
        if exception.message.split(":").first =~ /Packets out of order/
          raise ActiveRecord::StatementInvalid, "'Packets out of order'... bindings."
        else
          raise
        end
      end

      private

        def log_stack
          #If marazmuz will take over i would not like to spam logs in production
          return unless Rails.env == 'development'
          #Regex with rails directory path would be helpful in taking app stack trace only
          regexp = Regexp.new( Rails.root.to_s )
          res = ''
          caller.each_with_index{|x,i| 
          #We'll took only items containing Rails.root and we are not interested in current stack position, so skip i == 0
            res << "#{ '#'+i.to_s}:\t#{ x.sub(regexp,'') }\n" if x =~ regexp && i != 0 
          }
          Rails.logger.info( res ) unless res.blank?

        end

    end
  end
end

最后将以下输出写入日志

\#4:    /app/models/contact.rb:57:in `get_raw_cols'
\#5:    /app/models/contact.rb:65:in `stat_cols'
\#6:    /app/components/contacts_tab.rb:85:in `configuration'
\#19:   /app/views/welcome/index.html.erb:1:in    `_app_views_welcome_index_html_erb___736761216545810182_25680180__4434876849107960087'
  SQL (0.1ms)  SELECT `contacts`.`activity` FROM `contacts`

有人:

  • 知道具有相同功能的开箱即用的分析解决方案?
  • 我遇到过类似的问题以及你是如何解决的?

对上述代码的任何评论/改进也非常感谢。提前致谢。

ruby-on-rails debugging activerecord logging
2个回答
1
投票

我想我找到了一个完美的解决方案

https://github.com/lightyear/sql-logging

直到现在它对我来说都很完美。

请享用


0
投票

对于未来的Google员工:active_record_query_trace gem也可以做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.