Compare commits

...

12 commits

Author SHA1 Message Date
Matt Mackall
f2f19203ee Added tag 1.5 for changeset 98273ce331bb 2015-05-15 12:54:48 -05:00
Oren Tirosh
8f2294477c py3: do not use "except Exception, e:" syntax
If catching the exception is done with "except Exception as e:" this
will work only from 2.6. To maintain backward compatibility with 2.4 I
have used sys.exc_info(). A bit of a wart, but it works.
2015-05-15 12:52:02 -05:00
Oren Tirosh
0deddadf88 py3: add () to print statements
It's a function call in 3.x and redundant parentheses around an
expression on 2.x. This works fine as long as all prints have just a
single argument. One print statement with two arguments was changed to
use % formatting instead.
2015-05-15 12:50:59 -05:00
Oren Tirosh
afc19f79b6 py3: stop using iterkeys() 2015-05-15 12:49:06 -05:00
Cybjit
272cb17cf9 smem: allow column auto-sizing 2014-11-18 20:01:16 -06:00
Cybjit
29fc357a31 showfields: complain about sets 2014-11-18 16:26:12 -06:00
Matt Mackall
02dabc0b86 rename filter to filters to make 2to3 happy 2014-07-15 01:33:26 -05:00
Matt Mackall
834dc815c8 switch file() to open() 2014-05-22 17:04:26 -05:00
Matt Mackall
966493301c Added tag 1.4 for changeset e143c8fdb6f5 2013-11-20 15:57:07 -05:00
Matt Mackall
02bda05e5b handle division by zero with no swap
Reported by Stefan Praszalowicz
2013-05-08 14:21:28 -05:00
Matt Mackall
9e788b26c6 drop unused import of grp 2013-04-22 17:21:03 -05:00
Matt Mackall
18a680345c Added tag 1.3 for changeset ee281c13f31d 2013-03-27 20:02:06 -07:00
2 changed files with 77 additions and 27 deletions

98
smem
View file

