Created
September 10, 2012 06:12
-
-
Save balepc/3689181 to your computer and use it in GitHub Desktop.
Redis response-time monitor
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 characters
#!/usr/bin/ruby | |
require 'rubygems' | |
require 'redis' | |
# Redis command processor. Author: Valery Vishnyakov | |
# | |
# Reports the following metrics | |
# | |
# CMD_PER_SEC Commands processed per second | |
# DUR_MIN Command duration minimum | |
# DUR_MAX Command duration maximum | |
# DUR_AVG Command average duration | |
# DUR_DEV Command duration standard deviation | |
# | |
# Usage: | |
# | |
# redis-cli -p 6379 MONITOR | head -n <number of commands> | ./redis-monitor.rb | |
# | |
# | |
module Enumerable | |
def sum | |
return self.inject(0){|acc,i|acc +i} | |
end | |
def average | |
return self.sum/self.length.to_f | |
end | |
def sample_variance | |
avg=self.average | |
sum=self.inject(0){|acc,i|acc +(i-avg)**2} | |
return(1/self.length.to_f*sum) | |
end | |
def standard_deviation | |
return Math.sqrt(self.sample_variance) | |
end | |
end | |
class StatCounter | |
RE = /^([\d\.]+)\s\(db\s(\d+)\)\s?"(\w+)"(\s"([^(\\)"]+)(\\)")?(\s(.+))?$/ | |
RE2 = /^([\d\.]+)\s?"(\w+)"(\s"([^(\\)"]+)(\\)")?(\s(.+))?$/ | |
attr_accessor :commands_processed | |
attr_accessor :skipped_lines | |
attr_accessor :start_ts | |
attr_accessor :last_ts | |
attr_accessor :times | |
def initialize() | |
self.commands_processed= 0 | |
self.skipped_lines= 0 | |
self.times= [] | |
end | |
def process_entry(time, database, command) | |
self.commands_processed += 1 | |
record_duration(time) | |
end | |
def record_duration(time) | |
ts = time.to_f * 1000 * 1000 # microseconds | |
if not self.start_ts | |
self.start_ts= ts | |
self.last_ts= ts | |
else | |
times << (ts - self.last_ts) | |
self.last_ts= ts | |
end | |
end | |
def process_line(str) | |
if (match = str.match(RE)) | |
process_entry(match[1], match[2], match[3]) | |
else | |
self.skipped_lines += 1 | |
end | |
end | |
def commands_per_second | |
total_time = (self.last_ts - self.start_ts) / (1000 * 1000) | |
(self.commands_processed / total_time).to_i | |
end | |
def print_stats | |
"CMD_PER_SEC:#{commands_per_second} DUR_MIN:#{times.min.to_i} DUR_MAX:#{times.max.to_i} DUR_AVG:#{times.average.to_i} DUR_DEV:#{times.standard_deviation.to_i}" | |
end | |
end | |
port = 6379 | |
host = '127.0.0.1' | |
samples = 1000 | |
until ARGV.empty? do | |
while (arg = ARGV.shift) | |
case arg | |
when /^--port=(.+)/ | |
port = $1 | |
when /^--host=(.+)/ | |
host = $1 | |
when /^--samples=(.+)/ | |
samples = $1.to_i | |
end | |
end | |
end | |
counter = StatCounter.new | |
redis = Redis.new(:host=>host, :port=>port) | |
idx = 0 | |
begin | |
redis.monitor do |line| | |
idx += 1 | |
counter.process_line(line.strip) | |
break if idx == samples | |
end | |
rescue Timeout::Error | |
end | |
#res.each_line do |line| | |
# counter.process_line(line) | |
#end | |
#while line = gets | |
# counter.process_line(line) | |
#end | |
puts counter.print_stats |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment