1
1
import psutil
2
2
from datetime import datetime
3
3
import pandas as pd
4
+ import time
5
+ import os
6
+
4
7
5
8
def get_size (bytes ):
6
9
"""
@@ -11,59 +14,84 @@ def get_size(bytes):
11
14
return f"{ bytes :.2f} { unit } B"
12
15
bytes /= 1024
13
16
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
17
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
+
67
95
if __name__ == "__main__" :
68
96
import argparse
69
97
parser = argparse .ArgumentParser (description = "Process Viewer & Monitor" )
@@ -74,31 +102,31 @@ def get_size(bytes):
74
102
parser .add_argument ("-s" , "--sort-by" , dest = "sort_by" , help = "Column to sort by, default is memory_usage ." , default = "memory_usage" )
75
103
parser .add_argument ("--descending" , action = "store_true" , help = "Whether to sort in descending order." )
76
104
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" )
77
106
78
107
# parse arguments
79
108
args = parser .parse_args ()
80
109
columns = args .columns
81
110
sort_by = args .sort_by
82
111
descending = args .descending
83
112
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 )
96
117
if n == 0 :
97
118
print (df .to_string ())
98
119
elif n > 0 :
99
120
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