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 }; }