How To Track ActiveRecord Query Durations in Rails

With recent versions of Rails, you can subscribe to certain notifications that allow you to track various internal stats about your Rails app. In this post, I’ll show you how to track ActiveRecord query times.

This code is going to do two things. It is going to track the value of every query’s duration so that you know in general how your system is performing. It will also log the sql of any really slow queries to a log file so you can check to make sure you have the necessary indices. Mysql has had a slow log feature for years, but this is a database-agnostic way to do it in case you’re not using mysql. The code is also going to track the slow query occurrence so that you can get alerted when a lot of them suddenly appear. It will also only subscribe to the notification in production mode. Feel free to change the first line to test it in development mode.

The best time to subscribe to notifications is when your Rails app is initializing. Create a file in config/initializers named notifications.rb and put this code in it:

{% highlight ruby %} if Rails.env.production? slow_logfile = File.open(Rails.root.join(“log”, “slow.log”), ‘a’) slow_log = Logger.new(slow_logfile) slow_log.level = Logger::INFO

ActiveSupport::Notifications.subscribe "sql.active_record" do |name, start, finish, id, payload|
    if payload[:name] == "SQL"
        duration = (finish - start) * 1000
        StatHat::API.ez_post_value("rails sql query duration", "info@stathat.com", duration)

        if duration > 500
            slow_log.info("#{Time.now.to_formatted_s(:db)} slow query (#{duration.to_i}ms): #{payload[:sql]}")
            slow_logfile.flush
            StatHat::API.ez_post_count("rails slow sql query", "info@stathat.com", 1)
        end
    end
end

end {% endhighlight %}

Stay tuned for an upcoming post on other information you can track with the Rails notification subscriptions.


Comments? Send us a tweet.

Permalink:

Previous:
How to make an HTTP POST request in many languages
Next:
How To Track Rails Request Durations