| Index: third_party/psutil/examples/top.py
|
| diff --git a/third_party/psutil/examples/top.py b/third_party/psutil/examples/top.py
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..df6a480d3ff7ad7358cb7a903b5bb30c8644bfa1
|
| --- /dev/null
|
| +++ b/third_party/psutil/examples/top.py
|
| @@ -0,0 +1,202 @@
|
| +#!/usr/bin/env python
|
| +#
|
| +# $Id: top.py 1211 2011-10-28 19:58:18Z g.rodola $
|
| +#
|
| +# Copyright (c) 2009, Jay Loden, 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.
|
| +
|
| +"""
|
| +A clone of top / htop.
|
| +
|
| +Author: Giampaolo Rodola' <g.rodola@gmail.com>
|
| +"""
|
| +
|
| +import os
|
| +import sys
|
| +if os.name != 'posix':
|
| + sys.exit('platform not supported')
|
| +import time
|
| +import curses
|
| +import atexit
|
| +from datetime import datetime, timedelta
|
| +
|
| +import psutil
|
| +
|
| +
|
| +# --- curses stuff
|
| +def tear_down():
|
| + win.keypad(0)
|
| + curses.nocbreak()
|
| + curses.echo()
|
| + curses.endwin()
|
| +
|
| +win = curses.initscr()
|
| +atexit.register(tear_down)
|
| +curses.endwin()
|
| +lineno = 0
|
| +
|
| +def print_line(line, highlight=False):
|
| + """A thin wrapper around curses's addstr()."""
|
| + global lineno
|
| + try:
|
| + if highlight:
|
| + line += " " * (win.getmaxyx()[1] - len(line))
|
| + win.addstr(lineno, 0, line, curses.A_REVERSE)
|
| + else:
|
| + win.addstr(lineno, 0, line, 0)
|
| + except curses.error:
|
| + lineno = 0
|
| + win.refresh()
|
| + raise
|
| + else:
|
| + lineno += 1
|
| +# --- /curses stuff
|
| +
|
| +
|
| +def bytes2human(n):
|
| + """
|
| + >>> bytes2human(10000)
|
| + '9.8 K/s'
|
| + >>> bytes2human(100001221)
|
| + '95.4 M/s'
|
| + """
|
| + 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 = int(float(n) / prefix[s])
|
| + return '%s%s' % (value, s)
|
| + return "0B"
|
| +
|
| +procs = [p for p in psutil.process_iter()] # the current process list
|
| +
|
| +def poll(interval):
|
| + # add new processes to procs list; processes which have gone
|
| + # in meantime will be removed from the list later
|
| + cpids = [p.pid for p in procs]
|
| + for p in psutil.process_iter():
|
| + if p.pid not in cpids:
|
| + procs.append(p)
|
| +
|
| + # sleep some time
|
| + time.sleep(interval)
|
| +
|
| + procs_status = {}
|
| + # then retrieve the same info again
|
| + for p in procs[:]:
|
| + try:
|
| + p._username = p.username
|
| + p._nice = p.nice
|
| + p._meminfo = p.get_memory_info()
|
| + p._mempercent = p.get_memory_percent()
|
| + p._cpu_percent = p.get_cpu_percent(interval=0)
|
| + p._cpu_times = p.get_cpu_times()
|
| + p._name = p.name
|
| + try:
|
| + procs_status[str(p.status)] += 1
|
| + except KeyError:
|
| + procs_status[str(p.status)] = 1
|
| + except psutil.NoSuchProcess:
|
| + procs.remove(p)
|
| +
|
| + # return processes sorted by CPU percent usage
|
| + processes = sorted(procs, key=lambda p: p._cpu_percent, reverse=True)
|
| + return (processes, procs_status)
|
| +
|
| +def print_header(procs_status):
|
| + """Print system-related info, above the process list."""
|
| +
|
| + def get_dashes(perc):
|
| + dashes = "|" * int((float(perc) / 10 * 4))
|
| + empty_dashes = " " * (40 - len(dashes))
|
| + return dashes, empty_dashes
|
| +
|
| + # cpu usage
|
| + for lineno, perc in enumerate(psutil.cpu_percent(interval=0, percpu=True)):
|
| + dashes, empty_dashes = get_dashes(perc)
|
| + print_line(" CPU%-2s [%s%s] %5s%%" % (lineno, dashes, empty_dashes, perc))
|
| +
|
| + # physmem usage
|
| + phymem = psutil.phymem_usage()
|
| + dashes, empty_dashes = get_dashes(phymem.percent)
|
| + buffers = getattr(psutil, 'phymem_buffers', lambda: 0)()
|
| + cached = getattr(psutil, 'cached_phymem', lambda: 0)()
|
| + used = phymem.total - (phymem.free + buffers + cached)
|
| + line = " Mem [%s%s] %5s%% %6s/%s" % (dashes, empty_dashes,
|
| + phymem.percent,
|
| + str(used / 1024 / 1024) + "M",
|
| + str(phymem.total / 1024 / 1024) + "M")
|
| + print_line(line)
|
| +
|
| + # swap usage
|
| + vmem = psutil.virtmem_usage()
|
| + dashes, empty_dashes = get_dashes(vmem.percent)
|
| + line = " Swap [%s%s] %5s%% %6s/%s" % (dashes, empty_dashes,
|
| + vmem.percent,
|
| + str(vmem.used / 1024 / 1024) + "M",
|
| + str(vmem.total / 1024 / 1024) + "M")
|
| + print_line(line)
|
| +
|
| + # procesess number and status
|
| + st = []
|
| + for x, y in procs_status.iteritems():
|
| + if y:
|
| + st.append("%s=%s" % (x, y))
|
| + st.sort(key=lambda x: x[:3] in ('run', 'sle'), reverse=1)
|
| + print_line(" Processes: %s (%s)" % (len(procs), ' '.join(st)))
|
| + # load average, uptime
|
| + uptime = datetime.now() - datetime.fromtimestamp(psutil.BOOT_TIME)
|
| + av1, av2, av3 = os.getloadavg()
|
| + line = " Load average: %.2f %.2f %.2f Uptime: %s" \
|
| + % (av1, av2, av3, str(uptime).split('.')[0])
|
| + print_line(line)
|
| +
|
| +def refresh_window(procs, procs_status):
|
| + """Print results on screen by using curses."""
|
| + curses.endwin()
|
| + templ = "%-6s %-8s %4s %5s %5s %6s %4s %9s %2s"
|
| + win.erase()
|
| + header = templ % ("PID", "USER", "NI", "VIRT", "RES", "CPU%", "MEM%",
|
| + "TIME+", "NAME")
|
| + print_header(procs_status)
|
| + print_line("")
|
| + print_line(header, highlight=True)
|
| + for p in procs:
|
| + # TIME+ column shows process CPU cumulative time and
|
| + # is expressed as: mm:ss.ms
|
| + ctime = timedelta(seconds=sum(p._cpu_times))
|
| + ctime = "%s:%s.%s" % (ctime.seconds // 60 % 60,
|
| + str((ctime.seconds % 60)).zfill(2),
|
| + str(ctime.microseconds)[:2])
|
| + line = templ % (p.pid,
|
| + p._username[:8],
|
| + p._nice,
|
| + bytes2human(p._meminfo.vms),
|
| + bytes2human(p._meminfo.rss),
|
| + p._cpu_percent,
|
| + round(p._mempercent, 1),
|
| + ctime,
|
| + p._name,
|
| + )
|
| + try:
|
| + print_line(line)
|
| + except curses.error:
|
| + break
|
| + win.refresh()
|
| +
|
| +
|
| +def main():
|
| + try:
|
| + interval = 0
|
| + while 1:
|
| + args = poll(interval)
|
| + refresh_window(*args)
|
| + interval = 1
|
| + except (KeyboardInterrupt, SystemExit):
|
| + print
|
| +
|
| +if __name__ == '__main__':
|
| + main()
|
|
|