Add filtering, and vss, avgpss, avguss, and avgrss for maps

This commit is contained in:
Matt Mackall 2009-04-03 16:34:04 -05:00
commit 37261bad86

90
smem
View file

@ -32,16 +32,14 @@ def pidmaps(pid):
offset=int(f[2], 16), offset=int(f[2], 16),
device=f[3], inode=f[4], name=name) device=f[3], inode=f[4], name=name)
return maps if options.mapfilter:
f = {}
for m in maps:
if not filter(options.mapfilter, m, lambda x: maps[x]['name']):
f[m] = maps[m]
return f
def processtotals(pids): return maps
totals = {}
for pid in pids:
try:
totals[pid] = pidtotals(pid)
except:
continue
return totals
def sortmaps(totals, key): def sortmaps(totals, key):
l = [] l = []
@ -100,6 +98,9 @@ def username(uid):
_ucache[uid] = pwd.getpwuid(uid)[0] _ucache[uid] = pwd.getpwuid(uid)[0]
return _ucache[uid] return _ucache[uid]
def pidusername(pid):
return username(piduser(pid))
_gcache = {} _gcache = {}
def groupname(gid): def groupname(gid):
if gid not in _gcache: if gid not in _gcache:
@ -113,6 +114,15 @@ def showamount(a):
return "%.2f%%" % (102400.0 * a / totalmem()) return "%.2f%%" % (102400.0 * a / totalmem())
return a return a
def filter(opt, arg, *sources):
if not opt:
return False
for f in sources:
if re.search(opt, f(arg)):
return False
return True
def pidtotals(pid): def pidtotals(pid):
maps = pidmaps(pid) maps = pidmaps(pid)
t = dict(size=0, rss=0, pss=0, shared_clean=0, shared_dirty=0, t = dict(size=0, rss=0, pss=0, shared_clean=0, shared_dirty=0,
@ -130,8 +140,21 @@ def pidtotals(pid):
t['apss'] += maps[m].get('pss', 0) t['apss'] += maps[m].get('pss', 0)
t['avss'] += maps[m].get('size', 0) t['avss'] += maps[m].get('size', 0)
t['maps'] = len(maps) t['maps'] = len(maps)
return t return t
def processtotals(pids):
totals = {}
for pid in pids:
if (filter(options.processfilter, pid, pidname, pidcmd) or
filter(options.userfilter, pid, pidusername)):
continue
try:
totals[pid] = pidtotals(pid)
except:
continue
return totals
def showpids(): def showpids():
p = pids() p = pids()
pt = processtotals(p) pt = processtotals(p)
@ -139,7 +162,7 @@ def showpids():
def showuser(p): def showuser(p):
if options.numeric: if options.numeric:
return piduser(p) return piduser(p)
return username(piduser(p)) return pidusername(p)
fields = dict( fields = dict(
pid=('PID', lambda n: n, '% 5s', lambda x: len(p)), pid=('PID', lambda n: n, '% 5s', lambda x: len(p)),
@ -159,11 +182,14 @@ def showpids():
) )
columns = options.columns or 'pid user command swap uss pss rss' columns = options.columns or 'pid user command swap uss pss rss'
showtable(p, fields, columns.split(), options.sort or 'pss') showtable(pt.keys(), fields, columns.split(), options.sort or 'pss')
def maptotals(pids): def maptotals(pids):
totals = {} totals = {}
for pid in pids: for pid in pids:
if (filter(options.processfilter, pid, pidname, pidcmd) or
filter(options.userfilter, pid, pidusername)):
continue
try: try:
maps = pidmaps(pid) maps = pidmaps(pid)
for m in maps.iterkeys(): for m in maps.iterkeys():
@ -195,14 +221,24 @@ def showmaps():
+ pt[n]['private_dirty'], '% 8a', sum), + pt[n]['private_dirty'], '% 8a', sum),
rss=('RSS', lambda n: pt[n]['rss'], '% 8a', sum), rss=('RSS', lambda n: pt[n]['rss'], '% 8a', sum),
pss=('PSS', lambda n: pt[n]['pss'], '% 8a', sum), pss=('PSS', lambda n: pt[n]['pss'], '% 8a', sum),
vss=('VSS', lambda n: pt[n]['size'], '% 8a', sum),
avgpss=('AVGPSS', lambda n: int(1.0 * pt[n]['pss']/pt[n]['count']),
'% 8a', sum),
avguss=('AVGUSS', lambda n: int(1.0 * pt[n]['uss']/pt[n]['count']),
'% 8a', sum),
avgrss=('AVGRSS', lambda n: int(1.0 * pt[n]['rss']/pt[n]['count']),
'% 8a', sum),
) )
columns = options.columns or 'map count swap uss pss rss' columns = options.columns or 'map count swap uss avgpss pss rss'
showtable(pt.keys(), fields, columns.split(), options.sort or 'pss') showtable(pt.keys(), fields, columns.split(), options.sort or 'pss')
def usertotals(pids): def usertotals(pids):
totals = {} totals = {}
for pid in pids: for pid in pids:
if (filter(options.processfilter, pid, pidname, pidcmd) or
filter(options.userfilter, pid, pidusername)):
continue
try: try:
maps = pidmaps(pid) maps = pidmaps(pid)
except: except:
@ -227,10 +263,10 @@ def showusers():
p = pids() p = pids()
pt = usertotals(p) pt = usertotals(p)
def showuser(p): def showuser(u):
if options.numeric: if options.numeric:
return p return u
return username(p) return username(u)
fields = dict( fields = dict(
user=('User', showuser, '%-8s', None), user=('User', showuser, '%-8s', None),
@ -288,28 +324,40 @@ def showtable(rows, fields, columns, sort):
parser = optparse.OptionParser("%prog [options]") parser = optparse.OptionParser("%prog [options]")
parser.add_option("-H", "--no-header", action="store_true", parser.add_option("-H", "--no-header", action="store_true",
help="disable header line") help="disable header line")
parser.add_option("-n", "--numeric", action="store_true",
help="numeric output")
parser.add_option("-s", "--sort", type="str",
help="field to sort on")
parser.add_option("-t", "--totals", action="store_true",
help="show totals")
parser.add_option("-c", "--columns", type="str", parser.add_option("-c", "--columns", type="str",
help="columns to show") help="columns to show")
parser.add_option("-t", "--totals", action="store_true",
help="show totals")
parser.add_option("", "--realmem", type="str", parser.add_option("", "--realmem", type="str",
help="amount of physical RAM") help="amount of physical RAM")
parser.add_option("-m", "--mappings", action="store_true", parser.add_option("-m", "--mappings", action="store_true",
help="show mappings") help="show mappings")
parser.add_option("-u", "--users", action="store_true", parser.add_option("-u", "--users", action="store_true",
help="show users") help="show users")
parser.add_option("-P", "--processfilter", type="str",
help="process filter regex")
parser.add_option("-M", "--mapfilter", type="str",
help="map filter regex")
parser.add_option("-U", "--userfilter", type="str",
help="user filter regex")
parser.add_option("-n", "--numeric", action="store_true",
help="numeric output")
parser.add_option("-s", "--sort", type="str",
help="field to sort on")
parser.add_option("-r", "--reverse", action="store_true", parser.add_option("-r", "--reverse", action="store_true",
help="reverse sort") help="reverse sort")
parser.add_option("-p", "--percent", action="store_true", parser.add_option("-p", "--percent", action="store_true",
help="show percentage") help="show percentage")
parser.add_option("-k", "--abbreviate", action="store_true", parser.add_option("-k", "--abbreviate", action="store_true",
help="show unit suffixes") help="show unit suffixes")
defaults = {} defaults = {}
parser.set_defaults(**defaults) parser.set_defaults(**defaults)
(options, args) = parser.parse_args() (options, args) = parser.parse_args()