@hasna/logs 0.3.21 → 0.3.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ // @bun
2
+ import {
3
+ parseTime
4
+ } from "./index-997bkzr2.js";
5
+
6
+ // src/lib/diagnose.ts
7
+ function diagnose(db, projectId, since, include) {
8
+ const window = parseTime(since) ?? since ?? new Date(Date.now() - 24 * 3600 * 1000).toISOString();
9
+ const all = !include || include.length === 0;
10
+ const want = (k) => all || include.includes(k);
11
+ const top_errors = want("top_errors") ? db.prepare(`
12
+ SELECT message, COUNT(*) as count, service, MAX(timestamp) as last_seen
13
+ FROM logs
14
+ WHERE project_id = $p AND level IN ('error','fatal') AND timestamp >= $since
15
+ GROUP BY message, service
16
+ ORDER BY count DESC
17
+ LIMIT 10
18
+ `).all({ $p: projectId, $since: window }) : [];
19
+ const error_rate_by_service = want("error_rate") ? db.prepare(`
20
+ SELECT service,
21
+ SUM(CASE WHEN level IN ('error','fatal') THEN 1 ELSE 0 END) as errors,
22
+ SUM(CASE WHEN level = 'warn' THEN 1 ELSE 0 END) as warns,
23
+ COUNT(*) as total
24
+ FROM logs
25
+ WHERE project_id = $p AND timestamp >= $since
26
+ GROUP BY service
27
+ ORDER BY errors DESC
28
+ `).all({ $p: projectId, $since: window }) : [];
29
+ const failing_pages = want("failing_pages") ? db.prepare(`
30
+ SELECT l.page_id, p.url, COUNT(*) as error_count
31
+ FROM logs l
32
+ JOIN pages p ON p.id = l.page_id
33
+ WHERE l.project_id = $p AND l.level IN ('error','fatal') AND l.timestamp >= $since AND l.page_id IS NOT NULL
34
+ GROUP BY l.page_id, p.url
35
+ ORDER BY error_count DESC
36
+ LIMIT 10
37
+ `).all({ $p: projectId, $since: window }) : [];
38
+ const perf_regressions = want("perf") ? db.prepare(`
39
+ SELECT * FROM (
40
+ SELECT
41
+ cur.page_id,
42
+ p.url,
43
+ cur.score as score_now,
44
+ prev.score as score_prev,
45
+ (cur.score - prev.score) as delta
46
+ FROM performance_snapshots cur
47
+ JOIN pages p ON p.id = cur.page_id
48
+ LEFT JOIN performance_snapshots prev ON prev.page_id = cur.page_id AND prev.id != cur.id
49
+ WHERE cur.project_id = $p
50
+ AND cur.timestamp = (SELECT MAX(timestamp) FROM performance_snapshots WHERE page_id = cur.page_id)
51
+ AND (prev.timestamp = (SELECT MAX(timestamp) FROM performance_snapshots WHERE page_id = cur.page_id AND id != cur.id) OR prev.id IS NULL)
52
+ ) WHERE delta < -5 OR delta IS NULL
53
+ ORDER BY delta ASC
54
+ LIMIT 10
55
+ `).all({ $p: projectId }) : [];
56
+ const totalErrors = top_errors.reduce((s, e) => s + e.count, 0);
57
+ const totalWarns = error_rate_by_service.reduce((s, r) => s + r.warns, 0);
58
+ const topService = error_rate_by_service[0];
59
+ const score = totalErrors === 0 ? "green" : totalErrors <= 10 ? "yellow" : "red";
60
+ const summary = totalErrors === 0 ? "No errors in this window. All looks good." : `${totalErrors} error(s) detected. Worst service: ${topService?.service ?? "unknown"} (${topService?.errors ?? 0} errors). ${failing_pages.length} page(s) with errors. ${perf_regressions.length} perf regression(s).`;
61
+ return {
62
+ project_id: projectId,
63
+ window,
64
+ score,
65
+ error_count: totalErrors,
66
+ warn_count: totalWarns,
67
+ has_perf_regression: perf_regressions.length > 0,
68
+ top_errors,
69
+ error_rate_by_service,
70
+ failing_pages,
71
+ perf_regressions,
72
+ summary
73
+ };
74
+ }
75
+
76
+ export { diagnose };