/** * student-bff prom-client metrics. * * 仲裁依据: coord-final-decisions §1 G5 (首次实现即 /metrics + 基础业务指标) * 02-architecture-design.md §6.4 (11 个 student_bff_* 指标) * * 指标命名: ___ (project_rules §12) */ import promClient from "prom-client"; const registry = new promClient.Registry(); registry.setDefaultLabels({ service: "student-bff" }); // 1. 请求总数 registry.registerMetric( new promClient.Counter({ name: "student_bff_requests_total", help: "Total number of student-bff HTTP/GraphQL requests", labelNames: ["operation", "method", "status"], }), ); // 2. 请求延迟 registry.registerMetric( new promClient.Histogram({ name: "student_bff_request_duration_seconds", help: "Student-bff request duration in seconds", labelNames: ["operation", "method"], buckets: [0.01, 0.05, 0.1, 0.3, 0.5, 1, 3, 5], }), ); // 3. 下游调用总数 registry.registerMetric( new promClient.Counter({ name: "student_bff_downstream_calls_total", help: "Total downstream gRPC calls", labelNames: ["service", "method", "status"], }), ); // 4. 下游调用延迟 registry.registerMetric( new promClient.Histogram({ name: "student_bff_downstream_duration_seconds", help: "Downstream gRPC call duration in seconds", labelNames: ["service", "method"], buckets: [0.01, 0.05, 0.1, 0.3, 0.5, 1, 3, 5], }), ); // 5. 下游错误数 registry.registerMetric( new promClient.Counter({ name: "student_bff_downstream_errors_total", help: "Downstream gRPC call errors", labelNames: ["service", "method", "error_type"], }), ); // 6. 缓存命中 registry.registerMetric( new promClient.Counter({ name: "student_bff_cache_hits_total", help: "Cache hit count", labelNames: ["cache_key_pattern"], }), ); // 7. 缓存未命中 registry.registerMetric( new promClient.Counter({ name: "student_bff_cache_misses_total", help: "Cache miss count", labelNames: ["cache_key_pattern"], }), ); // 8. 熔断器状态 (P6) registry.registerMetric( new promClient.Gauge({ name: "student_bff_circuit_state", help: "Circuit breaker state (0=closed, 1=open, 2=half-open)", labelNames: ["service", "state"], }), ); // 9. SSE 连接数 (P5) registry.registerMetric( new promClient.Gauge({ name: "student_bff_sse_connections", help: "Active SSE connections", }), ); // 10. 事件消费数 (P5) registry.registerMetric( new promClient.Counter({ name: "student_bff_event_consumed_total", help: "Kafka events consumed", labelNames: ["topic", "event_type"], }), ); // 11. 推送数 (P5) registry.registerMetric( new promClient.Counter({ name: "student_bff_event_pushed_total", help: "Push-gateway push count", labelNames: ["topic", "push_status"], }), ); // 自动收集 Node.js 进程级指标 promClient.collectDefaultMetrics({ register: registry }); export { registry as metricsRegistry }; /** * 下游调用指标辅助器 (供 DownstreamClient 调用). */ export function recordDownstreamCall( service: string, method: string, status: "success" | "error", durationMs: number, errorType?: string, ): void { const labels = { service, method, status }; ( registry.getSingleMetric("student_bff_downstream_calls_total") as promClient.Counter | undefined )?.inc(labels); ( registry.getSingleMetric("student_bff_downstream_duration_seconds") as promClient.Histogram | undefined )?.observe({ service, method }, durationMs / 1000); if (status === "error" && errorType) { ( registry.getSingleMetric("student_bff_downstream_errors_total") as promClient.Counter | undefined )?.inc({ service, method, error_type: errorType }); } } /** * 缓存命中/未命中指标辅助器. */ export function recordCacheAccess(keyPattern: string, hit: boolean): void { if (hit) { ( registry.getSingleMetric("student_bff_cache_hits_total") as promClient.Counter | undefined )?.inc({ cache_key_pattern: keyPattern }); } else { ( registry.getSingleMetric("student_bff_cache_misses_total") as promClient.Counter | undefined )?.inc({ cache_key_pattern: keyPattern }); } }