This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
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 { 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 };
|
||||
}
|
||||
Reference in New Issue
Block a user