diff options
Diffstat (limited to 'python/psutil/examples')
-rwxr-xr-x | python/psutil/examples/disk_usage.py | 62 | ||||
-rwxr-xr-x | python/psutil/examples/free.py | 41 | ||||
-rw-r--r-- | python/psutil/examples/ifconfig.py | 78 | ||||
-rwxr-xr-x | python/psutil/examples/iotop.py | 179 | ||||
-rwxr-xr-x | python/psutil/examples/killall.py | 32 | ||||
-rwxr-xr-x | python/psutil/examples/meminfo.py | 68 | ||||
-rwxr-xr-x | python/psutil/examples/netstat.py | 64 | ||||
-rwxr-xr-x | python/psutil/examples/nettop.py | 165 | ||||
-rwxr-xr-x | python/psutil/examples/pidof.py | 53 | ||||
-rwxr-xr-x | python/psutil/examples/pmap.py | 57 | ||||
-rwxr-xr-x | python/psutil/examples/process_detail.py | 167 | ||||
-rw-r--r-- | python/psutil/examples/ps.py | 81 | ||||
-rw-r--r-- | python/psutil/examples/pstree.py | 71 | ||||
-rwxr-xr-x | python/psutil/examples/top.py | 233 | ||||
-rwxr-xr-x | python/psutil/examples/who.py | 33 |
15 files changed, 1384 insertions, 0 deletions
diff --git a/python/psutil/examples/disk_usage.py b/python/psutil/examples/disk_usage.py new file mode 100755 index 0000000000..d8600a8c47 --- /dev/null +++ b/python/psutil/examples/disk_usage.py @@ -0,0 +1,62 @@ +#!/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. + +""" +List all mounted disk partitions a-la "df -h" command. + +$ python examples/disk_usage.py +Device Total Used Free Use % Type Mount +/dev/sdb3 18.9G 14.7G 3.3G 77% ext4 / +/dev/sda6 345.9G 83.8G 244.5G 24% ext4 /home +/dev/sda1 296.0M 43.1M 252.9M 14% vfat /boot/efi +/dev/sda2 600.0M 312.4M 287.6M 52% fuseblk /media/Recovery +""" + +import sys +import os +import psutil + + +def bytes2human(n): + # http://code.activestate.com/recipes/578019 + # >>> bytes2human(10000) + # '9.8K' + # >>> bytes2human(100001221) + # '95.4M' + 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(): + templ = "%-17s %8s %8s %8s %5s%% %9s %s" + print(templ % ("Device", "Total", "Used", "Free", "Use ", "Type", + "Mount")) + for part in psutil.disk_partitions(all=False): + if os.name == 'nt': + if 'cdrom' in part.opts or part.fstype == '': + # skip cd-rom drives with no disk in it; they may raise + # ENOENT, pop-up a Windows GUI error for a non-ready + # partition or just hang. + continue + usage = psutil.disk_usage(part.mountpoint) + print(templ % ( + part.device, + bytes2human(usage.total), + bytes2human(usage.used), + bytes2human(usage.free), + int(usage.percent), + part.fstype, + part.mountpoint)) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/python/psutil/examples/free.py b/python/psutil/examples/free.py new file mode 100755 index 0000000000..913ca58a4c --- /dev/null +++ b/python/psutil/examples/free.py @@ -0,0 +1,41 @@ +#!/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. + +""" +A clone of 'free' cmdline utility. + +$ python examples/free.py + total used free shared buffers cache +Mem: 10125520 8625996 1499524 0 349500 3307836 +Swap: 0 0 0 +""" + +import psutil + + +def main(): + virt = psutil.virtual_memory() + swap = psutil.swap_memory() + templ = "%-7s %10s %10s %10s %10s %10s %10s" + print(templ % ('', 'total', 'used', 'free', 'shared', 'buffers', 'cache')) + print(templ % ( + 'Mem:', + int(virt.total / 1024), + int(virt.used / 1024), + int(virt.free / 1024), + int(getattr(virt, 'shared', 0) / 1024), + int(getattr(virt, 'buffers', 0) / 1024), + int(getattr(virt, 'cached', 0) / 1024))) + print(templ % ( + 'Swap:', int(swap.total / 1024), + int(swap.used / 1024), + int(swap.free / 1024), + '', + '', + '')) + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/ifconfig.py b/python/psutil/examples/ifconfig.py new file mode 100644 index 0000000000..e7a436cc0a --- /dev/null +++ b/python/psutil/examples/ifconfig.py @@ -0,0 +1,78 @@ +#!/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. + +""" +A clone of 'ifconfig' on UNIX. + +$ python examples/ifconfig.py +lo (speed=0MB, duplex=?, mtu=65536, up=yes): + IPv4 address : 127.0.0.1 + broadcast : 127.0.0.1 + netmask : 255.0.0.0 + IPv6 address : ::1 + netmask : ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff + MAC address : 00:00:00:00:00:00 + broadcast : 00:00:00:00:00:00 + +wlan0 (speed=0MB, duplex=?, mtu=1500, up=yes): + IPv4 address : 10.0.3.1 + broadcast : 10.0.3.255 + netmask : 255.255.255.0 + IPv6 address : fe80::3005:adff:fe31:8698 + netmask : ffff:ffff:ffff:ffff:: + MAC address : 32:05:ad:31:86:98 + broadcast : ff:ff:ff:ff:ff:ff + +eth0 (speed=100MB, duplex=full, mtu=1500, up=yes): + IPv4 address : 192.168.1.2 + broadcast : 192.168.1.255 + netmask : 255.255.255.0 + IPv6 address : fe80::c685:8ff:fe45:641 + netmask : ffff:ffff:ffff:ffff:: + MAC address : c4:85:08:45:06:41 + broadcast : ff:ff:ff:ff:ff:ff +""" + +from __future__ import print_function +import socket + +import psutil + + +af_map = { + socket.AF_INET: 'IPv4', + socket.AF_INET6: 'IPv6', + psutil.AF_LINK: 'MAC', +} + +duplex_map = { + psutil.NIC_DUPLEX_FULL: "full", + psutil.NIC_DUPLEX_HALF: "half", + psutil.NIC_DUPLEX_UNKNOWN: "?", +} + + +def main(): + stats = psutil.net_if_stats() + for nic, addrs in psutil.net_if_addrs().items(): + if nic in stats: + print("%s (speed=%sMB, duplex=%s, mtu=%s, up=%s):" % ( + nic, stats[nic].speed, duplex_map[stats[nic].duplex], + stats[nic].mtu, "yes" if stats[nic].isup else "no")) + else: + print("%s:" % (nic)) + for addr in addrs: + print(" %-8s" % af_map.get(addr.family, addr.family), end="") + print(" address : %s" % addr.address) + if addr.broadcast: + print(" broadcast : %s" % addr.broadcast) + if addr.netmask: + print(" netmask : %s" % addr.netmask) + print("") + + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/iotop.py b/python/psutil/examples/iotop.py new file mode 100755 index 0000000000..16ac7fbf61 --- /dev/null +++ b/python/psutil/examples/iotop.py @@ -0,0 +1,179 @@ +#!/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. + +""" +A clone of iotop (http://guichaz.free.fr/iotop/) showing real time +disk I/O statistics. + +It works on Linux only (FreeBSD and OSX are missing support for IO +counters). +It doesn't work on Windows as curses module is required. + +Example output: + +$ python examples/iotop.py +Total DISK READ: 0.00 B/s | Total DISK WRITE: 472.00 K/s +PID USER DISK READ DISK WRITE COMMAND +13155 giampao 0.00 B/s 428.00 K/s /usr/bin/google-chrome-beta +3260 giampao 0.00 B/s 0.00 B/s bash +3779 giampao 0.00 B/s 0.00 B/s gnome-session --session=ubuntu +3830 giampao 0.00 B/s 0.00 B/s /usr/bin/dbus-launch +3831 giampao 0.00 B/s 0.00 B/s //bin/dbus-daemon --fork --print-pid 5 +3841 giampao 0.00 B/s 0.00 B/s /usr/lib/at-spi-bus-launcher +3845 giampao 0.00 B/s 0.00 B/s /bin/dbus-daemon +3848 giampao 0.00 B/s 0.00 B/s /usr/lib/at-spi2-core/at-spi2-registryd +3862 giampao 0.00 B/s 0.00 B/s /usr/lib/gnome-settings-daemon + +Author: Giampaolo Rodola' <g.rodola@gmail.com> +""" + +import atexit +import time +import sys +try: + import curses +except ImportError: + sys.exit('platform not supported') + +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 = float(n) / prefix[s] + return '%.2f %s/s' % (value, s) + return '%.2f B/s' % (n) + + +def poll(interval): + """Calculate IO usage by comparing IO statics before and + after the interval. + Return a tuple including all currently running processes + sorted by IO activity and total disks I/O activity. + """ + # first get a list of all processes and disk io counters + procs = [p for p in psutil.process_iter()] + for p in procs[:]: + try: + p._before = p.io_counters() + except psutil.Error: + procs.remove(p) + continue + disks_before = psutil.disk_io_counters() + + # sleep some time + time.sleep(interval) + + # then retrieve the same info again + for p in procs[:]: + try: + p._after = p.io_counters() + p._cmdline = ' '.join(p.cmdline()) + if not p._cmdline: + p._cmdline = p.name() + p._username = p.username() + except (psutil.NoSuchProcess, psutil.ZombieProcess): + procs.remove(p) + disks_after = psutil.disk_io_counters() + + # finally calculate results by comparing data before and + # after the interval + for p in procs: + p._read_per_sec = p._after.read_bytes - p._before.read_bytes + p._write_per_sec = p._after.write_bytes - p._before.write_bytes + p._total = p._read_per_sec + p._write_per_sec + + disks_read_per_sec = disks_after.read_bytes - disks_before.read_bytes + disks_write_per_sec = disks_after.write_bytes - disks_before.write_bytes + + # sort processes by total disk IO so that the more intensive + # ones get listed first + processes = sorted(procs, key=lambda p: p._total, reverse=True) + + return (processes, disks_read_per_sec, disks_write_per_sec) + + +def refresh_window(procs, disks_read, disks_write): + """Print results on screen by using curses.""" + curses.endwin() + templ = "%-5s %-7s %11s %11s %s" + win.erase() + + disks_tot = "Total DISK READ: %s | Total DISK WRITE: %s" \ + % (bytes2human(disks_read), bytes2human(disks_write)) + print_line(disks_tot) + + header = templ % ("PID", "USER", "DISK READ", "DISK WRITE", "COMMAND") + print_line(header, highlight=True) + + for p in procs: + line = templ % ( + p.pid, + p._username[:7], + bytes2human(p._read_per_sec), + bytes2human(p._write_per_sec), + p._cmdline) + try: + print_line(line) + except curses.error: + break + win.refresh() + + +def main(): + try: + interval = 0 + while True: + args = poll(interval) + refresh_window(*args) + interval = 1 + except (KeyboardInterrupt, SystemExit): + pass + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/killall.py b/python/psutil/examples/killall.py new file mode 100755 index 0000000000..b548e7bc57 --- /dev/null +++ b/python/psutil/examples/killall.py @@ -0,0 +1,32 @@ +#!/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. + +""" +Kill a process by name. +""" + +import os +import sys +import psutil + + +def main(): + if len(sys.argv) != 2: + sys.exit('usage: %s name' % __file__) + else: + NAME = sys.argv[1] + + killed = [] + for proc in psutil.process_iter(): + if proc.name() == NAME and proc.pid != os.getpid(): + proc.kill() + killed.append(proc.pid) + if not killed: + sys.exit('%s: no process found' % NAME) + else: + sys.exit(0) + +sys.exit(main()) diff --git a/python/psutil/examples/meminfo.py b/python/psutil/examples/meminfo.py new file mode 100755 index 0000000000..c463a3de4b --- /dev/null +++ b/python/psutil/examples/meminfo.py @@ -0,0 +1,68 @@ +#!/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. + +""" +Print system memory information. + +$ python examples/meminfo.py +MEMORY +------ +Total : 9.7G +Available : 4.9G +Percent : 49.0 +Used : 8.2G +Free : 1.4G +Active : 5.6G +Inactive : 2.1G +Buffers : 341.2M +Cached : 3.2G + +SWAP +---- +Total : 0B +Used : 0B +Free : 0B +Percent : 0.0 +Sin : 0B +Sout : 0B +""" + +import psutil + + +def bytes2human(n): + # http://code.activestate.com/recipes/578019 + # >>> bytes2human(10000) + # '9.8K' + # >>> bytes2human(100001221) + # '95.4M' + 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 pprint_ntuple(nt): + for name in nt._fields: + value = getattr(nt, name) + if name != 'percent': + value = bytes2human(value) + print('%-10s : %7s' % (name.capitalize(), value)) + + +def main(): + print('MEMORY\n------') + pprint_ntuple(psutil.virtual_memory()) + print('\nSWAP\n----') + pprint_ntuple(psutil.swap_memory()) + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/netstat.py b/python/psutil/examples/netstat.py new file mode 100755 index 0000000000..884622e9e3 --- /dev/null +++ b/python/psutil/examples/netstat.py @@ -0,0 +1,64 @@ +#!/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. + +""" +A clone of 'netstat -antp' on Linux. + +$ python examples/netstat.py +Proto Local address Remote address Status PID Program name +tcp 127.0.0.1:48256 127.0.0.1:45884 ESTABLISHED 13646 chrome +tcp 127.0.0.1:47073 127.0.0.1:45884 ESTABLISHED 13646 chrome +tcp 127.0.0.1:47072 127.0.0.1:45884 ESTABLISHED 13646 chrome +tcp 127.0.0.1:45884 - LISTEN 13651 GoogleTalkPlugi +tcp 127.0.0.1:60948 - LISTEN 13651 GoogleTalkPlugi +tcp 172.17.42.1:49102 127.0.0.1:19305 CLOSE_WAIT 13651 GoogleTalkPlugi +tcp 172.17.42.1:55797 127.0.0.1:443 CLOSE_WAIT 13651 GoogleTalkPlugi +... +""" + +import socket +from socket import AF_INET, SOCK_STREAM, SOCK_DGRAM + +import psutil + + +AD = "-" +AF_INET6 = getattr(socket, 'AF_INET6', object()) +proto_map = { + (AF_INET, SOCK_STREAM): 'tcp', + (AF_INET6, SOCK_STREAM): 'tcp6', + (AF_INET, SOCK_DGRAM): 'udp', + (AF_INET6, SOCK_DGRAM): 'udp6', +} + + +def main(): + templ = "%-5s %-30s %-30s %-13s %-6s %s" + print(templ % ( + "Proto", "Local address", "Remote address", "Status", "PID", + "Program name")) + proc_names = {} + for p in psutil.process_iter(): + try: + proc_names[p.pid] = p.name() + except psutil.Error: + pass + for c in psutil.net_connections(kind='inet'): + laddr = "%s:%s" % (c.laddr) + raddr = "" + if c.raddr: + raddr = "%s:%s" % (c.raddr) + print(templ % ( + proto_map[(c.family, c.type)], + laddr, + raddr or AD, + c.status, + c.pid or AD, + proc_names.get(c.pid, '?')[:15], + )) + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/nettop.py b/python/psutil/examples/nettop.py new file mode 100755 index 0000000000..7a8343ee4c --- /dev/null +++ b/python/psutil/examples/nettop.py @@ -0,0 +1,165 @@ +#!/usr/bin/env python +# +# $Id: iotop.py 1160 2011-10-14 18:50:36Z g.rodola@gmail.com $ +# +# 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. + +""" +Shows real-time network statistics. + +Author: Giampaolo Rodola' <g.rodola@gmail.com> + +$ python examples/nettop.py +----------------------------------------------------------- +total bytes: sent: 1.49 G received: 4.82 G +total packets: sent: 7338724 received: 8082712 + +wlan0 TOTAL PER-SEC +----------------------------------------------------------- +bytes-sent 1.29 G 0.00 B/s +bytes-recv 3.48 G 0.00 B/s +pkts-sent 7221782 0 +pkts-recv 6753724 0 + +eth1 TOTAL PER-SEC +----------------------------------------------------------- +bytes-sent 131.77 M 0.00 B/s +bytes-recv 1.28 G 0.00 B/s +pkts-sent 0 0 +pkts-recv 1214470 0 +""" + +import atexit +import time +import sys +try: + import curses +except ImportError: + sys.exit('platform not supported') + +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' + >>> bytes2human(100001221) + '95.4 M' + """ + 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 '%.2f %s' % (value, s) + return '%.2f B' % (n) + + +def poll(interval): + """Retrieve raw stats within an interval window.""" + tot_before = psutil.net_io_counters() + pnic_before = psutil.net_io_counters(pernic=True) + # sleep some time + time.sleep(interval) + tot_after = psutil.net_io_counters() + pnic_after = psutil.net_io_counters(pernic=True) + return (tot_before, tot_after, pnic_before, pnic_after) + + +def refresh_window(tot_before, tot_after, pnic_before, pnic_after): + """Print stats on screen.""" + global lineno + + # totals + print_line("total bytes: sent: %-10s received: %s" % ( + bytes2human(tot_after.bytes_sent), + bytes2human(tot_after.bytes_recv)) + ) + print_line("total packets: sent: %-10s received: %s" % ( + tot_after.packets_sent, tot_after.packets_recv)) + + # per-network interface details: let's sort network interfaces so + # that the ones which generated more traffic are shown first + print_line("") + nic_names = list(pnic_after.keys()) + nic_names.sort(key=lambda x: sum(pnic_after[x]), reverse=True) + for name in nic_names: + stats_before = pnic_before[name] + stats_after = pnic_after[name] + templ = "%-15s %15s %15s" + print_line(templ % (name, "TOTAL", "PER-SEC"), highlight=True) + print_line(templ % ( + "bytes-sent", + bytes2human(stats_after.bytes_sent), + bytes2human( + stats_after.bytes_sent - stats_before.bytes_sent) + '/s', + )) + print_line(templ % ( + "bytes-recv", + bytes2human(stats_after.bytes_recv), + bytes2human( + stats_after.bytes_recv - stats_before.bytes_recv) + '/s', + )) + print_line(templ % ( + "pkts-sent", + stats_after.packets_sent, + stats_after.packets_sent - stats_before.packets_sent, + )) + print_line(templ % ( + "pkts-recv", + stats_after.packets_recv, + stats_after.packets_recv - stats_before.packets_recv, + )) + print_line("") + win.refresh() + lineno = 0 + + +def main(): + try: + interval = 0 + while True: + args = poll(interval) + refresh_window(*args) + interval = 1 + except (KeyboardInterrupt, SystemExit): + pass + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/pidof.py b/python/psutil/examples/pidof.py new file mode 100755 index 0000000000..8692a3152b --- /dev/null +++ b/python/psutil/examples/pidof.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +# Copyright (c) 2009, Giampaolo Rodola', karthikrev. 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 'pidof' cmdline utility. +$ pidof python +1140 1138 1136 1134 1133 1129 1127 1125 1121 1120 1119 +""" + +from __future__ import print_function +import psutil +import sys + + +def pidof(pgname): + pids = [] + for proc in psutil.process_iter(): + # search for matches in the process name and cmdline + try: + name = proc.name() + except psutil.Error: + pass + else: + if name == pgname: + pids.append(str(proc.pid)) + continue + + try: + cmdline = proc.cmdline() + except psutil.Error: + pass + else: + if cmdline and cmdline[0] == pgname: + pids.append(str(proc.pid)) + + return pids + + +def main(): + if len(sys.argv) != 2: + sys.exit('usage: %s pgname' % __file__) + else: + pgname = sys.argv[1] + pids = pidof(pgname) + if pids: + print(" ".join(pids)) + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/pmap.py b/python/psutil/examples/pmap.py new file mode 100755 index 0000000000..7593777aef --- /dev/null +++ b/python/psutil/examples/pmap.py @@ -0,0 +1,57 @@ +#!/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. + +""" +A clone of 'pmap' utility on Linux, 'vmmap' on OSX and 'procstat -v' on BSD. +Report memory map of a process. + +$ python examples/pmap.py 32402 +pid=32402, name=hg +Address RSS Mode Mapping +0000000000400000 1200K r-xp /usr/bin/python2.7 +0000000000838000 4K r--p /usr/bin/python2.7 +0000000000839000 304K rw-p /usr/bin/python2.7 +00000000008ae000 68K rw-p [anon] +000000000275e000 5396K rw-p [heap] +00002b29bb1e0000 124K r-xp /lib/x86_64-linux-gnu/ld-2.17.so +00002b29bb203000 8K rw-p [anon] +00002b29bb220000 528K rw-p [anon] +00002b29bb2d8000 768K rw-p [anon] +00002b29bb402000 4K r--p /lib/x86_64-linux-gnu/ld-2.17.so +00002b29bb403000 8K rw-p /lib/x86_64-linux-gnu/ld-2.17.so +00002b29bb405000 60K r-xp /lib/x86_64-linux-gnu/libpthread-2.17.so +00002b29bb41d000 0K ---p /lib/x86_64-linux-gnu/libpthread-2.17.so +00007fff94be6000 48K rw-p [stack] +00007fff94dd1000 4K r-xp [vdso] +ffffffffff600000 0K r-xp [vsyscall] +... +""" + +import sys + +import psutil + + +def main(): + if len(sys.argv) != 2: + sys.exit('usage: pmap <pid>') + p = psutil.Process(int(sys.argv[1])) + print("pid=%s, name=%s" % (p.pid, p.name())) + templ = "%-16s %10s %-7s %s" + print(templ % ("Address", "RSS", "Mode", "Mapping")) + total_rss = 0 + for m in p.memory_maps(grouped=False): + total_rss += m.rss + print(templ % ( + m.addr.split('-')[0].zfill(16), + str(m.rss / 1024) + 'K', + m.perms, + m.path)) + print("-" * 33) + print(templ % ("Total", str(total_rss / 1024) + 'K', '', '')) + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/process_detail.py b/python/psutil/examples/process_detail.py new file mode 100755 index 0000000000..e20371aefe --- /dev/null +++ b/python/psutil/examples/process_detail.py @@ -0,0 +1,167 @@ +#!/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. + +""" +Print detailed information about a process. +Author: Giampaolo Rodola' <g.rodola@gmail.com> + +$ python examples/process_detail.py +pid 820 +name python +exe /usr/bin/python2.7 +parent 29613 (bash) +cmdline python examples/process_detail.py +started 2014-41-27 03:41 +user giampaolo +uids real=1000, effective=1000, saved=1000 +gids real=1000, effective=1000, saved=1000 +terminal /dev/pts/17 +cwd /ssd/svn/psutil +memory 0.1% (resident=10.6M, virtual=58.5M) +cpu 0.0% (user=0.09, system=0.0) +status running +niceness 0 +num threads 1 +I/O bytes-read=0B, bytes-written=0B +open files +running threads id=820, user-time=0.09, sys-time=0.0 +""" + +import datetime +import os +import socket +import sys + +import psutil + + +POSIX = os.name == 'posix' + + +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 print_(a, b): + if sys.stdout.isatty() and POSIX: + 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() + + +def run(pid): + ACCESS_DENIED = '' + try: + p = psutil.Process(pid) + pinfo = p.as_dict(ad_value=ACCESS_DENIED) + except psutil.NoSuchProcess as err: + sys.exit(str(err)) + + try: + parent = p.parent() + if parent: + parent = '(%s)' % parent.name() + else: + parent = '' + except psutil.Error: + parent = '' + if pinfo['create_time'] != ACCESS_DENIED: + started = datetime.datetime.fromtimestamp( + pinfo['create_time']).strftime('%Y-%m-%d %H:%M') + else: + started = ACCESS_DENIED + io = pinfo.get('io_counters', ACCESS_DENIED) + if pinfo['memory_info'] != ACCESS_DENIED: + mem = '%s%% (resident=%s, virtual=%s) ' % ( + round(pinfo['memory_percent'], 1), + convert_bytes(pinfo['memory_info'].rss), + convert_bytes(pinfo['memory_info'].vms)) + else: + mem = ACCESS_DENIED + children = p.children() + + print_('pid', pinfo['pid']) + print_('name', pinfo['name']) + print_('exe', pinfo['exe']) + print_('parent', '%s %s' % (pinfo['ppid'], parent)) + print_('cmdline', ' '.join(pinfo['cmdline'])) + print_('started', started) + print_('user', pinfo['username']) + if POSIX and pinfo['uids'] and pinfo['gids']: + print_('uids', 'real=%s, effective=%s, saved=%s' % pinfo['uids']) + if POSIX and pinfo['gids']: + print_('gids', 'real=%s, effective=%s, saved=%s' % pinfo['gids']) + if POSIX: + print_('terminal', pinfo['terminal'] or '') + print_('cwd', pinfo['cwd']) + print_('memory', mem) + print_('cpu', '%s%% (user=%s, system=%s)' % ( + pinfo['cpu_percent'], + getattr(pinfo['cpu_times'], 'user', '?'), + getattr(pinfo['cpu_times'], 'system', '?'))) + print_('status', pinfo['status']) + print_('niceness', pinfo['nice']) + print_('num threads', pinfo['num_threads']) + if io != ACCESS_DENIED: + print_('I/O', 'bytes-read=%s, bytes-written=%s' % ( + convert_bytes(io.read_bytes), + convert_bytes(io.write_bytes))) + if children: + print_('children', '') + for child in children: + print_('', 'pid=%s name=%s' % (child.pid, child.name())) + + if pinfo['open_files'] != ACCESS_DENIED: + print_('open files', '') + for file in pinfo['open_files']: + print_('', 'fd=%s %s ' % (file.fd, file.path)) + + if pinfo['threads']: + print_('running threads', '') + for thread in pinfo['threads']: + print_('', 'id=%s, user-time=%s, sys-time=%s' % ( + thread.id, thread.user_time, thread.system_time)) + if pinfo['connections'] not in (ACCESS_DENIED, []): + print_('open connections', '') + for conn in pinfo['connections']: + if conn.type == socket.SOCK_STREAM: + type = 'TCP' + elif conn.type == socket.SOCK_DGRAM: + type = 'UDP' + else: + type = 'UNIX' + lip, lport = conn.laddr + if not conn.raddr: + rip, rport = '*', '*' + else: + rip, rport = conn.raddr + print_('', '%s:%s -> %s:%s type=%s status=%s' % ( + lip, lport, rip, rport, type, conn.status)) + + +def main(argv=None): + if argv is None: + argv = sys.argv + if len(argv) == 1: + sys.exit(run(os.getpid())) + elif len(argv) == 2: + sys.exit(run(int(argv[1]))) + else: + sys.exit('usage: %s [pid]' % __file__) + +if __name__ == '__main__': + sys.exit(main()) diff --git a/python/psutil/examples/ps.py b/python/psutil/examples/ps.py new file mode 100644 index 0000000000..2b67bd18ff --- /dev/null +++ b/python/psutil/examples/ps.py @@ -0,0 +1,81 @@ +#!/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. + +""" +A clone of 'ps -aux' on UNIX. + +$ python examples/ps.py +... +""" + +import datetime +import os +import time + +import psutil + + +def main(): + today_day = datetime.date.today() + templ = "%-10s %5s %4s %4s %7s %7s %-13s %5s %7s %s" + attrs = ['pid', 'cpu_percent', 'memory_percent', 'name', 'cpu_times', + 'create_time', 'memory_info'] + if os.name == 'posix': + attrs.append('uids') + attrs.append('terminal') + print(templ % ("USER", "PID", "%CPU", "%MEM", "VSZ", "RSS", "TTY", + "START", "TIME", "COMMAND")) + for p in psutil.process_iter(): + try: + pinfo = p.as_dict(attrs, ad_value='') + except psutil.NoSuchProcess: + pass + else: + if pinfo['create_time']: + ctime = datetime.datetime.fromtimestamp(pinfo['create_time']) + if ctime.date() == today_day: + ctime = ctime.strftime("%H:%M") + else: + ctime = ctime.strftime("%b%d") + else: + ctime = '' + cputime = time.strftime("%M:%S", + time.localtime(sum(pinfo['cpu_times']))) + try: + user = p.username() + except KeyError: + if os.name == 'posix': + if pinfo['uids']: + user = str(pinfo['uids'].real) + else: + user = '' + else: + raise + except psutil.Error: + user = '' + if os.name == 'nt' and '\\' in user: + user = user.split('\\')[1] + vms = pinfo['memory_info'] and \ + int(pinfo['memory_info'].vms / 1024) or '?' + rss = pinfo['memory_info'] and \ + int(pinfo['memory_info'].rss / 1024) or '?' + memp = pinfo['memory_percent'] and \ + round(pinfo['memory_percent'], 1) or '?' + print(templ % ( + user[:10], + pinfo['pid'], + pinfo['cpu_percent'], + memp, + vms, + rss, + pinfo.get('terminal', '') or '?', + ctime, + cputime, + pinfo['name'].strip() or '?')) + + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/pstree.py b/python/psutil/examples/pstree.py new file mode 100644 index 0000000000..1bf8c9c049 --- /dev/null +++ b/python/psutil/examples/pstree.py @@ -0,0 +1,71 @@ +#!/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. + +""" +Similar to 'ps aux --forest' on Linux, prints the process list +as a tree structure. + +$ python examples/pstree.py +0 ? +|- 1 init +| |- 289 cgmanager +| |- 616 upstart-socket-bridge +| |- 628 rpcbind +| |- 892 upstart-file-bridge +| |- 907 dbus-daemon +| |- 978 avahi-daemon +| | `_ 979 avahi-daemon +| |- 987 NetworkManager +| | |- 2242 dnsmasq +| | `_ 10699 dhclient +| |- 993 polkitd +| |- 1061 getty +| |- 1066 su +| | `_ 1190 salt-minion... +... +""" + +from __future__ import print_function +import collections +import sys + +import psutil + + +def print_tree(parent, tree, indent=''): + try: + name = psutil.Process(parent).name() + except psutil.Error: + name = "?" + print(parent, name) + if parent not in tree: + return + children = tree[parent][:-1] + for child in children: + sys.stdout.write(indent + "|- ") + print_tree(child, tree, indent + "| ") + child = tree[parent][-1] + sys.stdout.write(indent + "`_ ") + print_tree(child, tree, indent + " ") + + +def main(): + # construct a dict where 'values' are all the processes + # having 'key' as their parent + tree = collections.defaultdict(list) + for p in psutil.process_iter(): + try: + tree[p.ppid()].append(p.pid) + except (psutil.NoSuchProcess, psutil.ZombieProcess): + pass + # on systems supporting PID 0, PID 0's parent is usually 0 + if 0 in tree and 0 in tree[0]: + tree[0].remove(0) + print_tree(min(tree), tree) + + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/top.py b/python/psutil/examples/top.py new file mode 100755 index 0000000000..7aebef1d42 --- /dev/null +++ b/python/psutil/examples/top.py @@ -0,0 +1,233 @@ +#!/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. + +""" +A clone of top / htop. + +Author: Giampaolo Rodola' <g.rodola@gmail.com> + +$ python examples/top.py + CPU0 [| ] 4.9% + CPU1 [||| ] 7.8% + CPU2 [ ] 2.0% + CPU3 [||||| ] 13.9% + Mem [||||||||||||||||||| ] 49.8% 4920M/9888M + Swap [ ] 0.0% 0M/0M + Processes: 287 (running=1 sleeping=286) + Load average: 0.34 0.54 0.46 Uptime: 3 days, 10:16:37 + +PID USER NI VIRT RES CPU% MEM% TIME+ NAME +------------------------------------------------------------ +989 giampaol 0 66M 12M 7.4 0.1 0:00.61 python +2083 root 0 506M 159M 6.5 1.6 0:29.26 Xorg +4503 giampaol 0 599M 25M 6.5 0.3 3:32.60 gnome-terminal +3868 giampaol 0 358M 8M 2.8 0.1 23:12.60 pulseaudio +3936 giampaol 0 1G 111M 2.8 1.1 33:41.67 compiz +4401 giampaol 0 536M 141M 2.8 1.4 35:42.73 skype +4047 giampaol 0 743M 76M 1.8 0.8 42:03.33 unity-panel-service +13155 giampaol 0 1G 280M 1.8 2.8 41:57.34 chrome +10 root 0 0B 0B 0.9 0.0 4:01.81 rcu_sched +339 giampaol 0 1G 113M 0.9 1.1 8:15.73 chrome +... +""" + +from datetime import datetime, timedelta +import atexit +import os +import time +import sys +try: + import curses +except ImportError: + sys.exit('platform not supported') + +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) + '9K' + >>> bytes2human(100001221) + '95M' + """ + 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 "%sB" % n + + +def poll(interval): + # sleep some time + time.sleep(interval) + procs = [] + procs_status = {} + for p in psutil.process_iter(): + try: + p.dict = p.as_dict(['username', 'nice', 'memory_info', + 'memory_percent', 'cpu_percent', + 'cpu_times', 'name', 'status']) + try: + procs_status[p.dict['status']] += 1 + except KeyError: + procs_status[p.dict['status']] = 1 + except psutil.NoSuchProcess: + pass + else: + procs.append(p) + + # return processes sorted by CPU percent usage + processes = sorted(procs, key=lambda p: p.dict['cpu_percent'], + reverse=True) + return (processes, procs_status) + + +def print_header(procs_status, num_procs): + """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 + percs = psutil.cpu_percent(interval=0, percpu=True) + for cpu_num, perc in enumerate(percs): + dashes, empty_dashes = get_dashes(perc) + print_line(" CPU%-2s [%s%s] %5s%%" % (cpu_num, dashes, empty_dashes, + perc)) + mem = psutil.virtual_memory() + dashes, empty_dashes = get_dashes(mem.percent) + used = mem.total - mem.available + line = " Mem [%s%s] %5s%% %6s/%s" % ( + dashes, empty_dashes, + mem.percent, + str(int(used / 1024 / 1024)) + "M", + str(int(mem.total / 1024 / 1024)) + "M" + ) + print_line(line) + + # swap usage + swap = psutil.swap_memory() + dashes, empty_dashes = get_dashes(swap.percent) + line = " Swap [%s%s] %5s%% %6s/%s" % ( + dashes, empty_dashes, + swap.percent, + str(int(swap.used / 1024 / 1024)) + "M", + str(int(swap.total / 1024 / 1024)) + "M" + ) + print_line(line) + + # processes number and status + st = [] + for x, y in procs_status.items(): + 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)" % (num_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, len(procs)) + print_line("") + print_line(header, highlight=True) + for p in procs: + # TIME+ column shows process CPU cumulative time and it + # is expressed as: "mm:ss.ms" + if p.dict['cpu_times'] is not None: + ctime = timedelta(seconds=sum(p.dict['cpu_times'])) + ctime = "%s:%s.%s" % (ctime.seconds // 60 % 60, + str((ctime.seconds % 60)).zfill(2), + str(ctime.microseconds)[:2]) + else: + ctime = '' + if p.dict['memory_percent'] is not None: + p.dict['memory_percent'] = round(p.dict['memory_percent'], 1) + else: + p.dict['memory_percent'] = '' + if p.dict['cpu_percent'] is None: + p.dict['cpu_percent'] = '' + if p.dict['username']: + username = p.dict['username'][:8] + else: + username = "" + line = templ % (p.pid, + username, + p.dict['nice'], + bytes2human(getattr(p.dict['memory_info'], 'vms', 0)), + bytes2human(getattr(p.dict['memory_info'], 'rss', 0)), + p.dict['cpu_percent'], + p.dict['memory_percent'], + ctime, + p.dict['name'] or '', + ) + try: + print_line(line) + except curses.error: + break + win.refresh() + + +def main(): + try: + interval = 0 + while True: + args = poll(interval) + refresh_window(*args) + interval = 1 + except (KeyboardInterrupt, SystemExit): + pass + +if __name__ == '__main__': + main() diff --git a/python/psutil/examples/who.py b/python/psutil/examples/who.py new file mode 100755 index 0000000000..b382bebfa3 --- /dev/null +++ b/python/psutil/examples/who.py @@ -0,0 +1,33 @@ +#!/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. + +""" +A clone of 'who' command; print information about users who are +currently logged in. + +$ python examples/who.py +giampaolo tty7 2014-02-23 17:25 (:0) +giampaolo pts/7 2014-02-24 18:25 (:192.168.1.56) +giampaolo pts/8 2014-02-24 18:25 (:0) +giampaolo pts/9 2014-02-27 01:32 (:0) +""" + +from datetime import datetime + +import psutil + + +def main(): + users = psutil.users() + for user in users: + print("%-15s %-15s %s (%s)" % ( + user.name, + user.terminal or '-', + datetime.fromtimestamp(user.started).strftime("%Y-%m-%d %H:%M"), + user.host)) + +if __name__ == '__main__': + main() |