#!/usr/bin/python # # Script to demonstrate the usage of 'tshark' and calculating some statistics. # # Pass this script a .pcap[.gz] file which contains GlusterFS traffic, and the # total of transferred bytes per GlusterFS packet will be calculated. Some # things to keep in mind: # - only GlusterFS packets will be used (skipping setup/teardown of TCP) # - size from the RPC payload is used (not adding ../IP/TCP) # - the total includes both sent and received data # - all GlusterFS operations related to I/O are included # - the script is kept simple and contains little error checking # # Author: Niels de Vos # Date: Sat, 23 Feb 2013 # import sys import os if len(sys.argv) != 2: print "Usage: %s " % sys.argv[0] sys.exit(1) filename = sys.argv[1] tshark_command = "tshark -T fields -E header=y -E separator=, -r %s" % filename # dictionary with fieldnames and a function for convert the output fields = { "frame.number" : int, "rpc.repframe" : int, "rpc.fraglen" : int, "rpc.auth.uid" : str } filter = "glusterfs" tshark_command += " -e " + " -e ".join(fields.keys()) tshark_command += " '%s'" % (filter) # read the output from the tshark command output = os.popen(tshark_command) # header will contain the fields in the correct order header = list() # append all packets to a list packets = list() for line in output: # Bug in certain Wireshark versions causing extra line of output if line.startswith("libwireshark.so"): continue values = line.strip().split(",") if not header: header = values continue packet = dict() for (idx, val) in enumerate(values): # convert according to the function in fields if not val and fields[header[idx]] == int: packet[header[idx]] = 0 else: packet[header[idx]] = fields[header[idx]](val) packets.append(packet) # keep a list of packets that have been merged reap = list() # merge the reply with the call for p in packets: if p["rpc.repframe"]: for call in packets: if call["frame.number"] == p["rpc.repframe"]: call["rpc.fraglen"] += p["rpc.fraglen"] reap.append(p) break # remove all the replies that have been merged for p in reap: packets.remove(p) # create a list of uids and calculate the total traffic uids = dict() for p in packets: if p["rpc.auth.uid"] not in uids.keys(): uids[p["rpc.auth.uid"]] = 0 uids[p["rpc.auth.uid"]] += p["rpc.fraglen"] # print a table with the results print "%8s | UID" % ("bytes") print "---------+-----" for uid in uids.keys(): print "%8d | %s" % (uids[uid], uid)