third_party/python/psutil/scripts/pstree.py
author Ted Mielczarek <ted@mielczarek.org>
Wed, 15 Aug 2018 10:39:35 -0400
changeset 496241 c8f12706c4218440a04cbcb822f032306360d0cb
parent 456041 f3bfda748e339695fee5912acd12cd0c7a913b58
permissions -rwxr-xr-x
bug 1481612 - Re-vendor psutil 5.4.3 using `mach vendor python`. r=gps psutil was previously vendored manually, so re-vendor it using our new tooling to make for smaller diffs in follow-up patches. This mostly just winds up adding some extra files that must have been left out of the manual vendoring, but it also updates the root Pipfile + Pipfile.lock. Differential Revision: https://phabricator.services.mozilla.com/D3434

#!/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 scripts/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()