11import psutil
22from datetime import datetime
33import pandas as pd
4+ import time
5+ import os
6+
47
58def get_size (bytes ):
69 """
@@ -11,59 +14,84 @@ def get_size(bytes):
1114 return f"{ bytes :.2f} { unit } B"
1215 bytes /= 1024
1316
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- })
6217
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 )
18+ def get_processes_info ():
19+ # the list the contain all process dictionaries
20+ processes = []
21+ for process in psutil .process_iter ():
22+ # get all process info in one shot
23+ with process .oneshot ():
24+ # get the process id
25+ pid = process .pid
26+ if pid == 0 :
27+ # System Idle Process for Windows NT, useless to see anyways
28+ continue
29+ # get the name of the file executed
30+ name = process .name ()
31+ # get the time the process was spawned
32+ try :
33+ create_time = datetime .fromtimestamp (process .create_time ())
34+ except OSError :
35+ # system processes, using boot time instead
36+ create_time = datetime .fromtimestamp (psutil .boot_time ())
37+ try :
38+ # get the number of CPU cores that can execute this process
39+ cores = len (process .cpu_affinity ())
40+ except psutil .AccessDenied :
41+ cores = 0
42+ # get the CPU usage percentage
43+ cpu_usage = process .cpu_percent ()
44+ # get the status of the process (running, idle, etc.)
45+ status = process .status ()
46+ try :
47+ # get the process priority (a lower value means a more prioritized process)
48+ nice = int (process .nice ())
49+ except psutil .AccessDenied :
50+ nice = 0
51+ try :
52+ # get the memory usage in bytes
53+ memory_usage = process .memory_full_info ().uss
54+ except psutil .AccessDenied :
55+ memory_usage = 0
56+ # total process read and written bytes
57+ io_counters = process .io_counters ()
58+ read_bytes = io_counters .read_bytes
59+ write_bytes = io_counters .write_bytes
60+ # get the number of total threads spawned by this process
61+ n_threads = process .num_threads ()
62+ # get the username of user spawned the process
63+ try :
64+ username = process .username ()
65+ except psutil .AccessDenied :
66+ username = "N/A"
67+
68+ processes .append ({
69+ 'pid' : pid , 'name' : name , 'create_time' : create_time ,
70+ 'cores' : cores , 'cpu_usage' : cpu_usage , 'status' : status , 'nice' : nice ,
71+ 'memory_usage' : memory_usage , 'read_bytes' : read_bytes , 'write_bytes' : write_bytes ,
72+ 'n_threads' : n_threads , 'username' : username ,
73+ })
74+
75+ return processes
76+
77+
78+ def construct_dataframe (processes ):
79+ # convert to pandas dataframe
80+ df = pd .DataFrame (processes )
81+ # set the process id as index of a process
82+ df .set_index ('pid' , inplace = True )
83+ # sort rows by the column passed as argument
84+ df .sort_values (sort_by , inplace = True , ascending = not descending )
85+ # pretty printing bytes
86+ df ['memory_usage' ] = df ['memory_usage' ].apply (get_size )
87+ df ['write_bytes' ] = df ['write_bytes' ].apply (get_size )
88+ df ['read_bytes' ] = df ['read_bytes' ].apply (get_size )
89+ # convert to proper date format
90+ df ['create_time' ] = df ['create_time' ].apply (datetime .strftime , args = ("%Y-%m-%d %H:%M:%S" ,))
91+ # reorder and define used columns
92+ df = df [columns .split ("," )]
93+ return df
94+
6795if __name__ == "__main__" :
6896 import argparse
6997 parser = argparse .ArgumentParser (description = "Process Viewer & Monitor" )
@@ -74,31 +102,31 @@ def get_size(bytes):
74102 parser .add_argument ("-s" , "--sort-by" , dest = "sort_by" , help = "Column to sort by, default is memory_usage ." , default = "memory_usage" )
75103 parser .add_argument ("--descending" , action = "store_true" , help = "Whether to sort in descending order." )
76104 parser .add_argument ("-n" , help = "Number of processes to show, will show all if 0 is specified, default is 25 ." , default = 25 )
105+ parser .add_argument ("-u" , "--live-update" , action = "store_true" , help = "Whether to keep the program on and updating process information each second" )
77106
78107 # parse arguments
79108 args = parser .parse_args ()
80109 columns = args .columns
81110 sort_by = args .sort_by
82111 descending = args .descending
83112 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
113+ live_update = args .live_update
114+ # print the processes for the first time
115+ processes = get_processes_info ()
116+ df = construct_dataframe (processes )
96117 if n == 0 :
97118 print (df .to_string ())
98119 elif n > 0 :
99120 print (df .head (n ).to_string ())
100-
101-
102-
103-
104-
121+ # print continuously
122+ while live_update :
123+ # get all process info
124+ processes = get_processes_info ()
125+ df = construct_dataframe (processes )
126+ # clear the screen depending on your OS
127+ os .system ("cls" ) if "nt" in os .name else os .system ("clear" )
128+ if n == 0 :
129+ print (df .to_string ())
130+ elif n > 0 :
131+ print (df .head (n ).to_string ())
132+ time .sleep (0.7 )
0 commit comments