Skip to content

Instantly share code, notes, and snippets.

@msumit
Last active August 29, 2015 14:07
Show Gist options
  • Save msumit/710bb9e585048cfa0fb0 to your computer and use it in GitHub Desktop.
Save msumit/710bb9e585048cfa0fb0 to your computer and use it in GitHub Desktop.
List local memcached keys using Ruby
#!/usr/bin/env ruby
require 'rubygems'
require 'net/telnet'
require 'dalli'
require 'optparse'
options = {:host => 'localhost', :port => 11211}
option_parser = OptionParser.new do |opts|
opts.banner = "Usage: #{__FILE__} [-h server] [-p port] [-k cache_key] [-r regex] [-u key] [-d key] [-p regex] [-s]"
opts.on("--help", "Help") do |v|
puts opts.banner
exit
end
opts.on("-h HOST", "--host HOST", "memcache server ip or name") do |host|
options[:host] = host
end
opts.on("-p PORT", "--port PORT", "memcache server port") do |port|
options[:port] = port
end
opts.on("-k KEY", "--key KEY", "Value of a single key") do |key|
options[:key] = key
end
opts.on("-r REGEX", "--regex REGEX", "Regex matching against keys") do |regex|
options[:regex] = Regexp.new(regex)
end
opts.on("-s", "--stats", "Regex matching against keys") do |stats|
options[:stats] = stats
end
opts.on("-d KEY", "--del KEY", "Delete single key") do |key|
options[:del] = key
end
opts.on("-p KEY", "--prune KEY", "Deleting keys") do |key|
options[:prune] = Regexp.new(key)
end
opts.on("-u KEY", "--update KEY", "Update a key") do |key|
options[:update] = key
end
end
begin
option_parser.parse!
rescue OptionParser::ParseError
$stderr.print "Error: " + $! + "\nType --help to view correct options.\n"
exit
end
headings = %w(sno expires bytes cache_key value)
rows = []
dc = Dalli::Client.new("#{options[:host]}:#{options[:port]}")
if options[:key]
puts dc.get(options[:key])
exit
end
if options[:del]
puts (dc.delete(options[:del]) ? 'Success' : 'Failed')
exit
end
if options[:update]
if dc.get(options[:update])
puts "Please give new value for key #{options[:update]}"
val = gets.chomp
puts (dc.replace(options[:update], val) ? 'Success' : 'Failed')
else
puts "Key not found"
end
exit
end
if options[:stats]
hash = dc.stats["#{options[:host]}:#{options[:port]}"]
hash.each_pair{|k,v| puts "#{k} : #{v}"}
exit
end
begin
connection = Net::Telnet::new("Host" => options[:host], "Port" => options[:port], "Timeout" => 3)
rescue Errno::ECONNREFUSED
$stderr.print "Error: " + $! + "\n"
exit
end
matches = connection.cmd("String" => "stats items", "Match" => /^END/).scan(/STAT items:(\d+):number (\d+)/)
slabs = matches.inject([]) { |items, item| items << Hash[*['id','items'].zip(item).flatten]; items }
longest_key_len = 10
longest_val_len = 10
slabs.each do |slab|
connection.cmd("String" => "stats cachedump #{slab['id']} #{slab['items']}", "Match" => /^END/) do |c|
matches = c.scan(/^ITEM (.+?) \[(\d+) b; (\d+) s\]$/).each do |key_data|
cache_key, bytes, expires_time = key_data
if options[:prune] && cache_key.match(options[:prune])
puts "Successfully deleted key '#{cache_key}'" if dc.delete(cache_key)
elsif options[:regex].nil? or cache_key.match(options[:regex])
cache_val = dc.get(cache_key)
rows << [Time.at(expires_time.to_i), bytes, cache_key, cache_val]
longest_key_len = [longest_key_len,cache_key.length].max
longest_val_len = [longest_val_len,cache_val.to_s.length].max
end
end
end
end
if rows.length > 0 && options[:prune].nil?
row_format = %Q(|%4s | %30s | %12s | %-#{longest_key_len}s | %-#{longest_val_len}s |)
puts row_format%headings
rows.each_with_index{|row,i| puts row_format%row.unshift(i+1)}
end
connection.close
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment