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.
We've designed the handle to be fully ambidexterous -- yes, your Acme Drinking Mug Klein Bottle fits either hand. Indeed, it's possible to hold it with both hands simultaneously. And since it has no preferred angular momentum vector, you can swish your drink either clockwise or counterclockwise.Found it on the acme klein bottle site.