off the stack

Gather metrics using psutil

2013-09-28 | python

Psutil is a nice python module, providing an interface for gathering system and process related metrics.

It can be easily installed from pypi using pip for example. After that, a straightforward import psutil is enough to load the library.

Then one can get CPU metrics:

In [2]: psutil.cpu_percent()
Out[2]: 15.0

In [3]: psutil.cpu_percent(percpu=True)
Out[3]: [30.0, 10.0, 18.2, 0.0]

In [4]: psutil.cpu_percent()
Out[4]: 5.1

In [5]: psutil.cpu_percent(percpu=True)
Out[5]: [10.0, 0.0, 18.2, 0.0]

In [6]: psutil.cpu_times_percent()
Out[6]: cpupercent(user=4.9, nice=0.0, system=2.4, idle=92.7)

Or look up some disk related information:

In [7]: psutil.disk_partitions()
Out[7]:
[partition(device='/dev/disk1s2', mountpoint='/', fstype='hfs', opts='rw,local,rootfs,dovolfs,journaled,multilabel'),
 partition(device='/dev/disk0s2', mountpoint='/Volumes/ssd', fstype='hfs', opts='rw,local,dovolfs,journaled,multilabel')]

In [8]: psutil.disk_usage('/')
Out[8]: usage(total=499248103424, used=131396407296, free=367589552128, percent=26.3)

In [9]: psutil.disk_usage('/Volumes/ssd')
Out[9]: usage(total=179701792768, used=170759176192, free=8942616576, percent=95.0)

In [10]: psutil.disk_io_counters()
Out[10]: iostat(read_count=4172348L, write_count=12281956L, read_bytes=111858322944L, write_bytes=305864595968L, read_time=41385667L, write_time=180848739L)

In [11]: psutil.disk_io_counters(perdisk=True)
Out[11]:
{'disk0': iostat(read_count=670192L, write_count=3086920L, read_bytes=15604282880L, write_bytes=107617389568L, read_time=300909L, write_time=2128735L),
 'disk1': iostat(read_count=3505289L, write_count=9208877L, read_bytes=96349457920L, write_bytes=198652195328L, read_time=41111034L, write_time=178839667L)}

Or some information on memory, networking and users:

In [12]: psutil.virtual_memory()
Out[12]: vmem(total=8589934592L, available=3214712832L, percent=62.6, used=8093507584L, free=495013888L, active=3913555968L, inactive=2719698944L, wired=1460252672L)

In [13]: psutil.swap_memory()
Out[13]: swap(total=7516192768L, used=6119391232L, free=1396801536L, percent=81.4, sin=129702862848L, sout=11307806720L)

In [14]: psutil.net_io_counters()
Out[14]: iostat(bytes_sent=4525121720L, bytes_recv=19433505221L, packets_sent=16177042L, packets_recv=21742202L, errin=0L, errout=0L, dropin=0L, dropout=0)

In [15]: psutil.net_io_counters(pernic=True)
Out[15]:
{'gif0': iostat(bytes_sent=0L, bytes_recv=0L, packets_sent=0L, packets_recv=0L, errin=0L, errout=0L, dropin=0L, dropout=0),
 'en0': iostat(bytes_sent=875356954L, bytes_recv=10604934990L, packets_sent=6271968L, packets_recv=10024643L, errin=0L, errout=0L, dropin=0L, dropout=0),
 'en1': iostat(bytes_sent=1010727303L, bytes_recv=6189533434L, packets_sent=6253953L, packets_recv=8066436L, errin=0L, errout=0L, dropin=0L, dropout=0),
 'lo0': iostat(bytes_sent=2639038387L, bytes_recv=2639038387L, packets_sent=3651139L, packets_recv=3651139L, errin=0L, errout=0L, dropin=0L, dropout=0),
 'p2p0': iostat(bytes_sent=0L, bytes_recv=0L, packets_sent=0L, packets_recv=0L, errin=0L, errout=0L, dropin=0L, dropout=0),
 'stf0': iostat(bytes_sent=0L, bytes_recv=0L, packets_sent=0L, packets_recv=0L, errin=0L, errout=0L, dropin=0L, dropout=0),
 'vboxnet0': iostat(bytes_sent=0L, bytes_recv=0L, packets_sent=0L, packets_recv=0L, errin=0L, errout=0L, dropin=0L, dropout=0),
 'fw0': iostat(bytes_sent=346L, bytes_recv=0L, packets_sent=0L, packets_recv=0L, errin=0L, errout=0L, dropin=0L, dropout=0)}

