Skip to content

Instantly share code, notes, and snippets.

@balepc
Created September 10, 2012 06:12
Show Gist options
  • Save balepc/3689181 to your computer and use it in GitHub Desktop.
Save balepc/3689181 to your computer and use it in GitHub Desktop.
Redis response-time monitor
#!/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