|
| 1 | +importpsutil |
| 2 | +fromdatetimeimportdatetime |
| 3 | +importpandasaspd |
| 4 | + |
| 5 | +defget_size(bytes): |
| 6 | +""" |
| 7 | + Returns size of bytes in a nice format |
| 8 | + """ |
| 9 | +forunitin ['','K','M','G','T','P']: |
| 10 | +ifbytes<1024: |
| 11 | +returnf"{bytes:.2f}{unit}B" |
| 12 | +bytes/=1024 |
| 13 | + |
| 14 | +# the list the contain all process dictionaries |
| 15 | +processes= [] |
| 16 | +forprocessinpsutil.process_iter(): |
| 17 | +# get all process info in one shot |
| 18 | +withprocess.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 | +exceptpsutil.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 | +exceptpsutil.AccessDenied: |
| 38 | +nice=0 |
| 39 | +try: |
| 40 | +# get the memory usage in bytes |
| 41 | +memory_usage=process.memory_full_info().uss |
| 42 | +exceptpsutil.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 | +exceptpsutil.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 | +importargparse |
| 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=notdescending) |
| 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 | +ifn==0: |
| 97 | +print(df.to_string()) |
| 98 | +elifn>0: |
| 99 | +print(df.head(n).to_string()) |
| 100 | + |
| 101 | + |
| 102 | + |
| 103 | + |
| 104 | + |