xref: /3.0.3-GA/ep-engine/management/cbvdiff (revision 1de9ee71)
1#!/usr/bin/env python
2
3import optparse
4import socket
5import sys
6import os
7import subprocess
8
9import mc_bin_client
10
11def main():
12    parser = optparse.OptionParser(
13             usage="usage: %prog ip1:memcachedport1,ip2:memcachedport2",
14             version="%prog 1.0")
15    parser.add_option('-b', "--bucketName", dest="bucketName",
16                        help="name of bucket. default, if unspecified")
17    parser.add_option('-p', "--bucketPassword", dest="bucketPassword",
18                        help="password to authenticate to bucket")
19    stat_cmd = "vbucket-details"
20    vbstats = {}
21    states = {}
22    (options, args) = parser.parse_args()
23    if len(args) != 1:
24        parser.print_help()
25        sys.exit(-2)
26    cluster = args[0].split(',')
27    for node in cluster:
28        try:
29            host, port = node.split(':')
30            port = int(port)
31        except ValueError:
32            parser.print_help()
33            sys.exit(1)
34        # ----- Connect to memcached port ------
35        try:
36            mc = mc_bin_client.MemcachedClient(host, port)
37        except socket.gaierror, e:
38            print 'Source %s connection error: %s' % (host, e)
39            sys.exit(1)
40        if options.bucketName:
41            password = ""
42            if options.bucketPassword:
43                password = options.bucketPassword
44            try:
45                mc.sasl_auth_plain(options.bucketName, password)
46            except mc_bin_client.MemcachedError:
47                print "Authentication error for %s" % options.bucketName
48                sys.exit(2)
49        # ----- run cbstats to get the stats as a map ----
50        try:
51            stats = mc.stats(stat_cmd)
52        except Exception, e:
53            print "Stats '%s' not available from engine %s:%d"\
54                  % (stat_cmd, host, port)
55            sys.exit(2)
56        # ---- first pass over stats to hash the states of all vbuckets
57        for stat in stats.keys():
58            ignore, rest = stat.split('_', 1)
59            tokens = rest.split(':')
60            if len(tokens) == 1:
61                vbid = int(tokens[0])
62                states[vbid] = stats[stat]
63                if not vbid in vbstats:
64                    row = { stats[stat] : stats[stat]}
65                    col = { "state" : row }
66                    vbstats[vbid] = col
67
68        # ---- second pass over add stat, state => value
69        for stat in stats.keys():
70            ignore, rest = stat.split('_', 1)
71            tokens = rest.split(':')
72            if len(tokens) > 1:
73                vbid = int(tokens[0])
74                vbstat = tokens[1]
75                state = states[vbid]
76                if vbstat in vbstats[vbid]:
77                    vbstats[vbid][vbstat][state] = stats[stat]
78                else:
79                    row = {}
80                    row[state] = stats[stat]
81                    vbstats[vbid][vbstat] = row
82
83    # ------ Global Stats Collected ----------
84    item_count = 0
85    for vbid in vbstats:
86        active_count = int(vbstats[vbid]["num_items"]["active"])
87        replica_count = int(vbstats[vbid]["num_items"]["replica"])
88        if active_count != replica_count:
89           print "VBucket %d: active count %d != %d replica count \n" \
90                % (vbid, active_count, replica_count)
91        item_count += int(vbstats[vbid]["num_items"]["active"])
92    print "Active item count = %d\n" % item_count
93
94if __name__ == '__main__':
95    main()
96