3b8f63b311600af2cfd1cf0cd778fca9b671ebd5
[ashd.git] / python3 / ashd / perf.py
1 import collections
2 try:
3     import pdm.perf
4 except:
5     pdm = None
6 try:
7     import resource
8     ru_thread = resource.RUSAGE_THREAD
9 except:
10     ru_thread = None
11
12 reqstat = {}
13
14 if pdm:
15     statistics = pdm.perf.staticdir()
16     statistics["req"] = pdm.perf.valueattr(reqstat)
17     requests = pdm.perf.eventobj()
18
19     class reqstart(pdm.perf.startevent):
20         def __init__(self, env):
21             super().__init__()
22             self.method = env.get("REQUEST_METHOD")
23             self.uri = env.get("REQUEST_URI")
24             self.host = env.get("HTTP_HOST")
25             self.script_uri = env.get("SCRIPT_NAME")
26             self.script_path = env.get("SCRIPT_FILENAME")
27             self.pathinfo = env.get("PATH_INFO")
28             self.querystring = env.get("QUERY_STRING")
29             self.remoteaddr = env.get("REMOTE_ADDR")
30             self.remoteport = env.get("REMOTE_PORT")
31             self.scheme = env.get("wsgi.url_scheme")
32             if ru_thread is not None:
33                 ru = resource.getrusage(ru_thread)
34                 self.icpu = ru.ru_utime + ru.ru_stime
35
36     class reqfinish(pdm.perf.finishevent):
37         def __init__(self, start, aborted, status):
38             super().__init__(start, aborted)
39             self.status = status
40             self.cputime = 0
41             if ru_thread is not None:
42                 ru = resource.getrusage(ru_thread)
43                 self.cputime = ru.ru_utime + ru.ru_stime - start.icpu
44
45 class request(object):
46     def __init__(self, env):
47         self.resp = None
48         if pdm:
49             self.startev = reqstart(env)
50             requests.notify(self.startev)
51
52     def response(self, resp):
53         self.resp = resp
54
55     def finish(self, aborted):
56         key = None
57         status = None
58         try:
59             if len(self.resp) > 0:
60                 status = self.resp[0]
61                 if isinstance(status, collections.ByteString):
62                     status = status.decode("latin-1")
63                 else:
64                     status = str(status)
65                 p = status.find(" ")
66                 if p < 0:
67                     key = status
68                 else:
69                     key = status[:p]
70         except:
71             pass
72         reqstat[key] = reqstat.setdefault(key, 0) + 1
73         if pdm:
74             requests.notify(reqfinish(self.startev, aborted, status))
75
76     def __enter__(self):
77         return self
78     
79     def __exit__(self, *excinfo):
80         self.finish(bool(excinfo[0]))
81         return False