prom-client: add active connection gauge

This commit is contained in:
undefined committed 2025-07-24 14:00:49 +08:00
1 parent 4b2d4c74cd
commit 261a210da2
2 files changed
+28

No files matched your search

+14
View File
@@ -346,6 +346,7 @@ export class WebService<C extends CordisContext = CordisContext> extends Service
private wsLayers = []; private wsLayers = [];
private captureAllRoutes = Object.create(null); private captureAllRoutes = Object.create(null);
private customDefaultContext: C; private customDefaultContext: C;
private activeHandlers: Map<Handler<C>, { start: number, name: string }> = new Map();
renderers: Record<string, Renderer> = Object.create(null); renderers: Record<string, Renderer> = Object.create(null);
server = koa; server = koa;
@@ -473,6 +474,14 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
}); });
} }
public statistics() {
const count = Counter();
for (const [, t] of this.activeHandlers.entries()) {
count[t.name]++;
}
return count;
}
async listen() { async listen() {
this.ctx.effect(() => () => { this.ctx.effect(() => () => {
httpServer.close(); httpServer.close();
@@ -495,6 +504,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
const method = ctx.method.toLowerCase(); const method = ctx.method.toLowerCase();
const name = ((Object.hasOwn(HandlerClass, kHandler) && typeof HandlerClass[kHandler] === 'string') const name = ((Object.hasOwn(HandlerClass, kHandler) && typeof HandlerClass[kHandler] === 'string')
? HandlerClass[kHandler] : HandlerClass.name).replace(/Handler$/, ''); ? HandlerClass[kHandler] : HandlerClass.name).replace(/Handler$/, '');
this.activeHandlers.set(h, { start: Date.now(), name });
try { try {
const operation = (method === 'post' && ctx.request.body?.operation) const operation = (method === 'post' && ctx.request.body?.operation)
? `_${ctx.request.body.operation}`.replace(/_([a-z])/gm, (s) => s[1].toUpperCase()) ? `_${ctx.request.body.operation}`.replace(/_([a-z])/gm, (s) => s[1].toUpperCase())
@@ -565,6 +575,8 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
h.response.type = 'text/plain'; h.response.type = 'text/plain';
h.response.body = `${err.message}\n${err.stack}`; h.response.body = `${err.message}\n${err.stack}`;
} }
} finally {
this.activeHandlers.delete(h);
} }
} }
@@ -599,6 +611,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
ctx.handler = h; ctx.handler = h;
h.conn = conn; h.conn = conn;
let closed = false; let closed = false;
this.activeHandlers.set(h, { start: Date.now(), name: HandlerClass.name });
const clean = async (err?: Error) => { const clean = async (err?: Error) => {
if (closed) return; if (closed) return;
@@ -616,6 +629,7 @@ ${c.response.status} ${endTime - startTime}ms ${c.response.length}`);
} }
} finally { } finally {
await sub.dispose(); await sub.dispose();
this.activeHandlers.delete(h);
} }
}; };
+14
View File
@@ -66,6 +66,20 @@ export function createRegistry(ctx: Context) {
labelNames: ['type'], labelNames: ['type'],
}); });
ctx.inject(['server'], () => {
const gauge = createMetric(Gauge, 'hydro_active_handler', 'active handler count', {
async collect() {
const stats = ctx.server.statistics();
this.reset();
for (const key in stats) this.set({ type: key }, stats[key]);
},
labelNames: ['type'],
});
return () => {
gauge.remove();
};
});
const eventCounter = createMetric(Counter, 'hydro_eventcount', 'eventcount', { const eventCounter = createMetric(Counter, 'hydro_eventcount', 'eventcount', {
labelNames: ['name'], labelNames: ['name'],
}); });