bae4efd79327478976e5945cab03857fa8689bbc
[awesomized/libmemcached] / memcached / scripts / memcached-tool
1 #!/usr/bin/perl
2 #
3 # memcached-tool:
4 # stats/management tool for memcached.
5 #
6 # Author:
7 # Brad Fitzpatrick <brad@danga.com>
8 #
9 # License:
10 # public domain. I give up all rights to this
11 # tool. modify and copy at will.
12 #
13
14 use strict;
15 use IO::Socket::INET;
16
17 my $addr = shift;
18 my $mode = shift || "display";
19 my ($from, $to);
20
21 if ($mode eq "display") {
22 undef $mode if @ARGV;
23 } elsif ($mode eq "move") {
24 $from = shift;
25 $to = shift;
26 undef $mode if $from < 6 || $from > 17;
27 undef $mode if $to < 6 || $to > 17;
28 print STDERR "ERROR: parameters out of range\n\n" unless $mode;
29 } elsif ($mode eq 'dump') {
30 ;
31 } elsif ($mode eq 'stats') {
32 ;
33 } else {
34 undef $mode;
35 }
36
37 undef $mode if @ARGV;
38
39 die
40 "Usage: memcached-tool <host[:port] | /path/to/socket> [mode]\n
41 memcached-tool 10.0.0.5:11211 display # shows slabs
42 memcached-tool 10.0.0.5:11211 # same. (default is display)
43 memcached-tool 10.0.0.5:11211 stats # shows general stats
44 memcached-tool 10.0.0.5:11211 dump # dumps keys and values
45 " unless $addr && $mode;
46
47
48 my $sock;
49 if ($addr =~ m:/:) {
50 $sock = IO::Socket::UNIX->new(
51 Peer => $addr,
52 );
53 }
54 else {
55 $addr .= ':11211' unless $addr =~ /:\d+$/;
56
57 $sock = IO::Socket::INET->new(
58 PeerAddr => $addr,
59 Proto => 'tcp',
60 );
61 }
62 die "Couldn't connect to $addr\n" unless $sock;
63
64 if ($mode eq 'dump') {
65 my %items;
66 my $totalitems;
67
68 print $sock "stats items\r\n";
69
70 while (<$sock>) {
71 last if /^END/;
72 if (/^STAT items:(\d*):number (\d*)/) {
73 $items{$1} = $2;
74 $totalitems += $2;
75 }
76 }
77 print STDERR "Dumping memcache contents\n";
78 print STDERR " Number of buckets: " . scalar(keys(%items)) . "\n";
79 print STDERR " Number of items : $totalitems\n";
80
81 foreach my $bucket (sort(keys(%items))) {
82 print STDERR "Dumping bucket $bucket - " . $items{$bucket} . " total items\n";
83 print $sock "stats cachedump $bucket $items{$bucket}\r\n";
84 my %keyexp;
85 while (<$sock>) {
86 last if /^END/;
87 # return format looks like this
88 # ITEM foo [6 b; 1176415152 s]
89 if (/^ITEM (\S+) \[.* (\d+) s\]/) {
90 $keyexp{$1} = $2;
91 }
92 }
93
94 foreach my $k (keys(%keyexp)) {
95 print $sock "get $k\r\n";
96 my $response = <$sock>;
97 if ($response =~ /VALUE (\S+) (\d+) (\d+)/) {
98 my $flags = $2;
99 my $len = $3;
100 my $val;
101 read $sock, $val, $len;
102 print "add $k $flags $keyexp{$k} $len\r\n$val\r\n";
103 # get the END
104 $_ = <$sock>;
105 $_ = <$sock>;
106 }
107 }
108 }
109 exit;
110 }
111
112 if ($mode eq 'stats') {
113 my %items;
114
115 print $sock "stats\r\n";
116
117 while (<$sock>) {
118 last if /^END/;
119 chomp;
120 if (/^STAT\s+(\S*)\s+(.*)/) {
121 $items{$1} = $2;
122 }
123 }
124 printf ("#%-17s %5s %11s\n", $addr, "Field", "Value");
125 foreach my $name (sort(keys(%items))) {
126 printf ("%24s %12s\n", $name, $items{$name});
127
128 }
129 exit;
130 }
131
132 # display mode:
133
134 my %items; # class -> { number, age, chunk_size, chunks_per_page,
135 # total_pages, total_chunks, used_chunks,
136 # free_chunks, free_chunks_end }
137
138 print $sock "stats items\r\n";
139 my $max = 0;
140 while (<$sock>) {
141 last if /^END/;
142 if (/^STAT items:(\d+):(\w+) (\d+)/) {
143 $items{$1}{$2} = $3;
144 $max = $1;
145 }
146 }
147
148 print $sock "stats slabs\r\n";
149 while (<$sock>) {
150 last if /^END/;
151 if (/^STAT (\d+):(\w+) (\d+)/) {
152 $items{$1}{$2} = $3;
153 }
154 }
155
156 print " # Item_Size Max_age Pages Count Full? Evicted Evict_Time OOM\n";
157 foreach my $n (1..$max) {
158 my $it = $items{$n};
159 next if (0 == $it->{total_pages});
160 my $size = $it->{chunk_size} < 1024 ?
161 "$it->{chunk_size}B" :
162 sprintf("%.1fK", $it->{chunk_size} / 1024.0);
163 my $full = $it->{free_chunks_end} == 0 ? "yes" : " no";
164 printf("%3d %8s %9ds %7d %7d %7s %8d %8d %4d\n",
165 $n, $size, $it->{age}, $it->{total_pages},
166 $it->{number}, $full, $it->{evicted},
167 $it->{evicted_time}, $it->{outofmemory});
168 }
169