diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2016-02-09 13:21:16 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2016-02-09 13:21:16 +0100 |
commit | f0211e90a9c52e61fca2a197a894642f2dff74e7 (patch) | |
tree | 0ed9cb0cdbb98986d7629928291f58af7f1ff0b7 | |
parent | 5018d79a8980b7767370333108b4e98fb4ca44df (diff) | |
download | psutil-f0211e90a9c52e61fca2a197a894642f2dff74e7.tar.gz |
fix #762: add sripts/procsmem.py script.
-rw-r--r-- | HISTORY.rst | 1 | ||||
-rw-r--r-- | psutil/tests/test_misc.py | 5 | ||||
-rwxr-xr-x | scripts/procinfo.py | 8 | ||||
-rwxr-xr-x | scripts/procsmem.py | 80 |
4 files changed, 89 insertions, 5 deletions
diff --git a/HISTORY.rst b/HISTORY.rst index 1b1cf7e1..5be3772f 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -13,6 +13,7 @@ Bug tracker at https://github.com/giampaolo/psutil/issues - #755: Process.memory_percent() "memtype" parameter. - #758: tests now live in psutil namespace. - #760: expose OS constants (LINUX, OSX, etc.) +- #762: new sripts/procsmem.py script. **Bug fixes** diff --git a/psutil/tests/test_misc.py b/psutil/tests/test_misc.py index 45689a33..507abf94 100644 --- a/psutil/tests/test_misc.py +++ b/psutil/tests/test_misc.py @@ -392,6 +392,11 @@ class TestScripts(unittest.TestCase): def test_pmap(self): self.assert_stdout('pmap.py', args=str(os.getpid())) + @unittest.skipUnless(hasattr(psutil.Process, "memory_addrspace_info"), + "memory_addrspace_info() not supported") + def test_procsmem(self): + self.assert_stdout('procsmem.py') + @unittest.skipIf(ast is None, 'ast module not available on this python version') def test_killall(self): diff --git a/scripts/procinfo.py b/scripts/procinfo.py index bbb0b8e4..9990086f 100755 --- a/scripts/procinfo.py +++ b/scripts/procinfo.py @@ -58,9 +58,7 @@ def print_(a, b): fmt = '\x1b[1;32m%-17s\x1b[0m %s' % (a, b) else: fmt = '%-15s %s' % (a, b) - # python 2/3 compatibility layer - sys.stdout.write(fmt + '\n') - sys.stdout.flush() + print(fmt) def run(pid): @@ -125,12 +123,12 @@ def run(pid): for child in children: print_('', 'pid=%s name=%s' % (child.pid, child.name())) - if pinfo['open_files'] != ACCESS_DENIED: + if pinfo['open_files'] != ACCESS_DENIED and pinfo['open_files']: print_('open files', '') for file in pinfo['open_files']: print_('', 'fd=%s %s ' % (file.fd, file.path)) - if pinfo['threads']: + if pinfo['threads'] and len(pinfo['threads']) > 1: print_('running threads', '') for thread in pinfo['threads']: print_('', 'id=%s, user-time=%s, sys-time=%s' % ( diff --git a/scripts/procsmem.py b/scripts/procsmem.py new file mode 100755 index 00000000..bc2a79a2 --- /dev/null +++ b/scripts/procsmem.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +# Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +""" +Show detailed memory usage about all (querable) processes. + +Processes are sorted by their "USS" (Unique Set Size) memory, which is +probably the most representative metric for determining how much memory +is being used by a process. + +This is similar to "smem" cmdline utility on Linux: +https://www.selenic.com/smem/ +""" + +from __future__ import print_function +import sys + +import psutil + + +if not hasattr(psutil.Process, "memory_addrspace_info"): + sys.exit("platform not supported") + + +def convert_bytes(n): + symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') + prefix = {} + for i, s in enumerate(symbols): + prefix[s] = 1 << (i + 1) * 10 + for s in reversed(symbols): + if n >= prefix[s]: + value = float(n) / prefix[s] + return '%.1f%s' % (value, s) + return "%sB" % n + + +def main(): + ad_pids = [] + procs = [] + for p in psutil.process_iter(): + try: + mem_addrspace = p.memory_addrspace_info() + info = p.as_dict(attrs=["cmdline", "username", "memory_info"]) + except psutil.AccessDenied: + ad_pids.append(p.pid) + except psutil.NoSuchProcess: + pass + else: + p._uss = mem_addrspace.uss + if not p._uss: + continue + p._pss = getattr(mem_addrspace, "pss", "") + p._swap = getattr(mem_addrspace, "swap", "") + p._info = info + procs.append(p) + + procs.sort(key=lambda p: p._uss) + templ = "%-7s %-7s %-30s %7s %7s %7s %7s" + print(templ % ("PID", "User", "Cmdline", "USS", "PSS", "Swap", "RSS")) + print("=" * 78) + for p in procs: + line = templ % ( + p.pid, + p._info["username"][:7], + " ".join(p._info["cmdline"])[:30], + convert_bytes(p._uss), + convert_bytes(p._pss), + convert_bytes(p._swap), + convert_bytes(p._info['memory_info'].rss), + ) + print(line) + if ad_pids: + print("warning: access denied for %s pids" % (len(ad_pids)), + file=sys.stderr) + +if __name__ == '__main__': + sys.exit(main()) |