python/psutil/examples/top.py

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rwxr-xr-x

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 #!/usr/bin/env python
michael@0 2
michael@0 3 # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
michael@0 4 # Use of this source code is governed by a BSD-style license that can be
michael@0 5 # found in the LICENSE file.
michael@0 6
michael@0 7 """
michael@0 8 A clone of top / htop.
michael@0 9
michael@0 10 Author: Giampaolo Rodola' <g.rodola@gmail.com>
michael@0 11 """
michael@0 12
michael@0 13 import os
michael@0 14 import sys
michael@0 15 if os.name != 'posix':
michael@0 16 sys.exit('platform not supported')
michael@0 17 import time
michael@0 18 import curses
michael@0 19 import atexit
michael@0 20 from datetime import datetime, timedelta
michael@0 21
michael@0 22 import psutil
michael@0 23
michael@0 24
michael@0 25 # --- curses stuff
michael@0 26 def tear_down():
michael@0 27 win.keypad(0)
michael@0 28 curses.nocbreak()
michael@0 29 curses.echo()
michael@0 30 curses.endwin()
michael@0 31
michael@0 32 win = curses.initscr()
michael@0 33 atexit.register(tear_down)
michael@0 34 curses.endwin()
michael@0 35 lineno = 0
michael@0 36
michael@0 37 def print_line(line, highlight=False):
michael@0 38 """A thin wrapper around curses's addstr()."""
michael@0 39 global lineno
michael@0 40 try:
michael@0 41 if highlight:
michael@0 42 line += " " * (win.getmaxyx()[1] - len(line))
michael@0 43 win.addstr(lineno, 0, line, curses.A_REVERSE)
michael@0 44 else:
michael@0 45 win.addstr(lineno, 0, line, 0)
michael@0 46 except curses.error:
michael@0 47 lineno = 0
michael@0 48 win.refresh()
michael@0 49 raise
michael@0 50 else:
michael@0 51 lineno += 1
michael@0 52 # --- /curses stuff
michael@0 53
michael@0 54
michael@0 55 def bytes2human(n):
michael@0 56 """
michael@0 57 >>> bytes2human(10000)
michael@0 58 '9K'
michael@0 59 >>> bytes2human(100001221)
michael@0 60 '95M'
michael@0 61 """
michael@0 62 symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y')
michael@0 63 prefix = {}
michael@0 64 for i, s in enumerate(symbols):
michael@0 65 prefix[s] = 1 << (i+1)*10
michael@0 66 for s in reversed(symbols):
michael@0 67 if n >= prefix[s]:
michael@0 68 value = int(float(n) / prefix[s])
michael@0 69 return '%s%s' % (value, s)
michael@0 70 return "%sB" % n
michael@0 71
michael@0 72 def poll(interval):
michael@0 73 # sleep some time
michael@0 74 time.sleep(interval)
michael@0 75 procs = []
michael@0 76 procs_status = {}
michael@0 77 for p in psutil.process_iter():
michael@0 78 try:
michael@0 79 p.dict = p.as_dict(['username', 'get_nice', 'get_memory_info',
michael@0 80 'get_memory_percent', 'get_cpu_percent',
michael@0 81 'get_cpu_times', 'name', 'status'])
michael@0 82 try:
michael@0 83 procs_status[str(p.dict['status'])] += 1
michael@0 84 except KeyError:
michael@0 85 procs_status[str(p.dict['status'])] = 1
michael@0 86 except psutil.NoSuchProcess:
michael@0 87 pass
michael@0 88 else:
michael@0 89 procs.append(p)
michael@0 90
michael@0 91 # return processes sorted by CPU percent usage
michael@0 92 processes = sorted(procs, key=lambda p: p.dict['cpu_percent'], reverse=True)
michael@0 93 return (processes, procs_status)
michael@0 94
michael@0 95 def print_header(procs_status, num_procs):
michael@0 96 """Print system-related info, above the process list."""
michael@0 97
michael@0 98 def get_dashes(perc):
michael@0 99 dashes = "|" * int((float(perc) / 10 * 4))
michael@0 100 empty_dashes = " " * (40 - len(dashes))
michael@0 101 return dashes, empty_dashes
michael@0 102
michael@0 103 # cpu usage
michael@0 104 for cpu_num, perc in enumerate(psutil.cpu_percent(interval=0, percpu=True)):
michael@0 105 dashes, empty_dashes = get_dashes(perc)
michael@0 106 print_line(" CPU%-2s [%s%s] %5s%%" % (cpu_num, dashes, empty_dashes,
michael@0 107 perc))
michael@0 108 mem = psutil.virtual_memory()
michael@0 109 dashes, empty_dashes = get_dashes(mem.percent)
michael@0 110 used = mem.total - mem.available
michael@0 111 line = " Mem [%s%s] %5s%% %6s/%s" % (
michael@0 112 dashes, empty_dashes,
michael@0 113 mem.percent,
michael@0 114 str(int(used / 1024 / 1024)) + "M",
michael@0 115 str(int(mem.total / 1024 / 1024)) + "M"
michael@0 116 )
michael@0 117 print_line(line)
michael@0 118
michael@0 119 # swap usage
michael@0 120 swap = psutil.swap_memory()
michael@0 121 dashes, empty_dashes = get_dashes(swap.percent)
michael@0 122 line = " Swap [%s%s] %5s%% %6s/%s" % (
michael@0 123 dashes, empty_dashes,
michael@0 124 swap.percent,
michael@0 125 str(int(swap.used / 1024 / 1024)) + "M",
michael@0 126 str(int(swap.total / 1024 / 1024)) + "M"
michael@0 127 )
michael@0 128 print_line(line)
michael@0 129
michael@0 130 # processes number and status
michael@0 131 st = []
michael@0 132 for x, y in procs_status.items():
michael@0 133 if y:
michael@0 134 st.append("%s=%s" % (x, y))
michael@0 135 st.sort(key=lambda x: x[:3] in ('run', 'sle'), reverse=1)
michael@0 136 print_line(" Processes: %s (%s)" % (num_procs, ' '.join(st)))
michael@0 137 # load average, uptime
michael@0 138 uptime = datetime.now() - datetime.fromtimestamp(psutil.BOOT_TIME)
michael@0 139 av1, av2, av3 = os.getloadavg()
michael@0 140 line = " Load average: %.2f %.2f %.2f Uptime: %s" \
michael@0 141 % (av1, av2, av3, str(uptime).split('.')[0])
michael@0 142 print_line(line)
michael@0 143
michael@0 144 def refresh_window(procs, procs_status):
michael@0 145 """Print results on screen by using curses."""
michael@0 146 curses.endwin()
michael@0 147 templ = "%-6s %-8s %4s %5s %5s %6s %4s %9s %2s"
michael@0 148 win.erase()
michael@0 149 header = templ % ("PID", "USER", "NI", "VIRT", "RES", "CPU%", "MEM%",
michael@0 150 "TIME+", "NAME")
michael@0 151 print_header(procs_status, len(procs))
michael@0 152 print_line("")
michael@0 153 print_line(header, highlight=True)
michael@0 154 for p in procs:
michael@0 155 # TIME+ column shows process CPU cumulative time and it
michael@0 156 # is expressed as: "mm:ss.ms"
michael@0 157 if p.dict['cpu_times'] != None:
michael@0 158 ctime = timedelta(seconds=sum(p.dict['cpu_times']))
michael@0 159 ctime = "%s:%s.%s" % (ctime.seconds // 60 % 60,
michael@0 160 str((ctime.seconds % 60)).zfill(2),
michael@0 161 str(ctime.microseconds)[:2])
michael@0 162 else:
michael@0 163 ctime = ''
michael@0 164 if p.dict['memory_percent'] is not None:
michael@0 165 p.dict['memory_percent'] = round(p.dict['memory_percent'], 1)
michael@0 166 else:
michael@0 167 p.dict['memory_percent'] = ''
michael@0 168 if p.dict['cpu_percent'] is None:
michael@0 169 p.dict['cpu_percent'] = ''
michael@0 170 if p.dict['username']:
michael@0 171 username = p.dict['username'][:8]
michael@0 172 else:
michael@0 173 username = ""
michael@0 174 line = templ % (p.pid,
michael@0 175 username,
michael@0 176 p.dict['nice'],
michael@0 177 bytes2human(getattr(p.dict['memory_info'], 'vms', 0)),
michael@0 178 bytes2human(getattr(p.dict['memory_info'], 'rss', 0)),
michael@0 179 p.dict['cpu_percent'],
michael@0 180 p.dict['memory_percent'],
michael@0 181 ctime,
michael@0 182 p.dict['name'] or '',
michael@0 183 )
michael@0 184 try:
michael@0 185 print_line(line)
michael@0 186 except curses.error:
michael@0 187 break
michael@0 188 win.refresh()
michael@0 189
michael@0 190
michael@0 191 def main():
michael@0 192 try:
michael@0 193 interval = 0
michael@0 194 while 1:
michael@0 195 args = poll(interval)
michael@0 196 refresh_window(*args)
michael@0 197 interval = 1
michael@0 198 except (KeyboardInterrupt, SystemExit):
michael@0 199 pass
michael@0 200
michael@0 201 if __name__ == '__main__':
michael@0 202 main()

mercurial