I've often wondered why there isn't automatic, browser-based log tailing in rails. It would be a really nice addition in a development-mode rails app to be able to go to a certain URL and see the log files updating. I usually suspect that someone has already done what I need, so, in this case, I asked my friend Lucas if he had ever heard of someone doing this and making it available (like on the Rails list). He said, "No, but you should do it! It would be super easy." So, this post is a quick overview of what I did to get browser-based rails log tailing while eating breakfast yesterday morning.
Here's my app/controllers/log_controller.rb:
class LogController < ApplicationController
def show
case params[:type]
when /dev/
@log_type = 'development'
when /prod/
@log_type = 'production'
else
render :text => "oops #{params[:type]}"
end
session[@log_type] ||= {}
log = File.open(RAILS_ROOT + "/log/#{@log_type}.log", 'r')
if session[@log_type][:seek]
log.pos = session[@log_type][:seek]
else
log.seek(-999, IO::SEEK_END)
end
@lines = log.readlines
session[@log_type][:seek] = log.pos
@periodic_call = !request.xhr?
render :layout => !request.xhr?
end
end
It's not that pretty, but it works. Basically, it accepts one parameter, "type", which tells which log file to open (production or development). Then, it opens the file, seeks to the position of the last update or SEEK_END - 999 (if there was no position previously stored in the session).
Ok, now onto the view. Here is app/views/log/show.rhtml:
<%= periodically_call_remote(:update => 'next_chunk',
:url => show_log_url(:type => @log_type),
:complete => visual_effect(:scroll_to, 'bottom'),
:frequency => 10) if @periodic_call %>
<pre> <%= @lines.join("") %> </pre>
<div id="next_chunk"> </div>
<div id="bottom"> </div>
You'll notice that we're just calling the same action (log/show), and repeatedly replacing the "next_chunk" DIV with the newest piece of the log file. The AJAX call will also scroll to the DIV called "bottom" each time it updates.
And that's it! Browser-based rails log tailing in less time than it takes to finish your Raisin Bran.
January 25th, 2006 at 03:18 AM You rock like Slayer, Doug.
January 25th, 2006 at 09:24 AM Nice work and in such a short time