(name: str, text: str)
| 281 | |
| 282 | |
| 283 | def parse_ndjson(name: str, text: str) -> dict[str, Any]: |
| 284 | counts: defaultdict[str, int] = defaultdict(int) |
| 285 | fail_counts: defaultdict[str, float] = defaultdict(float) |
| 286 | latencies: defaultdict[str, list[float]] = defaultdict(list) |
| 287 | all_latencies: list[float] = [] |
| 288 | |
| 289 | for line in text.splitlines(): |
| 290 | stripped = line.strip() |
| 291 | if not stripped: |
| 292 | continue |
| 293 | try: |
| 294 | obj = json.loads(stripped) |
| 295 | except json.JSONDecodeError: |
| 296 | continue |
| 297 | if obj.get("type") != "Point": |
| 298 | continue |
| 299 | data = obj.get("data", {}) |
| 300 | timestamp = data.get("time") |
| 301 | if not timestamp: |
| 302 | continue |
| 303 | minute = floor_minute(timestamp) |
| 304 | value = to_float(data.get("value")) |
| 305 | if obj.get("metric") == "http_reqs": |
| 306 | counts[minute] += int(value or 0) |
| 307 | elif obj.get("metric") == "http_req_failed": |
| 308 | fail_counts[minute] += value or 0.0 |
| 309 | elif obj.get("metric") == "http_req_duration" and value is not None: |
| 310 | latencies[minute].append(value) |
| 311 | all_latencies.append(value) |
| 312 | |
| 313 | minutes = sorted(set(counts.keys()) | set(latencies.keys())) |
| 314 | series: list[dict[str, Any]] = [] |
| 315 | total_requests = 0 |
| 316 | total_failures = 0.0 |
| 317 | apdex_values: list[float] = [] |
| 318 | |
| 319 | for minute in minutes: |
| 320 | lats = latencies.get(minute, []) |
| 321 | requests = counts.get(minute, 0) or len(lats) |
| 322 | failures = fail_counts.get(minute, 0.0) |
| 323 | stats = percentile_stats(lats) |
| 324 | apdex = compute_apdex(lats) |
| 325 | if apdex is not None: |
| 326 | apdex_values.append(apdex) |
| 327 | total_requests += requests |
| 328 | total_failures += failures |
| 329 | series.append( |
| 330 | { |
| 331 | "minute": minute, |
| 332 | "label": minute[11:], |
| 333 | "requests": requests, |
| 334 | "tpm": requests, |
| 335 | "successRate": clamp_01(1 - (failures / requests)) if requests else None, |
| 336 | "p50Ms": stats["p50"], |
| 337 | "p95Ms": stats["p95"], |
| 338 | "p99Ms": stats["p99"], |
| 339 | "apdex": apdex, |
| 340 | } |
no test coverage detected