Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rbradford/3d942ed57f6ca021ad7566ed749e308f to your computer and use it in GitHub Desktop.
Save rbradford/3d942ed57f6ca021ad7566ed749e308f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
#
# Author: Craig Chi <[email protected]>
#
import sys
import os
import getopt
from subprocess import check_output
mem_types = ["Private_Clean", "Private_Dirty", "Shared_Clean", "Shared_Dirty"]
def usage():
print """
usage: parse_smaps.py [-p process_name] [-t memory_type] [-h] [smaps_filename]
example: parse_smaps.py /proc/12424/smaps
parse_smaps.py -p smbd
parse_smaps.py -p smbd -t Pss
parse_smaps.py -p smbd -t Private (the line starts with "Private")
"""
def main():
try:
opts, args = getopt.getopt(sys.argv[1:], "x:p:t:ah", ["process-name=", "memory-type=", "exclude", "all", "help"])
except getopt.GetoptError as err:
print err
usage()
sys.exit(2)
ps_name = ""
mem_type = ""
for o, a in opts:
if o in ("-p", "--process-name"):
ps_name = a
elif o in ("-t", "--memory-type"):
mem_type = a
elif o in ("-x", "--exclude"):
exclude = a
else:
usage()
sys.exit(2)
if (len(args) == 0 and ps_name == "") or len(args) > 1:
usage()
sys.exit(2)
smaps_file = ""
if ps_name == "":
smaps_file = os.path.abspath(args[0])
else:
try:
pid = str(check_output(["pidof", ps_name])).strip().split()[0]
except:
print "pidof failed or no such process[{0}]".format(ps_name)
sys.exit(1)
smaps_file = "/proc/" + pid + "/smaps"
fileinfo = {}
with open(smaps_file, 'r') as smap:
for line in smap:
if '-' in line:
line_arr = line.split()
if len(line_arr) < 6:
filename = "[anonymous]"
else:
filename = line_arr[5].split('/').pop()
elif mem_type == "":
for idx, name in enumerate(mem_types):
if line.startswith(name):
if filename in fileinfo:
fileinfo[filename][idx] += int(line.split()[1])
else:
fileinfo[filename] = [0] * 4;
fileinfo[filename][idx] += int(line.split()[1])
elif line.lower().startswith(mem_type.lower()):
if filename in fileinfo:
fileinfo[filename] += int(line.split()[1])
else:
fileinfo[filename] = int(line.split()[1])
if exclude:
del fileinfo[exclude]
if mem_type == "":
arr = []
total = [0] * 4
for k, v in fileinfo.items():
arr.append((v, k))
total = list(map(sum, zip(total, v)))
arr.sort(cmp=lambda x,y: cmp(sum(y[0]), sum(x[0])))
print "==============================================================================="
print "{:^8} {:^8} {:^8} {:^8}".format(mem_types[0].split('_')[0], mem_types[1].split('_')[0], mem_types[2].split('_')[0], mem_types[3].split('_')[0])
print "{:^8} + {:^8} + {:^8} + {:^8} = {:^8} : library".format(mem_types[0].split('_')[1], mem_types[1].split('_')[1], mem_types[2].split('_')[1], mem_types[3].split('_')[1], "Total")
print "==============================================================================="
for tup in arr:
print "{:>5} kB + {:>5} kB + {:>5} kB + {:>5} kB = {:>5} kB : {:<}".format(tup[0][0], tup[0][1], tup[0][2], tup[0][3], sum(tup[0]), tup[1])
print "==============================================================================="
print "{:>5} kB + {:>5} kB + {:>5} kB + {:>5} kB = {:>5} kB : Total".format(total[0], total[1], total[2], total[3], sum(total))
else:
arr = []
total = 0
for k, v in fileinfo.items():
arr.append((v, k))
total += v
arr.sort(reverse=True)
for tup in arr:
print "{:>5} kB {:<}".format(tup[0], tup[1])
print "====================="
print "Total: {0} kB".format(total)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment