Abstract proc interface
This commit is contained in:
parent
d3d4c72f1f
commit
40b49768d6
1 changed files with 50 additions and 31 deletions
81
smem
81
smem
|
|
@ -1,6 +1,41 @@
|
|||
#!/usr/bin/python
|
||||
import re, os, sys, pwd, grp, optparse, errno
|
||||
|
||||
_ucache = {}
|
||||
_gcache = {}
|
||||
|
||||
class procdata(object):
|
||||
def pids(self):
|
||||
'''get a list of processes'''
|
||||
return [int(e) for e in os.listdir("/proc")
|
||||
if e.isdigit() and not iskernel(e)]
|
||||
def _read(self, f):
|
||||
return file('/proc/' + f).read()
|
||||
def _readlines(self, f):
|
||||
return self._read(f).splitlines(True)
|
||||
def mapdata(self, pid):
|
||||
return self._readlines('%s/smaps' % pid)
|
||||
def memdata(self):
|
||||
return self._readlines('meminfo')
|
||||
def pidname(self, pid):
|
||||
l = self._read('%d/stat' % pid)
|
||||
return l[l.find('(') + 1: l.find(')')]
|
||||
def pidcmd(self, pid):
|
||||
c = self._read('%s/cmdline' % pid)[:-1]
|
||||
return c.replace('\0', ' ')
|
||||
def piduser(self, pid):
|
||||
return os.stat('/proc/%d/cmdline' % pid).st_uid
|
||||
def pidgroup(self, pid):
|
||||
return os.stat('/proc/%d/cmdline' % pid).st_gid
|
||||
def username(self, uid):
|
||||
if uid not in _ucache:
|
||||
_ucache[uid] = pwd.getpwuid(uid)[0]
|
||||
return _ucache[uid]
|
||||
def groupname(self, gid):
|
||||
if gid not in _gcache:
|
||||
_gcache[gid] = pwd.getgrgid(gid)[0]
|
||||
return _gcache[gid]
|
||||
|
||||
_totalmem = 0
|
||||
def totalmem():
|
||||
global _totalmem
|
||||
|
|
@ -11,14 +46,10 @@ def totalmem():
|
|||
_totalmem = memory()['memtotal']
|
||||
return _totalmem
|
||||
|
||||
def pids():
|
||||
'''get a list of processes'''
|
||||
return [int(e) for e in os.listdir("/proc") if e.isdigit() and not iskernel(e)]
|
||||
|
||||
def pidmaps(pid):
|
||||
maps = {}
|
||||
start = None
|
||||
for l in file('/proc/%s/smaps' % pid):
|
||||
for l in src.mapdata(pid):
|
||||
f = l.split()
|
||||
if f[-1] == 'kB':
|
||||
maps[start][f[0][:-1].lower()] = int(f[1])
|
||||
|
|
@ -49,26 +80,12 @@ def sortmaps(totals, key):
|
|||
return [pid for pid,key in l]
|
||||
|
||||
def iskernel(pid):
|
||||
return pidcmd(pid) == ""
|
||||
|
||||
def pidname(pid):
|
||||
l = file('/proc/%d/stat' % pid).read()
|
||||
return l[l.find('(') + 1: l.find(')')]
|
||||
|
||||
def pidcmd(pid):
|
||||
c = file('/proc/%s/cmdline' % pid).read()[:-1]
|
||||
return c.replace('\0', ' ')
|
||||
|
||||
def piduser(pid):
|
||||
return os.stat('/proc/%d/cmdline' % pid).st_uid
|
||||
|
||||
def pidgroup(pid):
|
||||
return os.stat('/proc/%d/cmdline' % pid).st_gid
|
||||
return src.pidcmd(pid) == ""
|
||||
|
||||
def memory():
|
||||
t = {}
|
||||
f = re.compile('(\\S+):\\s+(\\d+) kB')
|
||||
for l in file('/proc/meminfo'):
|
||||
for l in src.memdata():
|
||||
m = f.match(l)
|
||||
if m:
|
||||
t[m.group(1).lower()] = int(m.group(2)) * 1024
|
||||
|
|
@ -99,7 +116,7 @@ def username(uid):
|
|||
return _ucache[uid]
|
||||
|
||||
def pidusername(pid):
|
||||
return username(piduser(pid))
|
||||
return username(src.piduser(pid))
|
||||
|
||||
_gcache = {}
|
||||
def groupname(gid):
|
||||
|
|
@ -146,7 +163,7 @@ def pidtotals(pid):
|
|||
def processtotals(pids):
|
||||
totals = {}
|
||||
for pid in pids:
|
||||
if (filter(options.processfilter, pid, pidname, pidcmd) or
|
||||
if (filter(options.processfilter, pid, src.pidname, src.pidcmd) or
|
||||
filter(options.userfilter, pid, pidusername)):
|
||||
continue
|
||||
try:
|
||||
|
|
@ -158,7 +175,7 @@ def processtotals(pids):
|
|||
return totals
|
||||
|
||||
def showpids():
|
||||
p = pids()
|
||||
p = src.pids()
|
||||
pt = processtotals(p)
|
||||
|
||||
def showuser(p):
|
||||
|
|
@ -169,8 +186,8 @@ def showpids():
|
|||
fields = dict(
|
||||
pid=('PID', lambda n: n, '% 5s', lambda x: len(p)),
|
||||
user=('User', showuser, '%-8s', lambda x: len(dict.fromkeys(x))),
|
||||
name=('Name', pidname, '%-24.24s', None),
|
||||
command=('Command', pidcmd, '%-27.27s', None),
|
||||
name=('Name', src.pidname, '%-24.24s', None),
|
||||
command=('Command', src.pidcmd, '%-27.27s', None),
|
||||
maps=('Maps',lambda n: pt[n]['maps'], '% 5s', sum),
|
||||
swap=('Swap',lambda n: pt[n]['swap'], '% 8a', sum),
|
||||
uss=('USS', lambda n: pt[n]['uss'], '% 8a', sum),
|
||||
|
|
@ -189,7 +206,7 @@ def showpids():
|
|||
def maptotals(pids):
|
||||
totals = {}
|
||||
for pid in pids:
|
||||
if (filter(options.processfilter, pid, pidname, pidcmd) or
|
||||
if (filter(options.processfilter, pid, src.pidname, src.pidcmd) or
|
||||
filter(options.userfilter, pid, pidusername)):
|
||||
continue
|
||||
try:
|
||||
|
|
@ -212,7 +229,7 @@ def maptotals(pids):
|
|||
return totals
|
||||
|
||||
def showmaps():
|
||||
p = pids()
|
||||
p = src.pids()
|
||||
pt = maptotals(p)
|
||||
|
||||
fields = dict(
|
||||
|
|
@ -238,7 +255,7 @@ def showmaps():
|
|||
def usertotals(pids):
|
||||
totals = {}
|
||||
for pid in pids:
|
||||
if (filter(options.processfilter, pid, pidname, pidcmd) or
|
||||
if (filter(options.processfilter, pid, src.pidname, src.pidcmd) or
|
||||
filter(options.userfilter, pid, pidusername)):
|
||||
continue
|
||||
try:
|
||||
|
|
@ -247,7 +264,7 @@ def usertotals(pids):
|
|||
continue
|
||||
except:
|
||||
raise
|
||||
user = piduser(pid)
|
||||
user = src.piduser(pid)
|
||||
if user not in totals:
|
||||
t = dict(size=0, rss=0, pss=0, shared_clean=0,
|
||||
shared_dirty=0, private_clean=0, count=0,
|
||||
|
|
@ -264,7 +281,7 @@ def usertotals(pids):
|
|||
return totals
|
||||
|
||||
def showusers():
|
||||
p = pids()
|
||||
p = src.pids()
|
||||
pt = usertotals(p)
|
||||
|
||||
def showuser(u):
|
||||
|
|
@ -364,6 +381,8 @@ defaults = {}
|
|||
parser.set_defaults(**defaults)
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
src = procdata()
|
||||
|
||||
try:
|
||||
if options.mappings:
|
||||
showmaps()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue