feat(03-01): create MetricsCollector and wire into gateway
- Add MetricsCollector class with counters, model call ring buffer, event ring buffer, and active request tracking - Add system.metrics, system.events, system.activeRequests RPC handlers - Add GET /health unauthenticated HTTP endpoint for Docker HEALTHCHECK - Add totalPending() to LaneQueue for queue depth metrics - Add 20 tests for MetricsCollector
This commit is contained in:
@@ -3,11 +3,13 @@ import type { SendFn } from '../router.js';
|
||||
import { makeEvent, makeError, ErrorCode } from '../protocol.js';
|
||||
import type { SessionBridge } from '../session-bridge.js';
|
||||
import type { LaneQueue } from '../lane-queue.js';
|
||||
import type { MetricsCollector } from '../metrics.js';
|
||||
import type { Attachment } from '../../channels/types.js';
|
||||
|
||||
export interface AgentHandlerDeps {
|
||||
sessionBridge: SessionBridge;
|
||||
laneQueue: LaneQueue;
|
||||
metrics?: MetricsCollector;
|
||||
}
|
||||
|
||||
export function createAgentHandlers(deps: AgentHandlerDeps) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { GatewayRequest, OutboundMessage } from '../protocol.js';
|
||||
import { makeResponse, makeError, ErrorCode } from '../protocol.js';
|
||||
import type { MetricsSnapshot, EventEntry, ActiveRequestInfo } from '../metrics.js';
|
||||
|
||||
/** Per-session token usage report returned by system.tokenUsage. */
|
||||
export interface TokenUsageEntry {
|
||||
@@ -21,6 +22,12 @@ export interface SystemHandlerDeps {
|
||||
getUsage?: () => { totalSessions: number; activeConnections: number };
|
||||
/** Optional callback to retrieve per-session token usage data. */
|
||||
getTokenUsage?: () => TokenUsageEntry[];
|
||||
/** Optional callback to retrieve aggregated metrics snapshot. */
|
||||
getMetrics?: () => MetricsSnapshot;
|
||||
/** Optional callback to retrieve recent events. */
|
||||
getEvents?: (opts?: { level?: string; limit?: number }) => EventEntry[];
|
||||
/** Optional callback to retrieve active requests. */
|
||||
getActiveRequests?: () => ActiveRequestInfo[];
|
||||
}
|
||||
|
||||
export function createSystemHandlers(deps: SystemHandlerDeps) {
|
||||
@@ -75,5 +82,28 @@ export function createSystemHandlers(deps: SystemHandlerDeps) {
|
||||
const sessions = deps.getTokenUsage?.() ?? [];
|
||||
return makeResponse(request.id, { sessions });
|
||||
},
|
||||
|
||||
'system.metrics': async (request: GatewayRequest): Promise<OutboundMessage> => {
|
||||
if (!deps.getMetrics) {
|
||||
return makeResponse(request.id, {});
|
||||
}
|
||||
return makeResponse(request.id, deps.getMetrics());
|
||||
},
|
||||
|
||||
'system.events': async (request: GatewayRequest): Promise<OutboundMessage> => {
|
||||
if (!deps.getEvents) {
|
||||
return makeResponse(request.id, { events: [] });
|
||||
}
|
||||
const params = request.params as { level?: string; limit?: number } | undefined;
|
||||
const events = deps.getEvents({ level: params?.level, limit: params?.limit });
|
||||
return makeResponse(request.id, { events });
|
||||
},
|
||||
|
||||
'system.activeRequests': async (request: GatewayRequest): Promise<OutboundMessage> => {
|
||||
if (!deps.getActiveRequests) {
|
||||
return makeResponse(request.id, { requests: [] });
|
||||
}
|
||||
return makeResponse(request.id, { requests: deps.getActiveRequests() });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user