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