In [16]: psutil.get_users()
Out[16]:
[user(name='rico', terminal='console', host=None, started=1376508928.0),
 user(name='rico', terminal='ttys000', host=None, started=1379359104.0),
 user(name='rico', terminal='ttys001', host=None, started=1379345792.0),
 user(name='rico', terminal='ttys002', host=None, started=1379362304.0),
 user(name='rico', terminal='ttys003', host=None, started=1379362560.0),
 user(name='rico', terminal='ttys004', host=None, started=1379310080.0),
 user(name='rico', terminal='ttys005', host=None, started=1379359744.0),
 user(name='rico', terminal='ttys006', host=None, started=1379363968.0),
 user(name='rico', terminal='ttys007', host=None, started=1379364096.0)]

Besides those basic bits of system information, psutil also offers means to retrieve information on the currently running processes:

In [17]: [x.as_dict() for x in psutil.process_iter()]
Out[17]:
[
 ...
 {'cmdline': ['postgres: checkpointer process   ', '', '', '', ''],
  'connections': [connection(fd=11, family=30, type=2, laddr=('::1', 63472), raddr=('::1', 63472), status=20)],
  'cpu_percent': 0.0,
  'cpu_times': cputimes(user=0.007971584, system=0.034409444),
  'create_time': 1380061680.176461,
  'cwd': '/usr/local/var/postgres',
  'exe': '/usr/local/Cellar/postgresql/9.2.4/bin/postgres',
  'ext_memory_info': meminfo(rss=331776L, vms=2501677056L, pfaults=757760, pageins=0),
  'gids': group(real=20, effective=20, saved=20),
  'memory_info': meminfo(rss=331776L, vms=2501677056L),
  'memory_maps': None,
  'memory_percent': 0.0038623809814453125,
  'name': 'postgres: checkpointer process   ',
  'nice': 0,
  'num_ctx_switches': amount(voluntary=415, involuntary=0),
  'num_fds': 9,
  'num_threads': 1,
  'open_files': [openfile(path='/usr/local/var/postgres/server.log', fd=2)],
  'pid': 318,
  'ppid': 305,
  'status': 0,
  'terminal': None,
  'threads': None,
  'uids': user(real=501, effective=501, saved=501),
  'username': 'rico'},
 {'cmdline': ['postgres: writer process   ', '', '', '', ''],
  'connections': [connection(fd=11, family=30, type=2, laddr=('::1', 63472), raddr=('::1', 63472), status=20)],
  'cpu_percent': 0.0,
  'cpu_times': cputimes(user=7.840782848, system=20.813142016),
  'create_time': 1380061680.176621,
  'cwd': '/usr/local/var/postgres',
  'exe': '/usr/local/Cellar/postgresql/9.2.4/bin/postgres',
  'ext_memory_info': meminfo(rss=331776L, vms=2501677056L, pfaults=729088, pageins=8192),
  'gids': group(real=20, effective=20, saved=20),
  'memory_info': meminfo(rss=331776L, vms=2501677056L),
  'memory_maps': None,
  'memory_percent': 0.0038623809814453125,
  'name': 'postgres: writer process   ',
  'nice': 0,
  'num_ctx_switches': amount(voluntary=599872, involuntary=0),
  'num_fds': 9,
  'num_threads': 1,
  'open_files': [openfile(path='/usr/local/var/postgres/server.log', fd=2)],
  'pid': 319,
  'ppid': 305,
  'status': 0,
  'terminal': None,
  'threads': None,
  'uids': user(real=501, effective=501, saved=501),
  'username': 'rico'},
  ...
  ]

For each process, one can retrieve CPU-usage, memory, thread, network connections, open file descriptors information and more.

Last but not least, the library is multi-platform, currently supporting Linux, Windows, OSX, FreeBSD and Sun Solaris, both 32-bit and 64-bit.

With all this combined, psutil provides a really nice base for building system-metrics related applications.