Skip to content

Instantly share code, notes, and snippets.

@samuelkadolph
Created January 12, 2011 16:55
Show Gist options
  • Save samuelkadolph/776450 to your computer and use it in GitHub Desktop.
Save samuelkadolph/776450 to your computer and use it in GitHub Desktop.
Ruby script to parse a rails log file and gist the error and source files.
require "cgi"
require "net/http"
require "uri"
def error(msg, code = -1)
puts(msg)
exit(code)
end
def add_gist_file(gist, number, name, content, ext = File.extname(name))
gist << "&" << CGI::escape("file_name[gistfile#{number}]") << "=" << CGI::escape(name)
gist << "&" << CGI::escape("file_contents[gistfile#{number}]") << "=" << CGI::escape(content)
gist << "&" << CGI::escape("file_ext[gistfile#{number}]") << "=" << CGI::escape(ext)
end
in_rails_app = File.exists?("script/rails") || File.exists?("script/server")
if in_rails_app
print("Rails environment to look at [development]: ")
environment = gets.strip
environment = "development" if environment.empty?
file = "log/#{environment}.log"
error("No log for environment `#{environment}' exists") unless File.exists?(file)
else
print("Rails log file to look at: ")
file = gets.strip
error("No log found at `#{file}'") unless File.exists?(file)
end
error_regexp = /^(\w+(::\w*)* \((.|[\n])*?\):(\n .*)*(\n .*)*)\n$/
log = File.read(file)
errors = log.scan(error_regexp)
error("No errors detected in `#{file}', are you sure it's the right file?") if errors.empty?
error_index = errors.count - 1
selected_error = nil
loop do
selected_error = errors[error_index][0]
puts("\nError (#{error_index + 1} of #{errors.count}):")
puts(selected_error.gsub(/^/, " "))
puts
can_go_back = error_index > 0
can_go_forward = error_index < errors.count - 1
actions = ["y|yes", "#1-#{errors.count}"]
actions << "p|prev" if can_go_back
actions << "n|next" if can_go_forward
print("Submit this error (#{actions.join(' ')}) [yes]: ")
action = gets.strip
case action
when /\A(y|yes)\Z/i, ""
break
when /\A-?\d+\Z/
index = action.to_i - 1
if (0...errors.count).include?(index) then error_index = index; else puts("Number is out of range") end
when /\A(p|prev)\Z/i
if can_go_back then error_index -= 1; else puts("Cannot go to previous error") end
when /\A(n|next)\Z/i
if can_go_forward then error_index += 1; else puts("Cannot go to next error") end
else
puts("Unknown action: #{action}")
end
end
if in_rails_app
print("\nInclude source of files in stack trace [yes]: ")
include_source = !(gets.strip =~ /\A(n|no)\Z/i)
end
gist, gist_files = "action_button=private", 1
add_gist_file(gist, gist_files, "_log", selected_error, ".txt") && gist_files += 1
if include_source
puts("\nIncluding source files:")
source_file_regexp = /^ (.*):\d+(:(.*))?$/
source_files = selected_error.scan(source_file_regexp)
puts(" none detected") if source_files.empty?
source_files.map { |f| f[0] }.uniq.each do |source_file|
begin
add_gist_file(gist, gist_files, source_file, File.read(source_file)) && gist_files += 1
puts(" + `#{source_file}'")
rescue
puts(" - `#{source_file}': unable to read file")
end
end
end
provider = Net::HTTP
begin
http = provider.new("gist.github.com", 443)
http.use_ssl = true
result = http.post("/gists.xml", gist)
url = result['Location']
if url == "https://gist.github.com/gists/new"
error("\nError creating gist")
else
puts("\nYour error gist is available at #{url}")
exit(0)
end
rescue SocketError
puts
print("Unable to connect to gist.github.com. Use a HTTP proxy [no]: ")
use_proxy = !!(gets.strip =~ /\A(y|yes)\Z/i)
if use_proxy
print(" Proxy host: ")
host = gets.strip
print(" Proxy port: ")
port = gets.strip.to_i
provider = Net::HTTP::Proxy(host, port)
retry
else
error("Cannot submit gist")
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment