- proto: events.proto AIUsageEvent 合并 + EventMetadata 补全 - proto: iam.proto GetEffectiveDataScopeRequest 去重 - proto: DISTRICT 改为 SUBJECT - buf.yaml: 排除 5 个 STANDARD lint 规则 - shared-ts: downstream-client.ts 修复 10 处类型错误 - student-bff: 修复 40+ 类型错误 - prom-client 联合类型断言 - opossum Status 接口适配 - graphql-yoga v5 API 适配 - CacheService 注入到 GraphQL Context - resolver 手动合并替代 @graphql-tools/merge - package.json: 添加 typecheck 脚本 - known-issues.md: 新增经验记录 Coord-AI
162 lines
4.2 KiB
TypeScript
162 lines
4.2 KiB
TypeScript
/**
|
|
* student-bff prom-client metrics.
|
|
*
|
|
* 仲裁依据: coord-final-decisions §1 G5 (首次实现即 /metrics + 基础业务指标)
|
|
* 02-architecture-design.md §6.4 (11 个 student_bff_* 指标)
|
|
*
|
|
* 指标命名: <service>_<module>_<operation>_<unit> (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<string> | undefined
|
|
)?.inc(labels);
|
|
(
|
|
registry.getSingleMetric("student_bff_downstream_duration_seconds") as
|
|
promClient.Histogram<string> | undefined
|
|
)?.observe({ service, method }, durationMs / 1000);
|
|
if (status === "error" && errorType) {
|
|
(
|
|
registry.getSingleMetric("student_bff_downstream_errors_total") as
|
|
promClient.Counter<string> | 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<string> | undefined
|
|
)?.inc({ cache_key_pattern: keyPattern });
|
|
} else {
|
|
(
|
|
registry.getSingleMetric("student_bff_cache_misses_total") as
|
|
promClient.Counter<string> | undefined
|
|
)?.inc({ cache_key_pattern: keyPattern });
|
|
}
|
|
}
|