Watching Your Logs From The Console

I’ve often wished there was a way to see the rails logs right inside the console window, instead of having to switch back and forth betweeh console and a “tail -f” process. It wasn’t hard to find an answer — Jamis Buck blogged about it back in 2007 — but it didn’t quite do all I was hoping for, so I ended up going a different route, which I think gives a more complete solution.

The solution that I saw on Jamis’ blog was to replace wholesale the rails logger:


ActiveRecord::Base.logger = Logger.new(STDOUT)

The problems with this are:
1) It must be done before any AR::Base logging is done, and
2) It cannot be undone.
(Both due to the logger object being cached)

For my needs, I’m interested in the logs for a particular method call, but I don’t really want to see all the logs, all the time. So, I wrote the code that follows (at the end of this post), and put it in my .irbrc file. It gets around the cached logger object by altering the logger, rather than trying to replace it. This allows me to turn it on or off mid-session. For example (from a personal side project):


>> wr = WeightRecord.first
=> #
... # More commands, which I don't care to see the logs from ...
>> wr.weight = 176
=> 176

>> show_log
=> nil
>> wr.save
SQL (0.000154) BEGIN
SQL (0.069810) SELECT `date` FROM `weight_records` WHERE (`weight_records`.date = '2007-10-28' AND `weight_records`.user_id = 1 AND `weight_records`.id
1)
WeightRecord Update (0.000688) UPDATE `weight_records` SET `updated_at` = '2009-03-16 01:04:08', `weight` = 176.0 WHERE `id` = 1
SQL (0.004874) COMMIT
=> true

>> hide_log
=> nil
... # More stuff I don't need to see the logs from...

(The “SELECT `date`” bit in the logs is because my model has: “validates_uniqueness_of :date, :scope => :user_id”)

The code:


def show_log
unless @log_buffer_size
@log_file = Rails.logger.instance_variable_get("@log")
@log_level = Rails.logger.level
@log_buffer_size = Rails.logger.auto_flushing
end
Rails.logger.flush
Rails.logger.instance_variable_set("@log", STDOUT)
Rails.logger.level = Logger::DEBUG
Rails.logger.auto_flushing = 1
nil
end

def hide_log
if @log_buffer_size
Rails.logger.instance_variable_set("@log", @log_file)
Rails.logger.level = @log_level
Rails.logger.auto_flushing = @log_buffer_size
end
nil
end

Published by

Patrick Schless

I'm a (mostly) ruby/rails developer, living in Chicago. I work at Braintree, and I have lots of side-projects.

One thought on “Watching Your Logs From The Console”

Leave a Reply

Your email address will not be published. Required fields are marked *