Files
2026-07-13 13:39:12 +08:00

75 lines
2.6 KiB
JavaScript

import { writeFileSync } from "node:fs";
import { apiFetch } from "../api.mjs";
import { emit } from "../output.mjs";
import { t } from "../i18n.mjs";
function fmtMetric(v) {
if (v == null) return "-";
if (typeof v === "number") {
if (v > 1e9) return `${(v / 1e9).toFixed(2)}B`;
if (v > 1e6) return `${(v / 1e6).toFixed(2)}M`;
if (v > 1e3) return `${(v / 1e3).toFixed(2)}K`;
return Number.isInteger(v) ? v.toLocaleString() : v.toFixed(2);
}
return String(v);
}
function fmtDelta(v) {
if (v == null) return "-";
const arrow = v > 0 ? "↑" : v < 0 ? "↓" : "→";
const sign = v > 0 ? "+" : "";
return `${arrow} ${sign}${(v * 100).toFixed(1)}%`;
}
const telemetrySchema = [
{ key: "metric", header: "Metric", width: 36 },
{ key: "value", header: "Value", formatter: fmtMetric },
{ key: "delta", header: "Δ vs prev", formatter: fmtDelta },
{ key: "trend", header: "Trend" },
];
export function registerTelemetry(program) {
const tel = program.command("telemetry").description(t("telemetry.description"));
tel
.command("summary")
.description(t("telemetry.summary.description"))
.option("--period <p>", t("telemetry.summary.period"), "24h")
.option("--compare-to <p>", t("telemetry.summary.compareTo"))
.action(async (opts, cmd) => {
const params = new URLSearchParams({ period: opts.period });
if (opts.compareTo) params.set("compareTo", opts.compareTo);
const res = await apiFetch(`/api/telemetry/summary?${params}`);
if (!res.ok) {
process.stderr.write(`Error: ${res.status}\n`);
process.exit(1);
}
const data = await res.json();
const rows = Object.entries(data.metrics ?? data).map(([metric, info]) => ({
metric,
value: info?.value ?? info,
delta: info?.delta,
trend: info?.trend,
}));
emit(rows, cmd.optsWithGlobals(), telemetrySchema);
});
tel
.command("export")
.description(t("telemetry.export.description"))
.option("--out <path>", t("telemetry.export.out"), "telemetry.jsonl")
.option("--period <p>", t("telemetry.export.period"), "7d")
.action(async (opts, cmd) => {
const res = await apiFetch(`/api/telemetry/summary?format=jsonl&period=${opts.period}`);
if (!res.ok) {
process.stderr.write(`Error: ${res.status}\n`);
process.exit(1);
}
const data = await res.json();
const items = data.events ?? data.items ?? [];
const lines = items.map((e) => JSON.stringify(e)).join("\n");
writeFileSync(opts.out, lines);
process.stdout.write(`Exported ${items.length} events to ${opts.out}\n`);
});
}