10637.3.1
by Guilherme Salgado
Use the default python version instead of a hard-coded version |
1 |
#!/usr/bin/python -S
|
9232.2.52
by Stuart Bishop
Report statistics from the configured memcached servers. |
2 |
# Copyright 2010 Canonical Ltd. This software is licensed under the
|
3 |
# GNU Affero General Public License version 3 (see the file LICENSE).
|
|
4 |
||
5 |
"""Output memcached statistics."""
|
|
6 |
||
7 |
__metaclass__ = type |
|
8 |
__all__ = [] |
|
9 |
||
10 |
import _pythonpath |
|
11 |
||
12 |
from optparse import OptionParser |
|
13 |
from pprint import pprint |
|
14 |
import sys |
|
15 |
from textwrap import dedent |
|
16 |
import time |
|
17 |
||
18 |
from zope.component import getUtility |
|
19 |
||
20 |
from canonical.launchpad.scripts import execute_zcml_for_scripts |
|
21 |
from lp.services.memcache.interfaces import IMemcacheClient |
|
22 |
||
23 |
||
24 |
# The interesting bits we pull from the memcached stats.
|
|
25 |
INTERESTING_KEYS = [ |
|
26 |
'cmd_set', # Number of sets. |
|
27 |
'get_hits', # Number of gets that hit. |
|
28 |
'get_misses', # Number of gets that missed. |
|
29 |
'evictions', # Objects evicted from memcached. |
|
30 |
'bytes_read', # Bytes read from memcached. |
|
31 |
'bytes_written', # Bytes written to memcached. |
|
32 |
]
|
|
33 |
||
34 |
||
35 |
def get_summary(all_raw_stats): |
|
36 |
"""Aggregate individual server statistics into a summary."""
|
|
37 |
totals = dict((key, 0) for key in INTERESTING_KEYS) |
|
38 |
for server, raw_stats in all_raw_stats: |
|
39 |
for key in INTERESTING_KEYS: |
|
40 |
totals[key] += int(raw_stats.get(key, 0)) |
|
41 |
return totals |
|
42 |
||
43 |
||
44 |
def print_stats(stats): |
|
45 |
"""Output human readable statistics."""
|
|
46 |
print dedent('''\ |
|
47 |
Sets: %(cmd_set)s |
|
48 |
Hits: %(get_hits)s |
|
49 |
Misses: %(get_misses)s |
|
50 |
Evictions: %(evictions)s |
|
51 |
Bytes read: %(bytes_read)s |
|
52 |
Bytes written: %(bytes_written)s |
|
53 |
''' % stats) |
|
54 |
||
55 |
||
56 |
def print_summary(all_raw_stats): |
|
57 |
"""Output the summary in a human readable format."""
|
|
58 |
summary = get_summary(all_raw_stats) |
|
59 |
print "Totals\n======\n" |
|
60 |
print_stats(summary) |
|
61 |
||
62 |
||
63 |
def print_full(all_raw_stats): |
|
64 |
"""Output stats for individual servers in a human readable format."""
|
|
65 |
for server, stats in all_raw_stats: |
|
66 |
print server |
|
67 |
print "="*len(server) |
|
68 |
print
|
|
69 |
print_stats(stats) |
|
70 |
||
71 |
||
72 |
def print_cricket(all_raw_stats): |
|
73 |
"""Output stats in cricket format for graphing."""
|
|
74 |
summary = get_summary(all_raw_stats) |
|
75 |
now = time.time() |
|
76 |
for key in INTERESTING_KEYS: |
|
77 |
print 'memcached_total_%s:%s@%d' % ( |
|
78 |
key, summary[key], now) |
|
79 |
for server, stats in all_raw_stats: |
|
80 |
# Convert the '127.0.0.1:11217 (1)' style server string to a
|
|
81 |
# cricket key.
|
|
82 |
server = server.split()[0].replace(':','_').replace('.','_') |
|
83 |
for key in INTERESTING_KEYS: |
|
84 |
print 'memcached_%s_%s:%s@%d' % ( |
|
85 |
server, key, stats[key], now) |
|
86 |
||
87 |
||
88 |
def main(): |
|
89 |
parser = OptionParser() |
|
90 |
parser.add_option( |
|
91 |
"-r", "--raw", action="store_true", default=False, |
|
92 |
help="Output full raw data") |
|
93 |
parser.add_option( |
|
94 |
"-f", "--full", action="store_true", default=False, |
|
95 |
help="Output individual memcached server stats.") |
|
96 |
parser.add_option( |
|
97 |
"-c", "--cricket", action="store_true", default=False, |
|
98 |
help="Output stats in cricket compatible format.") |
|
99 |
options, args = parser.parse_args() |
|
100 |
if len(args) > 0: |
|
101 |
parser.error("Too many arguments.") |
|
102 |
execute_zcml_for_scripts() |
|
103 |
all_raw_stats = getUtility(IMemcacheClient).get_stats() |
|
104 |
if options.raw: |
|
105 |
pprint(all_raw_stats) |
|
106 |
elif options.cricket: |
|
107 |
print_cricket(all_raw_stats) |
|
108 |
elif options.full: |
|
109 |
print_summary(all_raw_stats) |
|
110 |
print_full(all_raw_stats) |
|
111 |
else: |
|
112 |
print_summary(all_raw_stats) |
|
113 |
return 0 |
|
114 |
||
115 |
||
116 |
if __name__ == '__main__': |
|
117 |
sys.exit(main()) |