Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created March 7, 2012 16:44
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ahoward/1994292 to your computer and use it in GitHub Desktop.
Save ahoward/1994292 to your computer and use it in GitHub Desktop.
completely k.i.s.s technique to do realtime log tailing in a live rails' app from the browser
### blogged @ http://dojo4.com/blog/easy-cheasy-realtime-log-tailing-in-a-rails-admin-view
### the su controller action
def logs
log = File.join(Rails.root, "log", "#{ Rails.env }.log")
@lines = `tail -1024 #{ log }`.split(/\n/).reverse
respond_to do |wants|
wants.html{ render }
wants.json{ render(:json => @lines) }
end
end
### the su view
<<-TEH_VIEW
<%= link_to 'Stop', 'javascript:void("stop")', :id => :stop %>
<%= link_to 'Start', 'javascript:void("start")', :id => :start, :style => 'display:none' %>
<br />
<hr />
<pre id='logs'>
<%= @lines.join("\n") %>
</pre>
<script>
jq(function(){
var start = jq('#start');
var stop = jq('#stop');
var milliseconds = 1024;
var id = null;
var update = function(){
id = setInterval(function(){
var lines = App.ajax('logs?silence=logger');
jq('#logs').html(lines.join("\n"));
}, milliseconds);
};
start.click(function(){ start.toggle(); stop.toggle(); update(); });
stop.click(function(){ stop.toggle(); start.toggle(); clearInterval(id); });
update();
});
</script>
TEH_VIEW
### the neat-o logger that let's us bludgeon the lame ass rails' logger for certain requests
# inspired by
#
# http://dennisreimann.de/blog/silencing-the-rails-log-on-a-per-action-basis/
#
# and
#
# http://stackoverflow.com/questions/6312448/how-to-disable-logging-of-asset-pipeline-sprockets-messages-in-rails-3-1
#
# file: ./config/initializers/silenceable_logger.rb
#
# then, in some crazy js polling action use
#
# ajax('/poll?silence=logger')
#
NullLogger = Logger.new('/dev/null')
Rails::Rack::Logger.class_eval do
def call_with_silenced_logger(env = {})
silence = (
env['QUERY_STRING'] =~ %r[silence=logger]iomx ||
env['PATH_INFO'] =~ %r[(^/assets\b)|(^/su/logs\b)]iomx
)
if silence
begin
a = Rails.logger
b = ActionController::Base.logger
Rails.logger = NullLogger
ActionController::Base.logger = NullLogger
call_without_silenced_logger(env)
ensure
Rails.logger = a
ActionController::Base.logger = b
end
else
call_without_silenced_logger(env)
end
end
alias_method_chain(:call, :silenced_logger)
end
Rails.application.assets.logger = NullLogger
### finally, the required configuration to use the above logger selectively
class Application < Rails::Application
config.autoload_paths += %w( lib app app/presenters )
require File.join(Rails.root, 'lib/silenceable_logger.rb')
config.middleware.swap(Rails::Rack::Logger, SilenceableLogger)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment