add complete parent-bff implementation including: - GraphQL endpoint with depth/cost validation - ChildGuard越权校验 with redis cache and singleflight - parallel orchestration with partial failure fallback - three-level cache fallback strategy (Redis + LRU + downstream) - Kafka consumer for cache invalidation and notification push - opossum circuit breaker for downstream services - Prometheus metrics and SLO alerts - Helm chart for k8s deployment with multi-environment configs - Grafana dashboard for observability - complete unit and integration tests
108 lines
3.8 KiB
TypeScript
108 lines
3.8 KiB
TypeScript
import promClient from "prom-client";
|
||
|
||
/**
|
||
* parent-bff Prometheus 指标注册中心。
|
||
*
|
||
* 指标清单对齐 02-architecture-design.md §6.4(11 项):
|
||
* - graphql 请求总数 / 延迟
|
||
* - 下游 gRPC 调用次数 / 延迟 / 错误数
|
||
* - 缓存命中 / 未命中
|
||
* - ChildGuard 越权拦截次数
|
||
* - 熔断器状态(P6)
|
||
* - 事件消费 / 推送数(P5)
|
||
*
|
||
* 同时导出具体 Counter / Histogram / Gauge 实例,
|
||
* 便于业务代码直接 .inc() / .observe() 调用,避免通过 registry.getSingleMetric 查找。
|
||
*/
|
||
const registry = new promClient.Registry();
|
||
registry.setDefaultLabels({ service: "parent-bff" });
|
||
|
||
// === GraphQL 指标 ===
|
||
export const graphqlRequestsTotal = new promClient.Counter({
|
||
name: "parent_bff_graphql_requests_total",
|
||
help: "Total number of parent-bff GraphQL requests",
|
||
labelNames: ["operation", "status"],
|
||
});
|
||
registry.registerMetric(graphqlRequestsTotal);
|
||
|
||
export const graphqlDurationSeconds = new promClient.Histogram({
|
||
name: "parent_bff_graphql_duration_seconds",
|
||
help: "Parent-bff GraphQL request duration in seconds",
|
||
labelNames: ["operation"],
|
||
buckets: [0.01, 0.05, 0.1, 0.2, 0.3, 0.5, 1, 3, 5],
|
||
});
|
||
registry.registerMetric(graphqlDurationSeconds);
|
||
|
||
// === 下游 gRPC 调用指标 ===
|
||
export const downstreamCallsTotal = new promClient.Counter({
|
||
name: "parent_bff_downstream_calls_total",
|
||
help: "Total number of downstream gRPC calls from parent-bff",
|
||
labelNames: ["service", "rpc", "status"],
|
||
});
|
||
registry.registerMetric(downstreamCallsTotal);
|
||
|
||
export const downstreamDurationSeconds = new promClient.Histogram({
|
||
name: "parent_bff_downstream_duration_seconds",
|
||
help: "Parent-bff downstream gRPC call duration in seconds",
|
||
labelNames: ["service", "rpc"],
|
||
buckets: [0.01, 0.05, 0.1, 0.2, 0.3, 0.5, 1, 3, 5],
|
||
});
|
||
registry.registerMetric(downstreamDurationSeconds);
|
||
|
||
export const downstreamErrorsTotal = new promClient.Counter({
|
||
name: "parent_bff_downstream_errors_total",
|
||
help: "Total number of downstream gRPC call errors from parent-bff",
|
||
labelNames: ["service", "rpc", "error_type"],
|
||
});
|
||
registry.registerMetric(downstreamErrorsTotal);
|
||
|
||
// === 缓存指标 ===
|
||
export const cacheHitsTotal = new promClient.Counter({
|
||
name: "parent_bff_cache_hits_total",
|
||
help: "Total number of parent-bff cache hits",
|
||
labelNames: ["cache_key_pattern"],
|
||
});
|
||
registry.registerMetric(cacheHitsTotal);
|
||
|
||
export const cacheMissesTotal = new promClient.Counter({
|
||
name: "parent_bff_cache_misses_total",
|
||
help: "Total number of parent-bff cache misses",
|
||
labelNames: ["cache_key_pattern"],
|
||
});
|
||
registry.registerMetric(cacheMissesTotal);
|
||
|
||
// === ChildGuard 越权拦截指标 ===
|
||
export const childGuardBlocksTotal = new promClient.Counter({
|
||
name: "parent_bff_child_guard_blocks_total",
|
||
help: "Total number of ChildGuard access denials in parent-bff",
|
||
});
|
||
registry.registerMetric(childGuardBlocksTotal);
|
||
|
||
// === 熔断器状态指标(P6 启用) ===
|
||
export const circuitStateGauge = new promClient.Gauge({
|
||
name: "parent_bff_circuit_state",
|
||
help: "Parent-bff circuit breaker state per downstream service",
|
||
labelNames: ["service", "state"],
|
||
});
|
||
registry.registerMetric(circuitStateGauge);
|
||
|
||
// === Kafka 事件消费 / 推送指标(P5 启用) ===
|
||
export const eventConsumedTotal = new promClient.Counter({
|
||
name: "parent_bff_event_consumed_total",
|
||
help: "Total number of Kafka events consumed by parent-bff",
|
||
labelNames: ["topic", "event_type"],
|
||
});
|
||
registry.registerMetric(eventConsumedTotal);
|
||
|
||
export const eventPushedTotal = new promClient.Counter({
|
||
name: "parent_bff_event_pushed_total",
|
||
help: "Total number of push-gateway pushes from parent-bff",
|
||
labelNames: ["topic", "push_status"],
|
||
});
|
||
registry.registerMetric(eventPushedTotal);
|
||
|
||
// 自动收集 Node.js 进程级指标(CPU/内存/事件循环/GC 等)
|
||
promClient.collectDefaultMetrics({ register: registry });
|
||
|
||
export { registry as metricsRegistry };
|