@@ -20,7 +20,7 @@ def __init__(self, name, action, is_active=True):
20
20
21
21
@property
22
22
def name (self ):
23
- return self .name
23
+ return self ._name
24
24
25
25
def measure (self , process ):
26
26
return str (self ._action (process ))
@@ -67,30 +67,12 @@ def get_affinity(process):
67
67
68
68
69
69
def get_read_open_files (process ):
70
- open_files = []
71
- try :
72
- for file in process .open_files ():
73
- try :
74
- if file .mode == 'r' :
75
- open_files .append (file .path )
76
- except :
77
- pass
78
- except :
79
- pass
70
+ open_files = [file .path for file in process .open_files () if file .mode == 'r' ]
80
71
return ';' .join (open_files )
81
72
82
73
83
74
def get_write_open_files (process ):
84
- open_files = []
85
- try :
86
- for file in process .open_files ():
87
- try :
88
- if file .mode != 'r' :
89
- open_files .append (f'{ file .path } :{ Path (file .path ).stat ().st_size } ' )
90
- except :
91
- pass
92
- except :
93
- pass
75
+ open_files = [file .path for file in process .open_files () if file .mode != 'r' ]
94
76
return ';' .join (open_files )
95
77
96
78
@@ -106,7 +88,6 @@ def define_actions(inactive=None):
106
88
metrics ['cpu_user' ] = Metric ('cpu_user' , lambda x : x .cpu_times ().user )
107
89
metrics ['cpu_sys' ] = Metric ('cpu_sys' , lambda x : x .cpu_times ().system )
108
90
metrics ['num_threads' ] = Metric ('num_threads' , lambda x : x .num_threads ())
109
- metrics ['mem_perpent' ] = Metric ('mem_perpent' , lambda x : f'{ x .cpu_percent ():.2f} ' )
110
91
metrics ['mem' ] = Metric ('mem' , lambda x : x .memory_full_info ().uss )
111
92
metrics ['affinity' ] = Metric ('affinity' , lambda x : get_affinity (x ))
112
93
metrics ['read_files' ] = Metric ('read_files' , lambda x : get_read_open_files (x ))
@@ -136,39 +117,49 @@ def process_status(process, metrics):
136
117
137
118
def main ():
138
119
arg_parser = ArgumentParser (description = 'monitor processes' )
139
- arg_parser .add_argument ('--pid' , type = int , help = 'parent process ID ot monitor' )
120
+ arg_parser .add_argument ('--pid' , type = int , required = True ,
121
+ help = 'parent process ID to monitor' )
140
122
arg_parser .add_argument ('--user' , help = 'user of the processes to monitor' )
141
123
arg_parser .add_argument ('--delta' , type = float , default = 60.0 ,
142
124
help = 'number of seconds between measurements' )
143
125
arg_parser .add_argument ('--affinity' , action = 'store_true' ,
144
126
help = 'monitor process affinity' )
145
- arg_parser .add_argument ('--files' , action = 'store_true' , help = 'monitor poen files' )
127
+ arg_parser .add_argument ('--files' , action = 'store_true' , help = 'monitor open files' )
146
128
arg_parser .add_argument ('--ancestor' , action = 'store_true' ,
147
- help = 'search for ancestor owned by use and report on all its decendants' )
148
- arg_parser .add_argument ('--output-file' , help = 'name of file to store informatoin ' )
129
+ help = 'search for ancestor process owned by user and report on all its decendants' )
130
+ arg_parser .add_argument ('--output-file' , help = 'name of file to store information ' )
149
131
options = arg_parser .parse_args ()
150
- if options .ancestor :
151
- process = find_ancestor (options .pid , options .user )
152
- else :
153
- process = psutil .Process (options .pid )
132
+ try :
133
+ if options .ancestor :
134
+ process = find_ancestor (options .pid , options .user )
135
+ else :
136
+ process = psutil .Process (options .pid )
137
+ except psutil .NoSuchProcess :
138
+ print (f'Process { options .pid } does not exist' , file = sys .stderr )
139
+ return 1
154
140
inactive = []
155
141
if not options .affinity :
156
142
inactive .append ('affinity' )
157
143
if not options .files :
158
144
inactive .extend (('read_files' , 'write_files' ))
159
145
metrics = define_actions (inactive )
160
- file = open (options .output_file , 'w' ) if options .output_file else sys .stdout
161
146
try :
162
- with file :
147
+ with open ( options . output_file , 'w' ) if options . output_file else sys . stdout as file :
163
148
print (status_header (metrics ), file = file )
164
149
while True :
165
150
process_info = [process_status (process , metrics )]
166
- process_info .extend (
167
- process_status (child_process , metrics )
168
- for child_process in process .children (recursive = True )
169
- )
151
+ try :
152
+ process_info .extend (
153
+ process_status (child_process , metrics )
154
+ for child_process in process .children (recursive = True )
155
+ )
156
+ except psutil .ZombieProcess :
157
+ print ('Zombie process encountered' , file = sys .stderr )
170
158
print ('\n ' .join (process_info ), file = file )
171
159
time .sleep (options .delta )
160
+ except psutil .NoSuchProcess :
161
+ # the process has terminated, but this is to be expected
162
+ pass
172
163
except KeyboardInterrupt :
173
164
pass
174
165
0 commit comments