@hasna/logs 0.3.25 → 0.3.27
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.
- package/README.md +33 -10
- package/dashboard/dist/assets/index-C0wZYq1m.js +53 -0
- package/dashboard/dist/assets/index-DGNrK5qb.css +1 -0
- package/dashboard/dist/index.html +14 -0
- package/dist/cli/index.js +8511 -177
- package/dist/count-bmj4r2zb.js +10 -0
- package/dist/{diagnose-e0w5rwbc.js → diagnose-3q5cy9ra.js} +2 -2
- package/dist/{export-c3eqjste.js → export-cngdb9fh.js} +1 -1
- package/dist/{http-zm3ph78w.js → http-r0xc3d2s.js} +79 -8
- package/dist/index-931pbyn5.js +141 -0
- package/dist/index-b5c72f1p.js +7 -0
- package/dist/{index-p1vgwwsz.js → index-bnr19y0h.js} +596 -37
- package/dist/{index-7w7v7hnr.js → index-by1pdzbr.js} +14 -5
- package/dist/{index-3dr7d80h.js → index-e1930v9b.js} +12 -8
- package/dist/{index-eh9bkbpa.js → index-e72k53yq.js} +10 -2
- package/dist/{index-edn08m6f.js → index-gcd14q2f.js} +9 -6
- package/dist/index-hq6kzaah.js +26 -0
- package/dist/index-j34f36wy.js +5672 -0
- package/dist/index-p4dbdzx4.js +1849 -0
- package/dist/{index-5qznfyah.js → index-q27bgpr1.js} +1086 -1646
- package/dist/index-t3x838zw.js +2583 -0
- package/dist/{index-ww5ggfv3.js → index-zkb3z95a.js} +12 -9
- package/dist/index.js +2982 -22
- package/dist/{jobs-ypmmc2ma.js → jobs-hsgyhfvm.js} +2 -1
- package/dist/mcp/index.js +1473 -4286
- package/dist/{query-7jwj05er.js → query-c5a43zx3.js} +3 -2
- package/dist/server/index.js +2944 -417
- package/dist/storage.js +50 -0
- package/package.json +27 -8
- package/biome.json +0 -13
- package/bun.lock +0 -376
- package/dashboard/README.md +0 -73
- package/dashboard/bun.lock +0 -526
- package/dashboard/eslint.config.js +0 -23
- package/dashboard/index.html +0 -13
- package/dashboard/package.json +0 -32
- package/dashboard/src/App.css +0 -184
- package/dashboard/src/App.tsx +0 -49
- package/dashboard/src/api.ts +0 -33
- package/dashboard/src/assets/hero.png +0 -0
- package/dashboard/src/assets/react.svg +0 -1
- package/dashboard/src/assets/vite.svg +0 -1
- package/dashboard/src/index.css +0 -111
- package/dashboard/src/main.tsx +0 -10
- package/dashboard/src/pages/Alerts.tsx +0 -69
- package/dashboard/src/pages/Issues.tsx +0 -50
- package/dashboard/src/pages/Perf.tsx +0 -75
- package/dashboard/src/pages/Projects.tsx +0 -67
- package/dashboard/src/pages/Summary.tsx +0 -67
- package/dashboard/src/pages/Tail.tsx +0 -65
- package/dashboard/tsconfig.app.json +0 -28
- package/dashboard/tsconfig.json +0 -7
- package/dashboard/tsconfig.node.json +0 -26
- package/dashboard/vite.config.ts +0 -14
- package/dist/count-x3n7qg3c.js +0 -9
- package/dist/index-5cj74qka.js +0 -10803
- package/dist/index-997bkzr2.js +0 -15
- package/dist/index-kezb178p.js +0 -1241
- package/dist/index-pen6t0yc.js +0 -10794
- package/sdk/package.json +0 -27
- package/sdk/src/index.ts +0 -143
- package/sdk/src/types.ts +0 -56
- package/src/cli/entrypoints.test.ts +0 -63
- package/src/cli/index.ts +0 -471
- package/src/db/index.test.ts +0 -33
- package/src/db/index.ts +0 -189
- package/src/db/migrations/001_alert_rules.ts +0 -21
- package/src/db/migrations/002_issues.ts +0 -21
- package/src/db/migrations/003_retention.ts +0 -15
- package/src/db/migrations/004_page_auth.ts +0 -13
- package/src/db/pg-migrations.ts +0 -167
- package/src/index.ts +0 -1
- package/src/lib/alerts.test.ts +0 -67
- package/src/lib/alerts.ts +0 -117
- package/src/lib/browser-script.test.ts +0 -35
- package/src/lib/browser-script.ts +0 -31
- package/src/lib/compare.test.ts +0 -52
- package/src/lib/compare.ts +0 -85
- package/src/lib/count.test.ts +0 -44
- package/src/lib/count.ts +0 -55
- package/src/lib/diagnose.test.ts +0 -55
- package/src/lib/diagnose.ts +0 -91
- package/src/lib/export.test.ts +0 -66
- package/src/lib/export.ts +0 -65
- package/src/lib/github.ts +0 -38
- package/src/lib/health.test.ts +0 -48
- package/src/lib/health.ts +0 -51
- package/src/lib/ingest.test.ts +0 -57
- package/src/lib/ingest.ts +0 -78
- package/src/lib/issues.test.ts +0 -79
- package/src/lib/issues.ts +0 -70
- package/src/lib/jobs.test.ts +0 -69
- package/src/lib/jobs.ts +0 -63
- package/src/lib/lighthouse.ts +0 -65
- package/src/lib/package-meta.test.ts +0 -43
- package/src/lib/package-meta.ts +0 -80
- package/src/lib/page-auth.test.ts +0 -54
- package/src/lib/page-auth.ts +0 -48
- package/src/lib/parse-time.test.ts +0 -37
- package/src/lib/parse-time.ts +0 -14
- package/src/lib/perf.test.ts +0 -45
- package/src/lib/perf.ts +0 -46
- package/src/lib/projects.test.ts +0 -73
- package/src/lib/projects.ts +0 -69
- package/src/lib/query.test.ts +0 -104
- package/src/lib/query.ts +0 -84
- package/src/lib/retention.test.ts +0 -42
- package/src/lib/retention.ts +0 -62
- package/src/lib/rotate.test.ts +0 -37
- package/src/lib/rotate.ts +0 -27
- package/src/lib/scanner.ts +0 -131
- package/src/lib/scheduler.ts +0 -63
- package/src/lib/session-context.ts +0 -28
- package/src/lib/summarize.test.ts +0 -38
- package/src/lib/summarize.ts +0 -23
- package/src/mcp/http.test.ts +0 -92
- package/src/mcp/http.ts +0 -135
- package/src/mcp/index.test.ts +0 -27
- package/src/mcp/index.ts +0 -444
- package/src/server/index.ts +0 -61
- package/src/server/routes/alerts.ts +0 -32
- package/src/server/routes/issues.ts +0 -43
- package/src/server/routes/jobs.ts +0 -32
- package/src/server/routes/logs.ts +0 -113
- package/src/server/routes/perf.ts +0 -23
- package/src/server/routes/projects.ts +0 -67
- package/src/server/routes/stream.ts +0 -43
- package/src/server/server.test.ts +0 -194
- package/src/types/index.ts +0 -119
- package/tsconfig.json +0 -22
- /package/dashboard/{public → dist}/favicon.svg +0 -0
- /package/dashboard/{public → dist}/icons.svg +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
parseTime
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-hq6kzaah.js";
|
|
5
5
|
|
|
6
6
|
// src/lib/diagnose.ts
|
|
7
7
|
function diagnose(db, projectId, since, include) {
|
|
8
8
|
const window = parseTime(since) ?? since ?? new Date(Date.now() - 24 * 3600 * 1000).toISOString();
|
|
9
9
|
const all = !include || include.length === 0;
|
|
10
|
-
const want = (k) => all || include
|
|
10
|
+
const want = (k) => all || include?.includes(k);
|
|
11
11
|
const top_errors = want("top_errors") ? db.prepare(`
|
|
12
12
|
SELECT message, COUNT(*) as count, service, MAX(timestamp) as last_seen
|
|
13
13
|
FROM logs
|
|
@@ -15,7 +15,10 @@ function diagnose(db, projectId, since, include) {
|
|
|
15
15
|
GROUP BY message, service
|
|
16
16
|
ORDER BY count DESC
|
|
17
17
|
LIMIT 10
|
|
18
|
-
`).all({
|
|
18
|
+
`).all({
|
|
19
|
+
$p: projectId,
|
|
20
|
+
$since: window
|
|
21
|
+
}) : [];
|
|
19
22
|
const error_rate_by_service = want("error_rate") ? db.prepare(`
|
|
20
23
|
SELECT service,
|
|
21
24
|
SUM(CASE WHEN level IN ('error','fatal') THEN 1 ELSE 0 END) as errors,
|
|
@@ -25,7 +28,10 @@ function diagnose(db, projectId, since, include) {
|
|
|
25
28
|
WHERE project_id = $p AND timestamp >= $since
|
|
26
29
|
GROUP BY service
|
|
27
30
|
ORDER BY errors DESC
|
|
28
|
-
`).all({
|
|
31
|
+
`).all({
|
|
32
|
+
$p: projectId,
|
|
33
|
+
$since: window
|
|
34
|
+
}) : [];
|
|
29
35
|
const failing_pages = want("failing_pages") ? db.prepare(`
|
|
30
36
|
SELECT l.page_id, p.url, COUNT(*) as error_count
|
|
31
37
|
FROM logs l
|
|
@@ -34,7 +40,10 @@ function diagnose(db, projectId, since, include) {
|
|
|
34
40
|
GROUP BY l.page_id, p.url
|
|
35
41
|
ORDER BY error_count DESC
|
|
36
42
|
LIMIT 10
|
|
37
|
-
`).all({
|
|
43
|
+
`).all({
|
|
44
|
+
$p: projectId,
|
|
45
|
+
$since: window
|
|
46
|
+
}) : [];
|
|
38
47
|
const perf_regressions = want("perf") ? db.prepare(`
|
|
39
48
|
SELECT * FROM (
|
|
40
49
|
SELECT
|
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
import {
|
|
3
|
+
sqlBindings
|
|
4
|
+
} from "./index-b5c72f1p.js";
|
|
5
|
+
|
|
2
6
|
// src/lib/jobs.ts
|
|
3
7
|
function createJob(db, data) {
|
|
4
8
|
return db.prepare(`
|
|
@@ -13,12 +17,12 @@ function createJob(db, data) {
|
|
|
13
17
|
}
|
|
14
18
|
function listJobs(db, projectId) {
|
|
15
19
|
if (projectId) {
|
|
16
|
-
return db.prepare("SELECT * FROM scan_jobs WHERE project_id = $p ORDER BY created_at DESC").all({ $p: projectId });
|
|
20
|
+
return db.prepare("SELECT * FROM scan_jobs WHERE project_id = $p ORDER BY created_at DESC").all(sqlBindings({ $p: projectId }));
|
|
17
21
|
}
|
|
18
22
|
return db.prepare("SELECT * FROM scan_jobs ORDER BY created_at DESC").all();
|
|
19
23
|
}
|
|
20
24
|
function getJob(db, id) {
|
|
21
|
-
return db.prepare("SELECT * FROM scan_jobs WHERE id = $id").get({ $id: id });
|
|
25
|
+
return db.prepare("SELECT * FROM scan_jobs WHERE id = $id").get(sqlBindings({ $id: id }));
|
|
22
26
|
}
|
|
23
27
|
function updateJob(db, id, data) {
|
|
24
28
|
const fields = Object.keys(data).map((k) => `${k} = $${k}`).join(", ");
|
|
@@ -26,15 +30,15 @@ function updateJob(db, id, data) {
|
|
|
26
30
|
return getJob(db, id);
|
|
27
31
|
const params = Object.fromEntries(Object.entries(data).map(([k, v]) => [`$${k}`, v]));
|
|
28
32
|
params.$id = id;
|
|
29
|
-
return db.prepare(`UPDATE scan_jobs SET ${fields} WHERE id = $id RETURNING *`).get(params);
|
|
33
|
+
return db.prepare(`UPDATE scan_jobs SET ${fields} WHERE id = $id RETURNING *`).get(sqlBindings(params));
|
|
30
34
|
}
|
|
31
35
|
function deleteJob(db, id) {
|
|
32
|
-
db.
|
|
36
|
+
db.prepare("DELETE FROM scan_jobs WHERE id = $id").run(sqlBindings({ $id: id }));
|
|
33
37
|
}
|
|
34
38
|
function createScanRun(db, data) {
|
|
35
39
|
return db.prepare(`
|
|
36
40
|
INSERT INTO scan_runs (job_id, page_id) VALUES ($job_id, $page_id) RETURNING *
|
|
37
|
-
`).get({ $job_id: data.job_id, $page_id: data.page_id ?? null });
|
|
41
|
+
`).get(sqlBindings({ $job_id: data.job_id, $page_id: data.page_id ?? null }));
|
|
38
42
|
}
|
|
39
43
|
function finishScanRun(db, id, data) {
|
|
40
44
|
return db.prepare(`
|
|
@@ -42,16 +46,16 @@ function finishScanRun(db, id, data) {
|
|
|
42
46
|
status = $status, logs_collected = $logs_collected,
|
|
43
47
|
errors_found = $errors_found, perf_score = $perf_score
|
|
44
48
|
WHERE id = $id RETURNING *
|
|
45
|
-
`).get({
|
|
49
|
+
`).get(sqlBindings({
|
|
46
50
|
$id: id,
|
|
47
51
|
$status: data.status,
|
|
48
52
|
$logs_collected: data.logs_collected,
|
|
49
53
|
$errors_found: data.errors_found,
|
|
50
54
|
$perf_score: data.perf_score ?? null
|
|
51
|
-
});
|
|
55
|
+
}));
|
|
52
56
|
}
|
|
53
57
|
function listScanRuns(db, jobId, limit = 20) {
|
|
54
|
-
return db.prepare("SELECT * FROM scan_runs WHERE job_id = $j ORDER BY started_at DESC LIMIT $l").all({ $j: jobId, $l: limit });
|
|
58
|
+
return db.prepare("SELECT * FROM scan_runs WHERE job_id = $j ORDER BY started_at DESC LIMIT $l").all(sqlBindings({ $j: jobId, $l: limit }));
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
export { createJob, listJobs, getJob, updateJob, deleteJob, createScanRun, finishScanRun, listScanRuns };
|
|
@@ -52,8 +52,16 @@ function exportToCsv(db, opts, writeLine) {
|
|
|
52
52
|
writeLine(CSV_HEADER);
|
|
53
53
|
let count = 0;
|
|
54
54
|
for (const row of iterLogs(db, opts)) {
|
|
55
|
-
const fields = [
|
|
56
|
-
|
|
55
|
+
const fields = [
|
|
56
|
+
row.id,
|
|
57
|
+
row.timestamp,
|
|
58
|
+
row.level,
|
|
59
|
+
row.service ?? "",
|
|
60
|
+
escapeCSV(row.message),
|
|
61
|
+
row.trace_id ?? "",
|
|
62
|
+
row.url ?? ""
|
|
63
|
+
];
|
|
64
|
+
writeLine(`${fields.join(",")}
|
|
57
65
|
`);
|
|
58
66
|
count++;
|
|
59
67
|
}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
import {
|
|
3
|
+
sqlBindings
|
|
4
|
+
} from "./index-b5c72f1p.js";
|
|
2
5
|
import {
|
|
3
6
|
parseTime
|
|
4
|
-
} from "./index-
|
|
7
|
+
} from "./index-hq6kzaah.js";
|
|
5
8
|
|
|
6
9
|
// src/lib/count.ts
|
|
7
10
|
function countLogs(db, opts) {
|
|
@@ -30,19 +33,19 @@ function countLogs(db, opts) {
|
|
|
30
33
|
params.$until = until;
|
|
31
34
|
}
|
|
32
35
|
const where = conditions.length ? `WHERE ${conditions.join(" AND ")}` : "";
|
|
33
|
-
const byLevel = db.prepare(`SELECT level, COUNT(*) as c FROM logs ${where} GROUP BY level`).all(params);
|
|
36
|
+
const byLevel = db.prepare(`SELECT level, COUNT(*) as c FROM logs ${where} GROUP BY level`).all(sqlBindings(params));
|
|
34
37
|
const by_level = Object.fromEntries(byLevel.map((r) => [r.level, r.c]));
|
|
35
38
|
const total = byLevel.reduce((s, r) => s + r.c, 0);
|
|
36
39
|
let by_service;
|
|
37
40
|
if (opts.group_by === "service") {
|
|
38
|
-
const bySvc = db.prepare(`SELECT COALESCE(service, '-') as service, COUNT(*) as c FROM logs ${where} GROUP BY service ORDER BY c DESC`).all(params);
|
|
41
|
+
const bySvc = db.prepare(`SELECT COALESCE(service, '-') as service, COUNT(*) as c FROM logs ${where} GROUP BY service ORDER BY c DESC`).all(sqlBindings(params));
|
|
39
42
|
by_service = Object.fromEntries(bySvc.map((r) => [r.service, r.c]));
|
|
40
43
|
}
|
|
41
44
|
return {
|
|
42
45
|
total,
|
|
43
|
-
errors: by_level
|
|
44
|
-
warns: by_level
|
|
45
|
-
fatals: by_level
|
|
46
|
+
errors: by_level.error ?? 0,
|
|
47
|
+
warns: by_level.warn ?? 0,
|
|
48
|
+
fatals: by_level.fatal ?? 0,
|
|
46
49
|
by_level,
|
|
47
50
|
by_service
|
|
48
51
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/lib/parse-time.ts
|
|
3
|
+
function parseTime(val) {
|
|
4
|
+
if (!val)
|
|
5
|
+
return;
|
|
6
|
+
const m = val.match(/^(\d+(?:\.\d+)?)(m|h|d|w)$/);
|
|
7
|
+
if (!m)
|
|
8
|
+
return val;
|
|
9
|
+
const [, amount, unit] = m;
|
|
10
|
+
if (!amount || !unit)
|
|
11
|
+
return val;
|
|
12
|
+
const secondsByUnit = {
|
|
13
|
+
m: 60,
|
|
14
|
+
h: 3600,
|
|
15
|
+
d: 86400,
|
|
16
|
+
w: 604800
|
|
17
|
+
};
|
|
18
|
+
const seconds = secondsByUnit[unit];
|
|
19
|
+
if (seconds === undefined)
|
|
20
|
+
return val;
|
|
21
|
+
const n = Number.parseFloat(amount);
|
|
22
|
+
const ms = n * seconds * 1000;
|
|
23
|
+
return new Date(Date.now() - ms).toISOString();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { parseTime };
|