@hasna/logs 0.3.6 → 0.3.8
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/dist/cli/index.js +67 -4
- package/dist/count-x3n7qg3c.js +9 -0
- package/dist/diagnose-e0w5rwbc.js +9 -0
- package/dist/index-14dvwcf1.js +45 -0
- package/dist/index-1f2ghyhm.js +540 -0
- package/dist/index-7qhh666n.js +1241 -0
- package/dist/index-7w7v7hnr.js +76 -0
- package/dist/index-997bkzr2.js +15 -0
- package/dist/index-edn08m6f.js +51 -0
- package/dist/index-exeq2gs6.js +79 -0
- package/dist/mcp/index.js +14 -78
- package/dist/query-6s5gqkck.js +15 -0
- package/dist/server/index.js +11 -9
- package/package.json +1 -1
- package/src/cli/index.ts +67 -0
- package/src/lib/count.ts +10 -0
- package/src/mcp/index.ts +1 -0
package/dist/cli/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
import {
|
|
4
4
|
runJob
|
|
5
|
-
} from "../index-
|
|
5
|
+
} from "../index-7qhh666n.js";
|
|
6
6
|
import {
|
|
7
7
|
createPage,
|
|
8
8
|
createProject,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
listProjects,
|
|
13
13
|
resolveProjectId,
|
|
14
14
|
summarizeLogs
|
|
15
|
-
} from "../index-
|
|
15
|
+
} from "../index-1f2ghyhm.js";
|
|
16
16
|
import {
|
|
17
17
|
createJob,
|
|
18
18
|
listJobs
|
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
import {
|
|
21
21
|
searchLogs,
|
|
22
22
|
tailLogs
|
|
23
|
-
} from "../index-
|
|
23
|
+
} from "../index-exeq2gs6.js";
|
|
24
|
+
import"../index-997bkzr2.js";
|
|
24
25
|
import {
|
|
25
26
|
__commonJS,
|
|
26
27
|
__require,
|
|
@@ -2283,9 +2284,46 @@ program2.command("scan").description("Run an immediate scan for a job").option("
|
|
|
2283
2284
|
await runJob(db, job.id, job.project_id, job.page_id ?? undefined);
|
|
2284
2285
|
console.log("Scan complete.");
|
|
2285
2286
|
});
|
|
2287
|
+
program2.command("diagnose").description("Health diagnosis: score, top errors, trends, failing pages").option("--project <name|id>", "Project name or ID").option("--since <time>", "Time window (1h, 24h, 7d)", "24h").option("--include <items>", "Comma-separated: top_errors,error_rate,failing_pages,perf").action(async (opts) => {
|
|
2288
|
+
const { diagnose } = await import("../diagnose-e0w5rwbc.js");
|
|
2289
|
+
const projectId = resolveProject(opts.project);
|
|
2290
|
+
if (!projectId) {
|
|
2291
|
+
console.error("--project required");
|
|
2292
|
+
process.exit(1);
|
|
2293
|
+
}
|
|
2294
|
+
const include = opts.include ? opts.include.split(",") : undefined;
|
|
2295
|
+
const result = diagnose(getDb(), projectId, opts.since, include);
|
|
2296
|
+
const scoreColor = result.health_score >= 80 ? "\x1B[32m" : result.health_score >= 50 ? "\x1B[33m" : "\x1B[31m";
|
|
2297
|
+
console.log(`
|
|
2298
|
+
${C.bold}Health Score:${C.reset} ${scoreColor}${result.health_score}/100${C.reset}`);
|
|
2299
|
+
if (result.top_errors?.length) {
|
|
2300
|
+
console.log(`
|
|
2301
|
+
${C.bold}Top Errors:${C.reset}`);
|
|
2302
|
+
for (const e of result.top_errors) {
|
|
2303
|
+
console.log(` ${C.red}${pad(String(e.count), 5)}x${C.reset} ${C.cyan}${pad(e.service ?? "-", 12)}${C.reset} ${e.message}`);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
if (result.error_rate !== undefined) {
|
|
2307
|
+
console.log(`
|
|
2308
|
+
${C.bold}Error Rate:${C.reset} ${result.error_rate.toFixed(2)}%`);
|
|
2309
|
+
}
|
|
2310
|
+
if (result.failing_pages?.length) {
|
|
2311
|
+
console.log(`
|
|
2312
|
+
${C.bold}Failing Pages:${C.reset}`);
|
|
2313
|
+
for (const p of result.failing_pages)
|
|
2314
|
+
console.log(` ${C.red}\u2717${C.reset} ${p.url} (${p.error_count} errors)`);
|
|
2315
|
+
}
|
|
2316
|
+
if (result.perf_regressions?.length) {
|
|
2317
|
+
console.log(`
|
|
2318
|
+
${C.bold}Perf Regressions:${C.reset}`);
|
|
2319
|
+
for (const r of result.perf_regressions)
|
|
2320
|
+
console.log(` ${C.yellow}\u26A0${C.reset} ${r.page_url} p95=${r.p95_ms}ms`);
|
|
2321
|
+
}
|
|
2322
|
+
console.log("");
|
|
2323
|
+
});
|
|
2286
2324
|
program2.command("watch").description("Stream new logs in real time with color coding").option("--project <name|id>", "Filter by project name or ID").option("--level <levels>", "Comma-separated levels (debug,info,warn,error,fatal)").option("--service <name>", "Filter by service name").option("--interval <ms>", "Poll interval in milliseconds (default: 500)", "500").option("--since <time>", "Start from this time (default: now)").action(async (opts) => {
|
|
2287
2325
|
const db = getDb();
|
|
2288
|
-
const { searchLogs: searchLogs2 } = await import("../query-
|
|
2326
|
+
const { searchLogs: searchLogs2 } = await import("../query-6s5gqkck.js");
|
|
2289
2327
|
let projectId = opts.project;
|
|
2290
2328
|
if (projectId) {
|
|
2291
2329
|
const proj = db.query("SELECT id FROM projects WHERE id = ? OR name = ?").get(projectId, projectId);
|
|
@@ -2341,6 +2379,31 @@ Errors: ${errorCount} Warnings: ${warnCount}`);
|
|
|
2341
2379
|
process.exit(0);
|
|
2342
2380
|
});
|
|
2343
2381
|
});
|
|
2382
|
+
program2.command("count").description("Count logs with optional breakdown by level or service").option("--project <name|id>", "Project name or ID").option("--service <name>", "Filter by service").option("--level <level>", "Filter by level").option("--since <time>", "Since (1h, 24h, 7d)").option("--until <time>", "Until").option("--group-by <field>", "Breakdown: level | service").action(async (opts) => {
|
|
2383
|
+
const { countLogs } = await import("../count-x3n7qg3c.js");
|
|
2384
|
+
const result = countLogs(getDb(), {
|
|
2385
|
+
project_id: resolveProject(opts.project),
|
|
2386
|
+
service: opts.service,
|
|
2387
|
+
level: opts.level,
|
|
2388
|
+
since: opts.since,
|
|
2389
|
+
until: opts.until,
|
|
2390
|
+
group_by: opts.groupBy
|
|
2391
|
+
});
|
|
2392
|
+
console.log(`Total: ${result.total} ${C.red}Errors: ${result.errors}${C.reset} ${C.yellow}Warns: ${result.warns}${C.reset} Fatals: ${result.fatals}`);
|
|
2393
|
+
if (result.by_service) {
|
|
2394
|
+
console.log(`
|
|
2395
|
+
By Service:`);
|
|
2396
|
+
for (const [svc, cnt] of Object.entries(result.by_service)) {
|
|
2397
|
+
console.log(` ${C.cyan}${pad(svc, 20)}${C.reset} ${cnt}`);
|
|
2398
|
+
}
|
|
2399
|
+
} else if (opts.groupBy === "level") {
|
|
2400
|
+
console.log(`
|
|
2401
|
+
By Level:`);
|
|
2402
|
+
for (const [lvl, cnt] of Object.entries(result.by_level)) {
|
|
2403
|
+
console.log(` ${colorLevel(lvl)} ${cnt}`);
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
});
|
|
2344
2407
|
program2.command("export").description("Export logs to JSON or CSV").option("--project <name|id>", "Project name or ID").option("--since <time>", "Relative time or ISO").option("--level <level>").option("--service <name>").option("--format <fmt>", "json or csv", "json").option("--output <file>", "Output file (default: stdout)").option("--limit <n>", "Max rows", "100000").action(async (opts) => {
|
|
2345
2408
|
const { exportToCsv, exportToJson } = await import("../export-c3eqjste.js");
|
|
2346
2409
|
const { createWriteStream } = await import("fs");
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
import {
|
|
3
|
+
parseTime
|
|
4
|
+
} from "./index-997bkzr2.js";
|
|
5
|
+
|
|
6
|
+
// src/lib/count.ts
|
|
7
|
+
function countLogs(db, opts) {
|
|
8
|
+
const conditions = [];
|
|
9
|
+
const params = {};
|
|
10
|
+
if (opts.project_id) {
|
|
11
|
+
conditions.push("project_id = $p");
|
|
12
|
+
params.$p = opts.project_id;
|
|
13
|
+
}
|
|
14
|
+
if (opts.service) {
|
|
15
|
+
conditions.push("service = $service");
|
|
16
|
+
params.$service = opts.service;
|
|
17
|
+
}
|
|
18
|
+
if (opts.level) {
|
|
19
|
+
conditions.push("level = $level");
|
|
20
|
+
params.$level = opts.level;
|
|
21
|
+
}
|
|
22
|
+
const since = parseTime(opts.since);
|
|
23
|
+
const until = parseTime(opts.until);
|
|
24
|
+
if (since) {
|
|
25
|
+
conditions.push("timestamp >= $since");
|
|
26
|
+
params.$since = since;
|
|
27
|
+
}
|
|
28
|
+
if (until) {
|
|
29
|
+
conditions.push("timestamp <= $until");
|
|
30
|
+
params.$until = until;
|
|
31
|
+
}
|
|
32
|
+
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);
|
|
34
|
+
const by_level = Object.fromEntries(byLevel.map((r) => [r.level, r.c]));
|
|
35
|
+
const total = byLevel.reduce((s, r) => s + r.c, 0);
|
|
36
|
+
return {
|
|
37
|
+
total,
|
|
38
|
+
errors: by_level["error"] ?? 0,
|
|
39
|
+
warns: by_level["warn"] ?? 0,
|
|
40
|
+
fatals: by_level["fatal"] ?? 0,
|
|
41
|
+
by_level
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { countLogs };
|