@ -8,7 +8,7 @@
# the GNU General Public License version 2 or later, incorporated # the GNU General Public License version 2 or later, incorporated
# herein by reference. # herein by reference.
import re, os, sys, pwd, grp, optparse, errno, tarfile import re, os, sys, pwd, optparse, errno, tarfile
warned = False warned = False
@ -21,7 +21,7 @@ class procdata(object):
def _list(self): def _list(self):
return os.listdir(self.source + "/proc") return os.listdir(self.source + "/proc")
def _read(self, f): def _read(self, f):
return file(self.source + '/proc/' + f).read() return open(self.source + '/proc/' + f).read()
def _readlines(self, f): def _readlines(self, f):
return self._read(f).splitlines(True) return self._read(f).splitlines(True)
def _stat(self, f): def _stat(self, f):
@ -170,7 +170,7 @@ def pidmaps(pid):
if options.mapfilter: if options.mapfilter:
f = {} f = {}
for m in maps: for m in maps:
if not filter(options.mapfilter, m, lambda x: maps[x]['name']): if not filters(options.mapfilter, m, lambda x: maps[x]['name']):
f[m] = maps[m] f[m] = maps[m]
return f return f
@ -222,10 +222,12 @@ def showamount(a, total):
if options.abbreviate: if options.abbreviate:
return units(a * 1024) return units(a * 1024)
elif options.percent: elif options.percent:
if total == 0:
return 'N/A'
return "%.2f%%" % (100.0 * a / total) return "%.2f%%" % (100.0 * a / total)
return a return a
def filter(opt, arg, *sources): def filters(opt, arg, *sources):
if not opt: if not opt:
return False return False
@ -238,7 +240,7 @@ 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,
private_clean=0, private_dirty=0, referenced=0, swap=0) private_clean=0, private_dirty=0, referenced=0, swap=0)
for m in maps.iterkeys(): for m in maps:
for k in t: for k in t:
t[k] += maps[m].get(k, 0) t[k] += maps[m].get(k, 0)
@ -250,8 +252,8 @@ def pidtotals(pid):
def processtotals(pids): def processtotals(pids):
totals = {} totals = {}
for pid in pids: for pid in pids:
if (filter(options.processfilter, pid, src.pidname, src.pidcmd) or if (filters(options.processfilter, pid, src.pidname, src.pidcmd) or
filter(options.userfilter, pid, pidusername)): filters(options.userfilter, pid, pidusername)):
continue continue
try: try:
p = pidtotals(pid) p = pidtotals(pid)
@ -299,13 +301,13 @@ def showpids():
def maptotals(pids): def maptotals(pids):
totals = {} totals = {}
for pid in pids: for pid in pids:
if (filter(options.processfilter, pid, src.pidname, src.pidcmd) or if (filters(options.processfilter, pid, src.pidname, src.pidcmd) or
filter(options.userfilter, pid, pidusername)): filters(options.userfilter, pid, pidusername)):
continue continue
try: try:
maps = pidmaps(pid) maps = pidmaps(pid)
seen = {} seen = {}
for m in maps.iterkeys(): for m in maps:
name = maps[m]['name'] name = maps[m]['name']
if name not in totals: if name not in totals:
t = dict(size=0, rss=0, pss=0, shared_clean=0, t = dict(size=0, rss=0, pss=0, shared_clean=0,
@ -364,8 +366,8 @@ def showmaps():
def usertotals(pids): def usertotals(pids):
totals = {} totals = {}
for pid in pids: for pid in pids:
if (filter(options.processfilter, pid, src.pidname, src.pidcmd) or if (filters(options.processfilter, pid, src.pidname, src.pidcmd) or
filter(options.userfilter, pid, pidusername)): filters(options.userfilter, pid, pidusername)):
continue continue
try: try:
maps = pidmaps(pid) maps = pidmaps(pid)
@ -381,7 +383,7 @@ def usertotals(pids):
else: else:
t = totals[user] t = totals[user]
for m in maps.iterkeys(): for m in maps:
for k in t: for k in t:
t[k] += maps[m].get(k, 0) t[k] += maps[m].get(k, 0)
@ -461,11 +463,44 @@ def showsystem():
showtable(range(len(l)), fields, columns.split(), options.sort or 'order') showtable(range(len(l)), fields, columns.split(), options.sort or 'order')
def showfields(fields, f): def showfields(fields, f):
if f != list: if type(f) in (list, set):
print "unknown field", f print("unknown fields: " + " ".join(f))
print "known fields:" else:
for l in sorted(fields.keys()): print("unknown field %s" % f)
print "%-8s %s" % (l, fields[l][-1]) print("known fields:")
for l in sorted(fields):
print("%-8s %s" % (l, fields[l][-1]))
def autosize(columns, fields, rows):
colsizes = {}
for c in columns:
sizes = [1]
if not options.no_header:
sizes.append(len(fields[c][0]))
if (options.abbreviate or options.percent) and 'a' in fields[c][2]:
sizes.append(7)
else:
for r in rows:
sizes.append(len(str(fields[c][1](r))))
colsizes[c] = max(sizes)
overflowcols = set(["command", "map"]) & set(columns)
if len(overflowcols) > 0:
overflowcol = overflowcols.pop()
totnoflow = sum(colsizes.values()) - colsizes[overflowcol]
try:
ttyrows, ttycolumns = os.popen('stty size', 'r').read().split()
ttyrows, ttycolumns = int(ttyrows), int(ttycolumns)
except:
ttyrows, ttycolumns = (24, 80)
maxflowcol = ttycolumns - totnoflow - len(columns)
maxflowcol = max(maxflowcol, 10)
colsizes[overflowcol] = min(colsizes[overflowcol], maxflowcol)
return colsizes
def showtable(rows, fields, columns, sort): def showtable(rows, fields, columns, sort):
header = "" header = ""
@ -484,11 +519,17 @@ def showtable(rows, fields, columns, sort):
mt = totalmem() mt = totalmem()
st = memory()['swaptotal'] st = memory()['swaptotal']
for n in columns: missing = set(columns) - set(fields)
if n not in fields: if len(missing) > 0:
showfields(fields, n) showfields(fields, missing)
sys.exit(-1) sys.exit(-1)
if options.autosize:
colsizes = autosize(columns, fields, rows)
else:
colsizes = {}
for n in columns:
f = fields[n][2] f = fields[n][2]
if 'a' in f: if 'a' in f:
if n == 'swap': if n == 'swap':
@ -498,6 +539,8 @@ def showtable(rows, fields, columns, sort):
f = f.replace('a', 's') f = f.replace('a', 's')
else: else:
formatter.append(lambda x: x) formatter.append(lambda x: x)
if n in colsizes:
f = re.sub(r"[0-9]+", str(colsizes[n]), f)
format += f + " " format += f + " "
header += f % fields[n][0] + " " header += f % fields[n][0] + " "
@ -516,10 +559,10 @@ def showtable(rows, fields, columns, sort):
return return
if not options.no_header: if not options.no_header:
print header print(header)
for k,r in l: for k,r in l:
print format % tuple([f(v) for f,v in zip(formatter, r)]) print(format % tuple([f(v) for f,v in zip(formatter, r)]))
if options.totals: if options.totals:
# totals # totals
@ -531,8 +574,8 @@ def showtable(rows, fields, columns, sort):
else: else:
t.append("") t.append("")
print "-" * len(header) print("-" * len(header))
print format % tuple([f(v) for f,v in zip(formatter, t)]) print(format % tuple([f(v) for f,v in zip(formatter, t)]))
def showpie(l, sort): def showpie(l, sort):
try: try:
@ -621,6 +664,8 @@ parser.add_option("-c", "--columns", type="str",
help="columns to show") help="columns to show")
parser.add_option("-t", "--totals", action="store_true", parser.add_option("-t", "--totals", action="store_true",
help="show totals") help="show totals")
parser.add_option("-a", "--autosize", action="store_true",
help="size columns to fit terminal size")
parser.add_option("-R", "--realmem", type="str", parser.add_option("-R", "--realmem", type="str",
help="amount of physical RAM") help="amount of physical RAM")
@ -680,7 +725,8 @@ try:
showsystem() showsystem()
else: else:
showpids() showpids()
except IOError, e: except IOError:
_, e, _ = sys.exc_info()
if e.errno == errno.EPIPE: if e.errno == errno.EPIPE:
pass pass
except KeyboardInterrupt: except KeyboardInterrupt:

4
smem.8
View file

@ -95,6 +95,10 @@ User filter regular expression.
.SS OUTPUT FORMATTING .SS OUTPUT FORMATTING
.TP
.B \-a, \-\-autosize
Size columns to fit terminal size.
.TP .TP
.BI "\-c " COLUMNS ", \-\-columns=" COLUMNS .BI "\-c " COLUMNS ", \-\-columns=" COLUMNS
Columns to show. Columns to show.