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 |
||
14612.2.7
by William Grant
scripts |
20 |
from lp.services.memcache.interfaces import IMemcacheClient |
14565.2.15
by Curtis Hovey
Moved canonical.launchpad.scripts __init__ to lp.services.scripts. |
21 |
from lp.services.scripts import execute_zcml_for_scripts |
9232.2.52
by Stuart Bishop
Report statistics from the configured memcached servers. |
22 |
|
23 |
# The interesting bits we pull from the memcached stats.
|
|
24 |
INTERESTING_KEYS = [ |
|
25 |
'cmd_set', # Number of sets. |
|
26 |
'get_hits', # Number of gets that hit. |
|
27 |
'get_misses', # Number of gets that missed. |
|
28 |
'evictions', # Objects evicted from memcached. |
|
29 |
'bytes_read', # Bytes read from memcached. |
|
30 |
'bytes_written', # Bytes written to memcached. |
|
31 |
]
|
|
32 |
||
33 |
||
34 |
def get_summary(all_raw_stats): |
|
35 |
"""Aggregate individual server statistics into a summary."""
|
|
36 |
totals = dict((key, 0) for key in INTERESTING_KEYS) |
|
37 |
for server, raw_stats in all_raw_stats: |
|
38 |
for key in INTERESTING_KEYS: |
|
39 |
totals[key] += int(raw_stats.get(key, 0)) |
|
40 |
return totals |
|
41 |
||
42 |
||
43 |
def print_stats(stats): |
|
44 |
"""Output human readable statistics."""
|
|
45 |
print dedent('''\ |
|
46 |
Sets: %(cmd_set)s |
|
47 |
Hits: %(get_hits)s |
|
48 |
Misses: %(get_misses)s |
|
49 |
Evictions: %(evictions)s |
|
50 |
Bytes read: %(bytes_read)s |
|
51 |
Bytes written: %(bytes_written)s |
|
52 |
''' % stats) |
|
53 |
||
54 |
||
55 |
def print_summary(all_raw_stats): |
|
56 |
"""Output the summary in a human readable format."""
|
|
57 |
summary = get_summary(all_raw_stats) |
|
58 |
print "Totals\n======\n" |
|
59 |
print_stats(summary) |
|
60 |
||
61 |
||
62 |
def print_full(all_raw_stats): |
|
63 |
"""Output stats for individual servers in a human readable format."""
|
|
64 |
for server, stats in all_raw_stats: |
|
65 |
print server |
|
66 |
print "="*len(server) |
|
67 |
print
|
|
68 |
print_stats(stats) |
|
69 |
||
70 |
||
71 |
def print_cricket(all_raw_stats): |
|
72 |
"""Output stats in cricket format for graphing."""
|
|
73 |
summary = get_summary(all_raw_stats) |
|
74 |
now = time.time() |
|
75 |
for key in INTERESTING_KEYS: |
|
76 |
print 'memcached_total_%s:%s@%d' % ( |
|
77 |
key, summary[key], now) |
|
78 |
for server, stats in all_raw_stats: |
|
79 |
# Convert the '127.0.0.1:11217 (1)' style server string to a
|
|
80 |
# cricket key.
|
|
81 |
server = server.split()[0].replace(':','_').replace('.','_') |
|
82 |
for key in INTERESTING_KEYS: |
|
83 |
print 'memcached_%s_%s:%s@%d' % ( |
|
84 |
server, key, stats[key], now) |
|
85 |
||
86 |
||
87 |
def main(): |
|
88 |
parser = OptionParser() |
|
89 |
parser.add_option( |
|
90 |
"-r", "--raw", action="store_true", default=False, |
|
91 |
help="Output full raw data") |
|
92 |
parser.add_option( |
|
93 |
"-f", "--full", action="store_true", default=False, |
|
94 |
help="Output individual memcached server stats.") |
|
95 |
parser.add_option( |
|
96 |
"-c", "--cricket", action="store_true", default=False, |
|
97 |
help="Output stats in cricket compatible format.") |
|
98 |
options, args = parser.parse_args() |
|
99 |
if len(args) > 0: |
|
100 |
parser.error("Too many arguments.") |
|
101 |
execute_zcml_for_scripts() |
|
102 |
all_raw_stats = getUtility(IMemcacheClient).get_stats() |
|
103 |
if options.raw: |
|
104 |
pprint(all_raw_stats) |
|
105 |
elif options.cricket: |
|
106 |
print_cricket(all_raw_stats) |
|
107 |
elif options.full: |
|
108 |
print_summary(all_raw_stats) |
|
109 |
print_full(all_raw_stats) |
|
110 |
else: |
|
111 |
print_summary(all_raw_stats) |
|
112 |
return 0 |
|
113 |
||
114 |
||
115 |
if __name__ == '__main__': |
|
116 |
sys.exit(main()) |