-
-
Save ginjo/aaa4a4395fcdbbad3d29 to your computer and use it in GitHub Desktop.
Get structured array of hashes of memcached keys on multiple servers
This file contains 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/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