Skip to content

Instantly share code, notes, and snippets.

@bootleq
Created September 22, 2012 09:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bootleq/3765618 to your computer and use it in GitHub Desktop.
Save bootleq/3765618 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'rubygems'
require 'redis'
require 'active_support/core_ext/hash'
require 'optparse'
require 'yaml'
require 'pp'
options = {}.with_indifferent_access
opt = OptionParser.new
opt.banner = "Usage: redis-client [env] [options]"
opt.on('-f pattern', '-k pattern', '--key-filter=pattern', 'only monitor keys with [pattern]') {|v| options[:key_filter] = v}
opt.on('-F pattern', '-K pattern', '--key-ignore=pattern', 'do not monitor keys with [pattern]') {|v| options[:key_ignore] = v}
opt.parse!(ARGV)
env = ARGV.join(' ')
env = 'development' if env.blank?
config = YAML.load_file(File.expand_path('path/to/config/redis.yml', __FILE__))[env].try(:to_options)
redis = Redis.new(config)
redis_monitor = Redis.new(config)
puts "Redis at #{config.inspect}"
puts "key filter: #{options[:key_filter]}\n" if options.key?(:key_filter)
puts "\n"
Thread.abort_on_exception = true
@last_input = ''
@monitoring = true
begin
Thread.new do
loop do
begin
case s = STDIN.gets.to_s.chomp
when /\A(del|get|set|setex|rename|renamenx|grep) .+/, /\A(keys|flushdb|flushall|info|ping)/
cmd, params = s.scan(/(\S+)\s?(.+)?/).flatten
case cmd
when 'del'
pp redis.send(cmd.to_sym, *redis.keys(params))
when 'grep'
pp redis.keys.grep(Regexp.new(params))
else
pp redis.send(*([cmd.to_sym] + Array(params.try(:split, /\s+/))))
end
puts "\n"
when 'monitor', 'm'
puts "-- #{@monitoring ? 'stop' : 'resume'} MONITOR output --"
@monitoring = !@monitoring
when 'stop', 's'
puts '-- stop MONITOR output --'
@monitoring = false
when 'quit'
redis.quit
exit
else
unless s.blank?
if s =~ /[^[:print:]]/
puts "Last: #{@last_input}\n"
s = @last_input
else
puts "usage: m(onitor) | s(top) | del [pattern] | grep [pattern] | quit | other redis commands\n\n"
end
end
end
rescue RuntimeError, ArgumentError, RegexpError => e
puts "#{e.backtrace.first}: #{e.message} (#{e.class})\n\n"
end
@last_input = s unless s.blank?
end
end
redis_monitor.monitor { |line|
next unless @monitoring
scan = line.scan(%r(
(\d+\.\d+) # timestamp
\s
"(\w+)" # command
\s?
(.+)? # detail
)x)
puts "#{line}" && next if scan.empty?
timestamp, cmd, detail = scan.flatten
key = nil
case cmd
when 'get', 'keys'
key = detail
when 'set'
key, value = detail.split(' ', 2)
detail = "#{key} (length: #{value.size})"
when 'setex'
key, time, value= detail.split(' ', 3)
detail = "#{key} (length: #{value.size}) (expire: #{time[/\d+/].to_i})"
end
next if key && options[:key_filter].present? && !key.match(options[:key_filter])
puts "#{Time.at(timestamp.to_f).strftime('%T')} #{cmd} #{detail}\n"
}
rescue Interrupt
redis.quit
redis_monitor.quit
puts "\nbye"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment