Created
December 30, 2011 11:07
-
-
Save nono/1539335 to your computer and use it in GitHub Desktop.
Revisions
-
nono created this gist
Dec 30, 2011 .There are no files selected for viewing
This file contains hidden or 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ #!/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 }