@hasna/logs 0.3.2 → 0.3.4

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 CHANGED
@@ -2,7 +2,7 @@
2
2
  // @bun
3
3
  import {
4
4
  runJob
5
- } from "../index-wbsq8qjd.js";
5
+ } from "../index-fzmz9aqs.js";
6
6
  import {
7
7
  createPage,
8
8
  createProject,
@@ -10,6 +10,7 @@ import {
10
10
  ingestLog,
11
11
  listPages,
12
12
  listProjects,
13
+ resolveProjectId,
13
14
  summarizeLogs
14
15
  } from "../index-5tvnhvgr.js";
15
16
  import {
@@ -24,7 +25,7 @@ import {
24
25
  __commonJS,
25
26
  __require,
26
27
  __toESM
27
- } from "../index-g8dczzvv.js";
28
+ } from "../index-re3ntm60.js";
28
29
 
29
30
  // node_modules/commander/lib/error.js
30
31
  var require_error = __commonJS((exports) => {
@@ -2136,12 +2137,17 @@ var {
2136
2137
  } = import__.default;
2137
2138
 
2138
2139
  // src/cli/index.ts
2140
+ function resolveProject(nameOrId) {
2141
+ if (!nameOrId)
2142
+ return;
2143
+ return resolveProjectId(getDb(), nameOrId) ?? nameOrId;
2144
+ }
2139
2145
  var program2 = new Command().name("logs").description("@hasna/logs \u2014 log aggregation and monitoring").version("0.0.1");
2140
- program2.command("list").description("Search and list logs").option("--project <id>", "Filter by project ID").option("--page <id>", "Filter by page ID").option("--level <levels>", "Comma-separated levels (error,warn,info,debug,fatal)").option("--service <name>", "Filter by service").option("--since <iso>", "Since timestamp or relative (1h, 24h, 7d)").option("--text <query>", "Full-text search").option("--limit <n>", "Max results", "100").option("--format <fmt>", "Output format: table|json|compact", "table").action((opts) => {
2146
+ program2.command("list").description("Search and list logs").option("--project <name|id>", "Filter by project name or ID").option("--page <id>", "Filter by page ID").option("--level <levels>", "Comma-separated levels (error,warn,info,debug,fatal)").option("--service <name>", "Filter by service").option("--since <iso>", "Since timestamp or relative (1h, 24h, 7d)").option("--text <query>", "Full-text search").option("--limit <n>", "Max results", "100").option("--format <fmt>", "Output format: table|json|compact", "table").action((opts) => {
2141
2147
  const db = getDb();
2142
2148
  const since = parseRelativeTime(opts.since);
2143
2149
  const rows = searchLogs(db, {
2144
- project_id: opts.project,
2150
+ project_id: resolveProject(opts.project),
2145
2151
  page_id: opts.page,
2146
2152
  level: opts.level ? opts.level.split(",") : undefined,
2147
2153
  service: opts.service,
@@ -2165,13 +2171,13 @@ program2.command("list").description("Search and list logs").option("--project <
2165
2171
  console.log(`
2166
2172
  ${rows.length} log(s)`);
2167
2173
  });
2168
- program2.command("tail").description("Show most recent logs").option("--project <id>").option("--n <count>", "Number of logs", "50").action((opts) => {
2169
- const rows = tailLogs(getDb(), opts.project, Number(opts.n));
2174
+ program2.command("tail").description("Show most recent logs").option("--project <name|id>", "Project name or ID").option("--n <count>", "Number of logs", "50").action((opts) => {
2175
+ const rows = tailLogs(getDb(), resolveProject(opts.project), Number(opts.n));
2170
2176
  for (const r of rows)
2171
2177
  console.log(`${r.timestamp} ${pad(r.level.toUpperCase(), 5)} ${r.message}`);
2172
2178
  });
2173
- program2.command("summary").description("Error/warn summary by service").option("--project <id>").option("--since <time>", "Relative time (1h, 24h, 7d)", "24h").action((opts) => {
2174
- const summary = summarizeLogs(getDb(), opts.project, parseRelativeTime(opts.since));
2179
+ program2.command("summary").description("Error/warn summary by service").option("--project <name|id>", "Project name or ID").option("--since <time>", "Relative time (1h, 24h, 7d)", "24h").action((opts) => {
2180
+ const summary = summarizeLogs(getDb(), resolveProject(opts.project), parseRelativeTime(opts.since));
2175
2181
  if (!summary.length) {
2176
2182
  console.log("No errors/warnings in this window.");
2177
2183
  return;
@@ -2179,8 +2185,8 @@ program2.command("summary").description("Error/warn summary by service").option(
2179
2185
  for (const s of summary)
2180
2186
  console.log(`${pad(s.level.toUpperCase(), 5)} ${pad(s.service ?? "-", 15)} count=${s.count} latest=${s.latest}`);
2181
2187
  });
2182
- program2.command("push <message>").description("Push a log entry").option("--level <level>", "Log level", "info").option("--service <name>").option("--project <id>").option("--trace <id>", "Trace ID").action((message, opts) => {
2183
- const row = ingestLog(getDb(), { level: opts.level, message, service: opts.service, project_id: opts.project, trace_id: opts.trace });
2188
+ program2.command("push <message>").description("Push a log entry").option("--level <level>", "Log level", "info").option("--service <name>").option("--project <name|id>", "Project name or ID").option("--trace <id>", "Trace ID").action((message, opts) => {
2189
+ const row = ingestLog(getDb(), { level: opts.level, message, service: opts.service, project_id: resolveProject(opts.project), trace_id: opts.trace });
2184
2190
  console.log(`Logged: ${row.id}`);
2185
2191
  });
2186
2192
  var projectCmd = program2.command("project").description("Manage projects");
@@ -2198,44 +2204,44 @@ projectCmd.command("list").action(() => {
2198
2204
  console.log(`${p.id} ${p.name} ${p.base_url ?? ""} ${p.github_repo ?? ""}`);
2199
2205
  });
2200
2206
  var pageCmd = program2.command("page").description("Manage pages");
2201
- pageCmd.command("add").option("--project <id>").option("--url <url>").option("--name <name>").action((opts) => {
2207
+ pageCmd.command("add").option("--project <name|id>", "Project name or ID").option("--url <url>").option("--name <name>").action((opts) => {
2202
2208
  if (!opts.project || !opts.url) {
2203
2209
  console.error("--project and --url required");
2204
2210
  process.exit(1);
2205
2211
  }
2206
- const p = createPage(getDb(), { project_id: opts.project, url: opts.url, name: opts.name });
2212
+ const p = createPage(getDb(), { project_id: resolveProject(opts.project), url: opts.url, name: opts.name });
2207
2213
  console.log(`Page registered: ${p.id} \u2014 ${p.url}`);
2208
2214
  });
2209
- pageCmd.command("list").option("--project <id>").action((opts) => {
2215
+ pageCmd.command("list").option("--project <name|id>", "Project name or ID").action((opts) => {
2210
2216
  if (!opts.project) {
2211
2217
  console.error("--project required");
2212
2218
  process.exit(1);
2213
2219
  }
2214
- const pages = listPages(getDb(), opts.project);
2220
+ const pages = listPages(getDb(), resolveProject(opts.project));
2215
2221
  for (const p of pages)
2216
2222
  console.log(`${p.id} ${p.url} last=${p.last_scanned_at ?? "never"}`);
2217
2223
  });
2218
2224
  var jobCmd = program2.command("job").description("Manage scan jobs");
2219
- jobCmd.command("create").option("--project <id>").option("--schedule <cron>", "Cron expression", "*/30 * * * *").action((opts) => {
2225
+ jobCmd.command("create").option("--project <name|id>", "Project name or ID").option("--schedule <cron>", "Cron expression", "*/30 * * * *").action((opts) => {
2220
2226
  if (!opts.project) {
2221
2227
  console.error("--project required");
2222
2228
  process.exit(1);
2223
2229
  }
2224
- const j = createJob(getDb(), { project_id: opts.project, schedule: opts.schedule });
2230
+ const j = createJob(getDb(), { project_id: resolveProject(opts.project), schedule: opts.schedule });
2225
2231
  console.log(`Job created: ${j.id} \u2014 ${j.schedule}`);
2226
2232
  });
2227
- jobCmd.command("list").option("--project <id>").action((opts) => {
2228
- const jobs = listJobs(getDb(), opts.project);
2233
+ jobCmd.command("list").option("--project <name|id>", "Project name or ID").action((opts) => {
2234
+ const jobs = listJobs(getDb(), resolveProject(opts.project));
2229
2235
  for (const j of jobs)
2230
2236
  console.log(`${j.id} ${j.schedule} enabled=${j.enabled} last=${j.last_run_at ?? "never"}`);
2231
2237
  });
2232
- program2.command("scan").description("Run an immediate scan for a job").option("--job <id>").option("--project <id>").action(async (opts) => {
2238
+ program2.command("scan").description("Run an immediate scan for a job").option("--job <id>").option("--project <name|id>", "Project name or ID").action(async (opts) => {
2233
2239
  if (!opts.job) {
2234
2240
  console.error("--job required");
2235
2241
  process.exit(1);
2236
2242
  }
2237
2243
  const db = getDb();
2238
- const job = (await import("../jobs-02z4fzsn.js")).getJob(db, opts.job);
2244
+ const job = (await import("../jobs-ypmmc2ma.js")).getJob(db, opts.job);
2239
2245
  if (!job) {
2240
2246
  console.error("Job not found");
2241
2247
  process.exit(1);
@@ -2244,9 +2250,15 @@ program2.command("scan").description("Run an immediate scan for a job").option("
2244
2250
  await runJob(db, job.id, job.project_id, job.page_id ?? undefined);
2245
2251
  console.log("Scan complete.");
2246
2252
  });
2247
- program2.command("watch").description("Stream new logs in real time with color coding").option("--project <id>").option("--level <levels>", "Comma-separated levels").option("--service <name>").action(async (opts) => {
2253
+ 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) => {
2248
2254
  const db = getDb();
2249
- const { searchLogs: searchLogs2 } = await import("../query-tcg3bm9s.js");
2255
+ const { searchLogs: searchLogs2 } = await import("../query-shjjj67k.js");
2256
+ let projectId = opts.project;
2257
+ if (projectId) {
2258
+ const proj = db.query("SELECT id FROM projects WHERE id = ? OR name = ?").get(projectId, projectId);
2259
+ if (proj)
2260
+ projectId = proj.id;
2261
+ }
2250
2262
  const COLORS = {
2251
2263
  debug: "\x1B[90m",
2252
2264
  info: "\x1B[36m",
@@ -2256,15 +2268,16 @@ program2.command("watch").description("Stream new logs in real time with color c
2256
2268
  };
2257
2269
  const RESET = "\x1B[0m";
2258
2270
  const BOLD = "\x1B[1m";
2259
- let lastTimestamp = new Date().toISOString();
2271
+ let lastTimestamp = opts.since ? new Date(opts.since).toISOString() : new Date().toISOString();
2260
2272
  let errorCount = 0;
2261
2273
  let warnCount = 0;
2274
+ const pollIntervalMs = Math.max(100, Number(opts.interval) || 500);
2262
2275
  process.stdout.write(`\x1B[2J\x1B[H`);
2263
- console.log(`${BOLD}@hasna/logs watch${RESET} \u2014 Ctrl+C to exit
2276
+ console.log(`${BOLD}@hasna/logs watch${RESET} \u2014 Ctrl+C to exit${projectId ? ` [project: ${opts.project}]` : ""}
2264
2277
  `);
2265
2278
  const poll = () => {
2266
2279
  const rows = searchLogs2(db, {
2267
- project_id: opts.project,
2280
+ project_id: projectId,
2268
2281
  level: opts.level ? opts.level.split(",") : undefined,
2269
2282
  service: opts.service,
2270
2283
  since: lastTimestamp,
@@ -2286,7 +2299,7 @@ program2.command("watch").description("Stream new logs in real time with color c
2286
2299
  }
2287
2300
  process.stdout.write(`\x1B]2;logs: ${errorCount}E ${warnCount}W\x07`);
2288
2301
  };
2289
- const interval = setInterval(poll, 500);
2302
+ const interval = setInterval(poll, pollIntervalMs);
2290
2303
  process.on("SIGINT", () => {
2291
2304
  clearInterval(interval);
2292
2305
  console.log(`
@@ -2295,12 +2308,12 @@ Errors: ${errorCount} Warnings: ${warnCount}`);
2295
2308
  process.exit(0);
2296
2309
  });
2297
2310
  });
2298
- program2.command("export").description("Export logs to JSON or CSV").option("--project <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) => {
2299
- const { exportToCsv, exportToJson } = await import("../export-yjaar93b.js");
2311
+ 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) => {
2312
+ const { exportToCsv, exportToJson } = await import("../export-c3eqjste.js");
2300
2313
  const { createWriteStream } = await import("fs");
2301
2314
  const db = getDb();
2302
2315
  const options = {
2303
- project_id: opts.project,
2316
+ project_id: resolveProject(opts.project),
2304
2317
  since: parseRelativeTime(opts.since),
2305
2318
  level: opts.level,
2306
2319
  service: opts.service,
@@ -2322,7 +2335,7 @@ Exported ${count} log(s)
2322
2335
  }
2323
2336
  });
2324
2337
  program2.command("health").description("Show server health and DB stats").action(async () => {
2325
- const { getHealth } = await import("../health-egdb00st.js");
2338
+ const { getHealth } = await import("../health-9792c1rc.js");
2326
2339
  const h = getHealth(getDb());
2327
2340
  console.log(JSON.stringify(h, null, 2));
2328
2341
  });
@@ -0,0 +1,10 @@
1
+ // @bun
2
+ import {
3
+ exportToCsv,
4
+ exportToJson
5
+ } from "./index-eh9bkbpa.js";
6
+ import"./index-re3ntm60.js";
7
+ export {
8
+ exportToJson,
9
+ exportToCsv
10
+ };
@@ -0,0 +1,8 @@
1
+ // @bun
2
+ import {
3
+ getHealth
4
+ } from "./index-xjn8gam3.js";
5
+ import"./index-re3ntm60.js";
6
+ export {
7
+ getHealth
8
+ };