|
| 1 | +import psutil |
| 2 | +from datetime import datetime |
| 3 | +import pandas as pd |
| 4 | + |
| 5 | +def get_size(bytes): |
| 6 | + """ |
| 7 | + Returns size of bytes in a nice format |
| 8 | + """ |
| 9 | + for unit in ['', 'K', 'M', 'G', 'T', 'P']: |
| 10 | + if bytes < 1024: |
| 11 | + return f"{bytes:.2f}{unit}B" |
| 12 | + bytes /= 1024 |
| 13 | + |
| 14 | +# the list the contain all process dictionaries |
| 15 | +processes = [] |
| 16 | +for process in psutil.process_iter(): |
| 17 | + # get all process info in one shot |
| 18 | + with process.oneshot(): |
| 19 | + # get the process id |
| 20 | + pid = process.pid |
| 21 | + # get the name of the file executed |
| 22 | + name = process.name() |
| 23 | + # get the time the process was spawned |
| 24 | + create_time = datetime.fromtimestamp(process.create_time()) |
| 25 | + try: |
| 26 | + # get the number of CPU cores that can execute this process |
| 27 | + cores = len(process.cpu_affinity()) |
| 28 | + except psutil.AccessDenied: |
| 29 | + cores = 0 |
| 30 | + # get the CPU usage percentage |
| 31 | + cpu_usage = process.cpu_percent() |
| 32 | + # get the status of the process (running, idle, etc.) |
| 33 | + status = process.status() |
| 34 | + try: |
| 35 | + # get the process priority (a lower value means a more prioritized process) |
| 36 | + nice = int(process.nice()) |
| 37 | + except psutil.AccessDenied: |
| 38 | + nice = 0 |
| 39 | + try: |
| 40 | + # get the memory usage in bytes |
| 41 | + memory_usage = process.memory_full_info().uss |
| 42 | + except psutil.AccessDenied: |
| 43 | + memory_usage = 0 |
| 44 | + # total process read and written bytes |
| 45 | + io_counters = process.io_counters() |
| 46 | + read_bytes = io_counters.read_bytes |
| 47 | + write_bytes = io_counters.write_bytes |
| 48 | + # get the number of total threads spawned by this process |
| 49 | + n_threads = process.num_threads() |
| 50 | + # get the username of user spawned the process |
| 51 | + try: |
| 52 | + username = process.username() |
| 53 | + except psutil.AccessDenied: |
| 54 | + username = "N/A" |
| 55 | + |
| 56 | + processes.append({ |
| 57 | + 'pid': pid, 'name': name, 'create_time': create_time, |
| 58 | + 'cores': cores, 'cpu_usage': cpu_usage, 'status': status, 'nice': nice, |
| 59 | + 'memory_usage': memory_usage, 'read_bytes': read_bytes, 'write_bytes': write_bytes, |
| 60 | + 'n_threads': n_threads, 'username': username, |
| 61 | + }) |
| 62 | + |
| 63 | +# convert to pandas dataframe |
| 64 | +df = pd.DataFrame(processes) |
| 65 | +# set the process id as index of a process |
| 66 | +df.set_index('pid', inplace=True) |
| 67 | +if __name__ == "__main__": |
| 68 | + import argparse |
| 69 | + parser = argparse.ArgumentParser(description="Process Viewer & Monitor") |
| 70 | + parser.add_argument("-c", "--columns", help="""Columns to show, |
| 71 | + available are name,create_time,cores,cpu_usage,status,nice,memory_usage,read_bytes,write_bytes,n_threads,username. |
| 72 | + Default is name,cpu_usage,memory_usage,read_bytes,write_bytes,status,create_time,nice,n_threads,cores.""", |
| 73 | + default="name,cpu_usage,memory_usage,read_bytes,write_bytes,status,create_time,nice,n_threads,cores") |
| 74 | + parser.add_argument("-s", "--sort-by", dest="sort_by", help="Column to sort by, default is memory_usage .", default="memory_usage") |
| 75 | + parser.add_argument("--descending", action="store_true", help="Whether to sort in descending order.") |
| 76 | + parser.add_argument("-n", help="Number of processes to show, will show all if 0 is specified, default is 25 .", default=25) |
| 77 | + |
| 78 | + # parse arguments |
| 79 | + args = parser.parse_args() |
| 80 | + columns = args.columns |
| 81 | + sort_by = args.sort_by |
| 82 | + descending = args.descending |
| 83 | + n = int(args.n) |
| 84 | + |
| 85 | + # sort rows by the column passed as argument |
| 86 | + df.sort_values(sort_by, inplace=True, ascending=not descending) |
| 87 | + # pretty printing bytes |
| 88 | + df['memory_usage'] = df['memory_usage'].apply(get_size) |
| 89 | + df['write_bytes'] = df['write_bytes'].apply(get_size) |
| 90 | + df['read_bytes'] = df['read_bytes'].apply(get_size) |
| 91 | + # convert to proper date format |
| 92 | + df['create_time'] = df['create_time'].apply(datetime.strftime, args=("%Y-%m-%d %H:%M:%S",)) |
| 93 | + # reorder and define used columns |
| 94 | + df = df[columns.split(",")] |
| 95 | + # print |
| 96 | + if n == 0: |
| 97 | + print(df.to_string()) |
| 98 | + elif n > 0: |
| 99 | + print(df.head(n).to_string()) |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | + |
| 104 | + |
0 commit comments