feat(monitoring): add backend protocol metrics to network stats and ops dashboard

This commit is contained in:
2026-03-23 07:17:33 +00:00
parent 474cc328dd
commit 2f8c04edc4
12 changed files with 282 additions and 46 deletions

View File

@@ -558,6 +558,7 @@ export class MetricsManager {
throughputByIP: new Map<string, { in: number; out: number }>(),
requestsPerSecond: 0,
requestsTotal: 0,
backends: [] as Array<any>,
};
}
@@ -590,6 +591,73 @@ export class MetricsManager {
const requestsPerSecond = proxyMetrics.requests.perSecond();
const requestsTotal = proxyMetrics.requests.total();
// Collect backend protocol data
const backendMetrics = proxyMetrics.backends.byBackend();
const protocolCache = proxyMetrics.backends.detectedProtocols();
// Index protocol cache by "host:port"
const cacheByKey = new Map<string, (typeof protocolCache)[number]>();
for (const entry of protocolCache) {
cacheByKey.set(`${entry.host}:${entry.port}`, entry);
}
const backends: Array<any> = [];
const seen = new Set<string>();
for (const [key, bm] of backendMetrics) {
seen.add(key);
const cache = cacheByKey.get(key);
backends.push({
backend: key,
domain: cache?.domain ?? null,
protocol: bm.protocol,
activeConnections: bm.activeConnections,
totalConnections: bm.totalConnections,
connectErrors: bm.connectErrors,
handshakeErrors: bm.handshakeErrors,
requestErrors: bm.requestErrors,
avgConnectTimeMs: Math.round(bm.avgConnectTimeMs * 10) / 10,
poolHitRate: Math.round(bm.poolHitRate * 1000) / 1000,
h2Failures: bm.h2Failures,
h2Suppressed: cache?.h2Suppressed ?? false,
h3Suppressed: cache?.h3Suppressed ?? false,
h2CooldownRemainingSecs: cache?.h2CooldownRemainingSecs ?? null,
h3CooldownRemainingSecs: cache?.h3CooldownRemainingSecs ?? null,
h2ConsecutiveFailures: cache?.h2ConsecutiveFailures ?? null,
h3ConsecutiveFailures: cache?.h3ConsecutiveFailures ?? null,
h3Port: cache?.h3Port ?? null,
cacheAgeSecs: cache?.ageSecs ?? null,
});
}
// Include protocol cache entries with no matching backend metric
for (const entry of protocolCache) {
const key = `${entry.host}:${entry.port}`;
if (!seen.has(key)) {
backends.push({
backend: key,
domain: entry.domain,
protocol: entry.protocol,
activeConnections: 0,
totalConnections: 0,
connectErrors: 0,
handshakeErrors: 0,
requestErrors: 0,
avgConnectTimeMs: 0,
poolHitRate: 0,
h2Failures: 0,
h2Suppressed: entry.h2Suppressed,
h3Suppressed: entry.h3Suppressed,
h2CooldownRemainingSecs: entry.h2CooldownRemainingSecs,
h3CooldownRemainingSecs: entry.h3CooldownRemainingSecs,
h2ConsecutiveFailures: entry.h2ConsecutiveFailures,
h3ConsecutiveFailures: entry.h3ConsecutiveFailures,
h3Port: entry.h3Port,
cacheAgeSecs: entry.ageSecs,
});
}
}
return {
connectionsByIP,
throughputRate,
@@ -599,6 +667,7 @@ export class MetricsManager {
throughputByIP,
requestsPerSecond,
requestsTotal,
backends,
};
}, 1000); // 1s cache — matches typical dashboard poll interval
}