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.

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

mercurial