-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtspy.py
More file actions
63 lines (52 loc) · 2.42 KB
/
tspy.py
File metadata and controls
63 lines (52 loc) · 2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#
# Written by: Carlos Bazaga
#
# Licensed under BSD 2-Clause
#
import multiprocessing as mp
import threading as th
class Tspy:
"""
Tspy objects are itended to be created inside a process to get information about his threads and subprocesses.
In order to work properly a Tspy object must be created and called inside the process itself.
The process must provide the mechanism to allow external access to the internal execution of this class methods,
maybe via a thread attending a queue of requests.
Also the process must publicly show a "tspy" attribute to let "upper" Tspys know that process can be inspected,
that attribute's "get_report()" method must be someway linked to the previously mentioned mechanism to trigger
the internal execution of the real Tspy's methods inside the object.
"""
def __init__(self, name=None):
"""
Return a new Tspy for the current process.
If keyword argument 'name' is given current process's name is overwritten.
"""
self._process = mp.current_process()
self._process.name = name or mp.current_process().name
def get_report(self):
"""
Return the report of subprocesses and threads.
-> ( (process name, process representation string, process pid),
[(thread name, thread representation string, thread identifier)],
[subprocess report] )
"""
return ((self._process.name, str(self._process), self._process.pid)
,self._get_threads_reports()
,self._get_subprocesses_reports())
def _get_threads_reports(self):
"""Return the list of reports of threads."""
try:
return [(thread.name, str(thread), thread.ident) for thread in sorted(th.enumerate(), key=lambda x: x.name)]
except:
return []
def _get_subprocesses_reports(self):
"""Return the list of reports of subprocesses."""
try:
return [self._get_subprocess_report(process) for process in sorted(mp.active_children(), key=lambda x: x.name)]
except:
return []
def _get_subprocess_report(self, process):
"""Request the report of a subporcess."""
if hasattr(process,'tspy'):
return process.tspy.get_report()
else: # In case of an "unspied" process return empty lists for his descendants.
return ((process.name, str(process), process.pid), [], [])