Created
May 7, 2020 10:37
-
-
Save rbradford/3d942ed57f6ca021ad7566ed749e308f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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