Files
maestro/src/bridge/metrics-subsystem.ts
T
oss-sync 57702b4f34
CI / build-and-test (push) Canceled after 0s
sync: update from private repo (2336949a)
2026-09-17 11:29:31 +00:00

57 lines
2.6 KiB
TypeScript

import express from 'express';
import { logger } from '../logger.js';
import { ConfigManager } from '../config-manager.js';
import { createWorkerRegistry } from '../metrics/registry.js';
import { createWorkerMetrics, type WorkerMetrics } from '../metrics/worker-metrics.js';
import { createMetricsHandler } from '../metrics/http-handler.js';
/**
* Phase 3b: Prometheus /metrics endpoint, extracted verbatim from
* createCoreServer (bridge/server.ts). Mounted BEFORE any auth middleware so
* the standard Prometheus scrape job works without a session cookie.
* Restrict scrape access at the reverse proxy / firewall layer (see help
* doc). Disabled by provider.metrics.enabled=false in config.yaml.
*/
export function setupMetricsSubsystem(
app: express.Application,
configManager: ConfigManager | undefined,
): {
workerMetrics: WorkerMetrics | null;
/** Phase 3c: shared prom-client registry so the same-process gateway mount
* can register its gateway_* counters into the same /metrics endpoint
* (one scrape serves both worker and gateway). Null when metrics are
* disabled. */
sharedPromRegistry: import('prom-client').Registry | null;
} {
const appConfig = (() => {
try { return configManager?.getConfig() ?? null; } catch {
// Configuration errors may contain credentials; report the fallback only.
logger.warn('[bridge] failed to read metrics configuration; using default metrics settings');
return null;
}
})();
const metricsCfg = appConfig?.provider?.metrics;
let workerMetrics: WorkerMetrics | null = null;
let sharedPromRegistry: import('prom-client').Registry | null = null;
if (metricsCfg?.enabled !== false) {
const prefix = metricsCfg?.prefix ?? 'aao_worker';
sharedPromRegistry = createWorkerRegistry(prefix);
workerMetrics = createWorkerMetrics(sharedPromRegistry, prefix);
// Phase 3b post-review: gate /metrics on (1) bearer token if set,
// (2) otherwise client-IP allowlist (default localhost). Labels
// like `worker_id` / `backend_id` would leak otherwise.
const metricsAuth = {
bearerToken: metricsCfg?.bearerToken,
allowedHosts: metricsCfg?.allowedHosts,
};
app.get('/metrics', createMetricsHandler(sharedPromRegistry, metricsAuth));
const authMode = metricsAuth.bearerToken
? 'bearer'
: `ip-allowlist=${(metricsAuth.allowedHosts ?? ['127.0.0.1', '::1', 'localhost']).join(',')}`;
logger.info(`[bridge] worker metrics enabled prefix=${prefix} auth=${authMode}`);
} else {
logger.info('[bridge] worker metrics disabled (provider.metrics.enabled=false)');
}
return { workerMetrics, sharedPromRegistry };
}