Created
December 30, 2011 11:07
-
-
Save nono/1539335 to your computer and use it in GitHub Desktop.
Parse a Rails log file and send metrics to stathat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'net/http/persistent' | |
require 'uri' | |
require 'thread' | |
USAGE = <<EOS | |
Parse a Rails log file and send metrics to stathat | |
export EMAIL=email | |
export PREFIX=prefix | |
tail -f logfile | #{$0} | |
- logfile is the path to the Rails logfile (example: log/production.log) | |
- email is the email of the stathat account (mandatory) | |
- prefix is the prefix for the stats name (optional, blank by default) | |
WARNING: need ruby 1.9 and the net-http-persistent gem | |
EOS | |
$verbose = false | |
$exit = false | |
$uri = URI "http://api.stathat.com/ez" | |
$queue = Queue.new | |
$email = ENV['EMAIL'] | |
$prefix = ENV['PREFIX'] | |
if %w(-h --help).include?(ARGV[0]) || $email.nil? | |
puts USAGE | |
exit 0 | |
end | |
module REGEXP | |
PROCESSING = /^ Processing by (?<controller>\w+)#(?<action>\w+) as (?<format>\w+)$/ | |
COMPLETED = /^Completed (?<code>\d+) .* in (?<time>\d+)/ | |
MONGODB = /^MONGODB/ | |
RENDERED = /^Rendered (?<template>\w+)/ | |
STARTED = /^Started (?<verb>\w+) "(?<url>.+)" for (?<ip>[0-9.]+)/ | |
end | |
def count(stat, value) | |
stat = "#{$prefix} - #{stat}" if $prefix | |
$queue << [stat, value] | |
end | |
def incr(stat) | |
count stat, 1 | |
end | |
def processing(line) | |
data = line.match(REGEXP::PROCESSING) | |
return unless data | |
incr data['controller'] | |
incr "#{data['controller']}##{data['action']}" | |
incr "as #{data['format']}" | |
end | |
def completed(line) | |
data = line.match(REGEXP::COMPLETED) | |
return unless data | |
incr "Code #{data['code']}" | |
count "Completed in", data['time'].to_i | |
end | |
def mongodb(line) | |
incr "MongoDB" if line =~ REGEXP::MONGODB | |
end | |
def rendered(line) | |
data = line.match(REGEXP::RENDERED) | |
return unless data | |
incr "Rendering total" | |
incr "Rendering #{data['template']}" | |
end | |
def started(line) | |
data = line.match(REGEXP::STARTED) | |
return unless data | |
incr "Requests" | |
incr "#{data['verb']} requests" | |
incr "URL #{data['url']}" | |
incr "IP #{data['ip']}" | |
end | |
$threads = [] | |
8.times do | |
$threads << Thread.new do | |
http = Net::HTTP::Persistent.new $0 | |
until $exit | |
stat, count = *$queue.pop | |
post = Net::HTTP::Post.new $uri.path | |
post.set_form_data stat: stat, count: count, email: $email | |
http.request $uri, post | |
puts "count #{stat} -> #{count}" if $verbose | |
end | |
http.shutdown | |
end | |
end | |
ARGF.each do |line| | |
case line[0] | |
when ' ' then processing line | |
when 'C' then completed line | |
when 'M' then mongodb line | |
when 'R' then rendered line | |
when 'S' then started line | |
end | |
end | |
Thread.pass until $queue.empty? | |
$exit = true | |
$threads.each {|t| t.join } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment