michael@0: #!/usr/bin/env python michael@0: michael@0: # Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. michael@0: # Use of this source code is governed by a BSD-style license that can be michael@0: # found in the LICENSE file. michael@0: michael@0: """ michael@0: Print detailed information about a process. michael@0: michael@0: Author: Giampaolo Rodola' michael@0: """ michael@0: michael@0: import os michael@0: import datetime michael@0: import socket michael@0: import sys michael@0: michael@0: import psutil michael@0: michael@0: michael@0: def convert_bytes(n): michael@0: symbols = ('K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') michael@0: prefix = {} michael@0: for i, s in enumerate(symbols): michael@0: prefix[s] = 1 << (i+1)*10 michael@0: for s in reversed(symbols): michael@0: if n >= prefix[s]: michael@0: value = float(n) / prefix[s] michael@0: return '%.1f%s' % (value, s) michael@0: return "%sB" % n michael@0: michael@0: def print_(a, b): michael@0: if sys.stdout.isatty() and os.name == 'posix': michael@0: fmt = '\x1b[1;32m%-17s\x1b[0m %s' %(a, b) michael@0: else: michael@0: fmt = '%-15s %s' %(a, b) michael@0: # python 2/3 compatibility layer michael@0: sys.stdout.write(fmt + '\n') michael@0: sys.stdout.flush() michael@0: michael@0: def run(pid): michael@0: ACCESS_DENIED = '' michael@0: try: michael@0: p = psutil.Process(pid) michael@0: pinfo = p.as_dict(ad_value=ACCESS_DENIED) michael@0: except psutil.NoSuchProcess: michael@0: sys.exit(str(sys.exc_info()[1])) michael@0: michael@0: try: michael@0: if p.parent: michael@0: parent = '(%s)' % p.parent.name michael@0: else: michael@0: parent = '' michael@0: except psutil.Error: michael@0: parent = '' michael@0: started = datetime.datetime.fromtimestamp(pinfo['create_time'] michael@0: ).strftime('%Y-%M-%d %H:%M') michael@0: io = pinfo.get('io_counters', ACCESS_DENIED) michael@0: mem = '%s%% (resident=%s, virtual=%s) ' % ( michael@0: round(pinfo['memory_percent'], 1), michael@0: convert_bytes(pinfo['memory_info'].rss), michael@0: convert_bytes(pinfo['memory_info'].vms)) michael@0: children = p.get_children() michael@0: michael@0: print_('pid', pinfo['pid']) michael@0: print_('name', pinfo['name']) michael@0: print_('exe', pinfo['exe']) michael@0: print_('parent', '%s %s' % (pinfo['ppid'], parent)) michael@0: print_('cmdline', ' '.join(pinfo['cmdline'])) michael@0: print_('started', started) michael@0: print_('user', pinfo['username']) michael@0: if os.name == 'posix' and pinfo['uids'] and pinfo['gids']: michael@0: print_('uids', 'real=%s, effective=%s, saved=%s' % pinfo['uids']) michael@0: if os.name == 'posix' and pinfo['gids']: michael@0: print_('gids', 'real=%s, effective=%s, saved=%s' % pinfo['gids']) michael@0: if os.name == 'posix': michael@0: print_('terminal', pinfo['terminal'] or '') michael@0: if hasattr(p, 'getcwd'): michael@0: print_('cwd', pinfo['cwd']) michael@0: print_('memory', mem) michael@0: print_('cpu', '%s%% (user=%s, system=%s)' % (pinfo['cpu_percent'], michael@0: getattr(pinfo['cpu_times'], 'user', '?'), michael@0: getattr(pinfo['cpu_times'], 'system', '?'))) michael@0: print_('status', pinfo['status']) michael@0: print_('niceness', pinfo['nice']) michael@0: print_('num threads', pinfo['num_threads']) michael@0: if io != ACCESS_DENIED: michael@0: print_('I/O', 'bytes-read=%s, bytes-written=%s' % \ michael@0: (convert_bytes(io.read_bytes), michael@0: convert_bytes(io.write_bytes))) michael@0: if children: michael@0: print_('children', '') michael@0: for child in children: michael@0: print_('', 'pid=%s name=%s' % (child.pid, child.name)) michael@0: michael@0: if pinfo['open_files'] != ACCESS_DENIED: michael@0: print_('open files', '') michael@0: for file in pinfo['open_files']: michael@0: print_('', 'fd=%s %s ' % (file.fd, file.path)) michael@0: michael@0: if pinfo['threads']: michael@0: print_('running threads', '') michael@0: for thread in pinfo['threads']: michael@0: print_('', 'id=%s, user-time=%s, sys-time=%s' \ michael@0: % (thread.id, thread.user_time, thread.system_time)) michael@0: if pinfo['connections'] != ACCESS_DENIED: michael@0: print_('open connections', '') michael@0: for conn in pinfo['connections']: michael@0: if conn.type == socket.SOCK_STREAM: michael@0: type = 'TCP' michael@0: elif conn.type == socket.SOCK_DGRAM: michael@0: type = 'UDP' michael@0: else: michael@0: type = 'UNIX' michael@0: lip, lport = conn.laddr michael@0: if not conn.raddr: michael@0: rip, rport = '*', '*' michael@0: else: michael@0: rip, rport = conn.raddr michael@0: print_('', '%s:%s -> %s:%s type=%s status=%s' \ michael@0: % (lip, lport, rip, rport, type, conn.status)) michael@0: michael@0: def main(argv=None): michael@0: if argv is None: michael@0: argv = sys.argv michael@0: if len(argv) == 1: michael@0: sys.exit(run(os.getpid())) michael@0: elif len(argv) == 2: michael@0: sys.exit(run(int(argv[1]))) michael@0: else: michael@0: sys.exit('usage: %s [pid]' % __file__) michael@0: michael@0: if __name__ == '__main__': michael@0: sys.exit(main())