Skip to content

Instantly share code, notes, and snippets.

@ginjo
Forked from bkimble/gist:1365005
Last active December 1, 2019 08:32
Show Gist options
  • Save ginjo/aaa4a4395fcdbbad3d29 to your computer and use it in GitHub Desktop.
Save ginjo/aaa4a4395fcdbbad3d29 to your computer and use it in GitHub Desktop.
Get structured array of hashes of memcached keys on multiple servers
#!/usr/bin/env ruby
# List all keys stored in memcache.
# Forked from bkimble's gist https://gist.github.com/bkimble/1365005
# Credit to Graham King at http://www.darkcoding.net/software/memcached-list-all-keys/ for the original article on how to get the data from memcache in the first place.
# Currently resides at https://gist.github.com/ginjo/aaa4a4395fcdbbad3d29
#
# This fork separates the server query code from results presentation.
# The primary function of this script is to return an array of hashes of
# key items from any number of provided memcached servers.
#
# Usage: items = Memcached.items '192.168.0.5', 'my.otherserver.com:11233', ...
#
# puts items.to_yaml
# =>
#
# - :id: '8'
# :expires: 2015-01-28 18:52:26.000000000 -08:00
# :bytes: '376'
# :name: training_active_dates
# :server: 192.168.55.1:11211
# - :id: '46'
# :expires: 2015-01-28 19:22:46.000000000 -08:00
# :bytes: '1973011'
# :name: test_upcoming_cache
# :server: 192.168.55.1:11211
# - :id: '6'
# :expires: 2015-01-28 21:50:33.000000000 -08:00
# :bytes: '185'
# :name: participant_active_countries
# :server: 192.168.55.2:11211
# - :id: '8'
# :expires: 2015-01-28 18:52:25.000000000 -08:00
# :bytes: '378'
# :name: training_active_locations
# :server: 192.168.55.2:11211
require 'net/telnet'
module Memcached
# Get array of hashes of cache items from all listed servers.
# Usage: Memcached.items 'my.server.com', 'my.otherserver.com:11233', ...
def self.items(*_servers)
servers = _servers.collect {|s| s.split(':')}
all_rows = servers.collect do |server|
server_rows = server_items(*server) do |slab_id, expires_time, bytes, cache_key, cache_key_length, host, port|
{:id=>slab_id, :expires=>expires_time, :bytes=>bytes, :name=>cache_key, :server=>[host,port].join(':')}
end
#puts "items#server_rows for #{server}"
#puts server_rows.to_s
server_rows
end.flatten(1)
#puts "items#all_rows for #{_servers}"
#puts all_rows.to_s
return all_rows
end
# Get array of item data for each key stored on a single server.
# Pass in a block to customize the results for each row.
def self.server_items(_host='host', _port=11211)
server_rows = []
host = Net::Telnet::new("Host" => _host, "Port" => _port, "Timeout" => 1)
matches = host.cmd("String" => "stats items", "Match" => /^END/).scan(/STAT items:(\d+):number (\d+)/)
#puts "server_items#matches for #{_host}:#{_port}"
#puts matches.to_s
slabs = matches.inject([]) { |items, item| items << Hash[*['id','items'].zip(item).flatten]; items }
longest_key_len = 0
#puts "server_items#slabs for #{_host}:#{_port}"
#puts slabs.to_s
slabs.each do |slab|
host.cmd("String" => "stats cachedump #{slab['id']} #{slab['items']}", "Match" => /^END/) do |row|
row.scan(/^ITEM (.+?) \[(\d+) b; (\d+) s\]$/).each do |key_data|
slab_id, cache_key, bytes, expires_time = [slab['id'], key_data[0], key_data[1].to_i, Time.at(key_data[2].to_i)]
row_data = [slab_id, expires_time, bytes, cache_key, cache_key.length, _host, _port]
server_rows << if block_given?
yield(*row_data)
else
row_data
end
end
end
end
host.close
rescue Exception
puts "Could not get memcache items from #{_host}:#{_port}"
ensure
#puts "server_items#server_rows for #{_host}:#{_port}"
#puts server_rows.to_s
return server_rows
end
# Print cache items for single server - just like the original script.
def self.print_server_items(*_server)
headings = %w(id expires bytes cache_key)
longest_key_len=0
rows = server_items(*_server) {|*row| longest_key_len = [longest_key_len,row[4]].max; row }
puts "LONGEST KEY: #{longest_key_len}"
puts "ROW: #{rows[0].inspect}"
row_format = %Q(|%8s | %28s | %12s | %-#{longest_key_len}s |)
#puts row_format%headings
#rows.each{|row| puts row_format%row}
end
# Get only key names from cache items on all servers.
def self.keys(*_servers)
self.items(*_servers).collect {|i| i[:name]}
end
end # Memcached
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment