forked from kobinpy/wsgi-vmprof
-
Notifications
You must be signed in to change notification settings - Fork 0
/
wsgi_vmprof.py
120 lines (102 loc) · 3.34 KB
/
wsgi_vmprof.py
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import gc
import os
import platform
import sys
import tempfile
import vmprof
from vmshare.service import Service
try:
import _jitlog
except ImportError:
_jitlog = None
OUTPUT_CLI = "cli"
OUTPUT_WEB = "web"
OUTPUT_FILE = "file"
def upload_stats(filename, web_url, web_auth):
sys.stderr.write("Compiling and uploading to {}...\n".format(web_url))
service = Service(web_url, web_auth)
service.post(
{
Service.FILE_CPU_PROFILE: filename,
Service.FILE_JIT_PROFILE: filename + ".jit",
"VM": platform.python_implementation(),
}
)
def show_stats(filename, output_mode, web_url, web_auth):
if output_mode == OUTPUT_FILE:
return
if output_mode == OUTPUT_CLI:
stats = vmprof.read_profile(filename)
vmprof.cli.show(stats)
elif output_mode == OUTPUT_WEB:
upload_stats(filename, web_url, web_auth)
class VmprofMiddleware:
def __init__(
self,
app,
period=0.001,
web_url="http://vmprof.com",
web_auth=None,
mem=False,
lines=False,
jitlog=False,
web=None,
output=None,
):
"""
Parameter details are here:
https://github.com/vmprof/vmprof-python/blob/master/vmprof/cli.py#L7-L72
:param app: Your WSGI application object.
:param float period: Sampling period (in microseconds)
:param str web_auth: Authtoken for your acount on the server, works only when --web is used
:param str web_url: Provide URL instead of the default vmprof.com)
:param bool mem: Do memory profiling as well
:param bool lines: Store lines execution stats
:param bool jitlog: Upload the jitlog to remote server (defaults to vmprof.com)
:param bool web: Upload profiling stats to a remote server (defaults to vmprof.com)
:param output: Save profiling data to file
"""
self.app = app
self.web_url = web_url
self.web_auth = web_auth
self.period = period
self.mem = mem
self.lines = lines
self.jitlog = jitlog
if web:
self.output_mode = OUTPUT_WEB
elif output:
self.output_mode = OUTPUT_FILE
self.prof_name = output
else:
self.output_mode = OUTPUT_CLI
def start(self):
if self.output_mode == OUTPUT_FILE:
self.prof_file = open(self.prof_name, "w+b")
else:
self.prof_file = tempfile.NamedTemporaryFile(delete=False)
self.prof_name = self.prof_file.name
if self.jitlog and _jitlog:
self.jitlog_fd = os.open(
self.prof_file + ".jitlog", os.O_WRONLY | os.O_TRUNC | os.O_CREAT
)
_jitlog.enable(self.jitlog_fd)
vmprof.enable(self.prof_file.fileno(), self.period, self.mem, self.lines)
def stop(self):
vmprof.disable()
self.prof_file.close()
show_stats(
self.prof_name,
self.output_mode,
web_url=self.web_url,
web_auth=self.web_auth,
)
if self.output_mode != OUTPUT_FILE:
os.unlink(self.prof_name)
def __call__(self, *args, **kwargs):
try:
self.start()
gc.disable()
return self.app(*args, **kwargs)
finally:
self.stop()