Skip to content

Instantly share code, notes, and snippets.

@joshmn
Last active September 18, 2015 18:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshmn/150686246b8e487bd987 to your computer and use it in GitHub Desktop.
Save joshmn/150686246b8e487bd987 to your computer and use it in GitHub Desktop.
ActiveAdmin Logs
Inspired by Gitlab's Admin Logs (app/controllers/admin/logs_controller.rb)
Probably should put things in lib. Put in one file for breviety.
# begin - put this in lib/my_rails_app/* and load it in your application.rb
module MyRailsApp
class Logger < ::Logger
def self.file_name
file_name_noext + '.log'
end
def self.error(message)
build.error(message)
end
def self.info(message)
build.info(message)
end
def self.read_latest
path = Rails.root.join("log", file_name)
self.build unless File.exist?(path)
tail_output, _ = Propertyprompt::Popen.popen(%W(tail -n 2000 #{path}))
tail_output.split("\n")
end
def self.read_latest_for(filename)
path = Rails.root.join("log", filename)
tail_output, _ = Propertyprompt::Popen.popen(%W(tail -n 2000 #{path}))
tail_output.split("\n")
end
def self.build
new(Rails.root.join("log", file_name))
end
end
end
module MyRailsApp
class AppLogger < MyRailsApp::Logger
def self.file_name_noext
'application'
end
def format_message(severity, timestamp, progname, msg)
"#{timestamp.to_s(:long)}: #{msg}\n"
end
end
end
module Propertyprompt
class ProductionLogger < MyRailsApp::Logger
def self.file_name_noext
'production'
end
end
end
module MyRailsApp
class DevelopmentLogger < MyRailsApp::Logger
def self.file_name_noext
'development'
end
end
end
require 'fileutils'
require 'open3'
module MyRailsApp
module Popen
extend self
def popen(cmd, path=nil)
unless cmd.is_a?(Array)
raise "System commands must be given as an array of strings"
end
path ||= Dir.pwd
vars = { "PWD" => path }
options = { chdir: path }
unless File.directory?(path)
FileUtils.mkdir_p(path)
end
@cmd_output = ""
@cmd_status = 0
Open3.popen3(vars, *cmd, options) do |stdin, stdout, stderr, wait_thr|
# We are not using stdin so we should close it, in case the command we
# are running waits for input.
stdin.close
@cmd_output << stdout.read
@cmd_output << stderr.read
@cmd_status = wait_thr.value.exitstatus
end
[@cmd_output, @cmd_status]
end
end
end
# end - put this in lib/my_rails_app/*
# app/admin/logs.rb
ActiveAdmin.register_page "Logs" do
content do
render 'show'
end
end
<style>
/* sorry for the blatent rip */
.file-holder {
border: 1px solid #e5e5e5;
margin-bottom: 1em;
}
.file-holder .file-title {
position: relative;
background: whitesmoke;
border-bottom: 1px solid #e5e5e5;
text-shadow: 0 1px 1px #fff;
margin: 0;
text-align: left;
padding: 10px 15px;
}
.file-holder .file-content.logs {
background: #eee;
max-height: 700px;
overflow-y: auto;
}
.file-holder .file-content.logs ol {
margin-left: 40px;
padding: 10px 0;
border-left: 1px solid #e5e5e5;
margin-bottom: 0;
background: white;
}
.file-holder .file-content.logs ol li {
color: #888;
}
.file-holder .file-content.logs ol li p {
margin: 0;
color: #333;
line-height: 24px;
padding-left: 10px;
}
</style>
<% loggers = [MyRailsApp::AppLogger, MyRailsApp::ProductionLogger, MyRailsApp::DevelopmentLogger] %>
<% # development logger for dev purposes %>
<% klass = loggers.first
if params[:log]
loggers.each do |log|
if log.file_name_noext == params[:log]
klass = log
break
end
end
end
%>
<div class="table_tools">
<ul class="scopes table_tools_segmented_control">
<% loggers.each do |l| %>
<li class="scope <%= 'selected' if klass == l %> ">
<a href="/admin/logs?log=<%=l.file_name_noext%>" class="table_tools_button">
<%=l.file_name_noext.capitalize%>
</a>
</li>
<% end %>
</ul>
</div>
<div class="file-holder">
<div class="file-title">
<i class="fa fa-file"></i>
<%= klass::file_name %>
<div style="float:right;"><a href="javascript:var objDiv = document.getElementById('log');objDiv.scrollTop = objDiv.scrollHeight;">Bottom</a></div>
</div>
<div class="file-content logs" id="log">
<ol>
<% klass.read_latest.each do |line| %>
<li>
<p>
<%= line %>
</p>
</li>
<% end %>
</ol>
</div>
</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment