diff --git a/src/diagnostics.test.ts b/src/diagnostics.test.ts index 56f92ec..fa49f49 100644 --- a/src/diagnostics.test.ts +++ b/src/diagnostics.test.ts @@ -1,6 +1,6 @@ import { describe, it } from "node:test"; import assert from "node:assert/strict"; -import { parseSfuMetrics } from "./diagnostics"; +import { parseSfuMetrics, sfuMetricsUrl } from "./diagnostics"; describe("parseSfuMetrics", () => { it("keeps gryt_sfu series, sums labelled ones and drops the rest", () => { @@ -19,3 +19,13 @@ describe("parseSfuMetrics", () => { }); }); }); + +describe("sfuMetricsUrl", () => { + it("prefers SFU_METRICS_URL, and otherwise guesses port 9091 on the SFU's host", () => { + assert.equal(sfuMetricsUrl({ SFU_METRICS_URL: "http://x:1/m", SFU_WS_HOST: "ws://sfu:9092" }), "http://x:1/m"); + assert.equal(sfuMetricsUrl({ SFU_WS_HOST: "ws://sfu:9092" }), "http://sfu:9091/metrics"); + assert.equal(sfuMetricsUrl({ SFU_WS_HOST: "wss://sfu.example.com" }), "http://sfu.example.com:9091/metrics"); + assert.equal(sfuMetricsUrl({ SFU_WS_HOST: "ws://[::1]:9092" }), "http://[::1]:9091/metrics"); + assert.equal(sfuMetricsUrl({}), undefined); + }); +}); diff --git a/src/diagnostics.ts b/src/diagnostics.ts index f373fc9..562c77e 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -6,7 +6,7 @@ export interface DiagnosticsSnapshot { uptimeSeconds: number; online: number; sfu: ReturnType | null; - /** Null when SFU_METRICS_URL is unset or the SFU did not answer. */ + /** Null when the SFU's metrics did not answer. */ sfuMetrics: Record | null; voice: { channelId: string; @@ -34,6 +34,17 @@ export function parseSfuMetrics(text: string): Record { return out; } +/** SFU_METRICS_URL, or the SFU's default metrics port on the host SFU_WS_HOST names. */ +export function sfuMetricsUrl(env: NodeJS.ProcessEnv = process.env): string | undefined { + if (env.SFU_METRICS_URL) return env.SFU_METRICS_URL; + try { + const host = new URL(env.SFU_WS_HOST ?? "").hostname; + return host ? `http://${host}:9091/metrics` : undefined; + } catch { + return undefined; + } +} + async function readSfuMetrics(url: string | undefined): Promise | null> { if (!url) return null; try { @@ -72,7 +83,7 @@ export async function collectDiagnostics( uptimeSeconds: Math.round(process.uptime()), online, sfu: sfuClient?.getConnectionStatus() ?? null, - sfuMetrics: await readSfuMetrics(process.env.SFU_METRICS_URL), + sfuMetrics: await readSfuMetrics(sfuMetricsUrl()), voice: [...rooms].map(([channelId, members]) => ({ channelId, members })), }; }