(self)
| 2137 | return |
| 2138 | |
| 2139 | def _dispatch(self) -> None: |
| 2140 | parsed = urllib.parse.urlparse(self.path) |
| 2141 | params = urllib.parse.parse_qs(parsed.query) |
| 2142 | |
| 2143 | if parsed.path in {"/", "/index.html"}: |
| 2144 | body = page.encode("utf-8") |
| 2145 | self.send_response(200) |
| 2146 | self.send_header("Content-Type", "text/html; charset=utf-8") |
| 2147 | self.send_header("Content-Length", str(len(body))) |
| 2148 | self.end_headers() |
| 2149 | self.wfile.write(body) |
| 2150 | return |
| 2151 | |
| 2152 | if parsed.path == "/api/meta": |
| 2153 | self._write_json(engine.meta()) |
| 2154 | return |
| 2155 | |
| 2156 | if parsed.path == "/api/threads": |
| 2157 | self._write_json(engine.list_threads()) |
| 2158 | return |
| 2159 | |
| 2160 | if parsed.path == "/api/functions": |
| 2161 | rows = engine.list_functions( |
| 2162 | thread_ids=_parse_csv_ints(params.get("threads", [""])[0]), |
| 2163 | query=params.get("q", [""])[0], |
| 2164 | limit=int(params.get("limit", ["200"])[0]), |
| 2165 | sort=params.get("sort", ["alpha"])[0], |
| 2166 | start_ms=int(params["start"][0]) if "start" in params else None, |
| 2167 | end_ms=int(params["end"][0]) if "end" in params else None, |
| 2168 | ) |
| 2169 | self._write_json(rows) |
| 2170 | return |
| 2171 | |
| 2172 | if parsed.path == "/api/series": |
| 2173 | thread_ids = _parse_csv_ints(params.get("threads", [""])[0]) |
| 2174 | function_ids = _parse_csv_ints(params.get("functions", [""])[0]) |
| 2175 | start_ms = int(params["start"][0]) if "start" in params else None |
| 2176 | end_ms = int(params["end"][0]) if "end" in params else None |
| 2177 | metric_default = params.get("value", ["malloc"])[0] |
| 2178 | selected_metrics = _parse_csv_strings(params.get("metrics", [metric_default])[0]) |
| 2179 | response = engine.query_multi_series( |
| 2180 | thread_ids=thread_ids, |
| 2181 | function_ids=function_ids, |
| 2182 | start_ms=start_ms, |
| 2183 | end_ms=end_ms, |
| 2184 | metrics=selected_metrics, |
| 2185 | scope=params.get("scope", ["inclusive"])[0], |
| 2186 | split=params.get("split", ["auto"])[0], |
| 2187 | resolution=int(params["resolution"][0]) if "resolution" in params else None, |
| 2188 | ) |
| 2189 | detail_metric = engine.detail_metric(selected_metrics, default=metric_default) |
| 2190 | self._write_json( |
| 2191 | { |
| 2192 | "ticks": response.ticks, |
| 2193 | "series": [ |
| 2194 | {"label": label, "values": values} for label, values in response.series.items() |
| 2195 | ], |
| 2196 | "metric": response.metric, |
no test coverage detected