在Rails中记录长时间运行的事务



我的生产Rails应用程序中出现了"Mysql2::错误:超过了锁定等待超时"错误,我正在寻求帮助,以调试哪个事务锁定表的时间过长。MySQL有一个"慢速查询"日志,但据我所知,没有慢速事务日志。

有没有一种方法可以直接从ActiveRecord记录事务需要多长时间的信息?

我的团队记录的慢事务如下:

lib/slow_transaction_logger.rb:中

module SlowTransactionLogger
  LOG_IF_SLOWER_THAN_SECONDS = ENV.fetch("LOG_TRANSACTIONS_SLOWER_THAN_SECONDS", "5").to_f
  def transaction(*args)
    start = Time.now
    value = super
    finish = Time.now
    duration = finish - start
    return value if duration <= LOG_IF_SLOWER_THAN_SECONDS
    backtrace = caller.
      select { |path| path.start_with?(Rails.root.to_s) }.
      reject { |row|
        row.include?("/gems/") ||
        row.include?("/app/middleware/") ||
        row.include?("/config/initializers/")
      }
    puts "slow_transaction_logger: duration=#{duration.round(2)} start=#{start.to_s.inspect} finish=#{finish.to_s.inspect} class=#{name} caller=#{backtrace.to_json}"
    value
  end
end

config/initializers/active_record.rb:中

class ActiveRecord::Base
  class << self
    prepend SlowTransactionLogger
  end
end

因此,默认情况下,在每个环境中,它记录事务的速度都低于5秒。

如果设置了LOG_TRANSACTIONS_SLOWER_THAN_SECONDS环境变量(例如在Heroku上),则可以调整该限制。

我们有意使用puts进行日志记录,因为它最终会出现在Heroku中的日志中,而且我们在开发和测试中也更容易看到它。但如果您愿意,可以随意使用Rails.logger

最新更新