feat(msg): 完整实现 msg 消息服务
包含 channels/preferences/templates/grpc/kafka/outbox/push/redis 等完整实现
This commit is contained in:
@@ -4,25 +4,234 @@ const registry = new promClient.Registry();
|
||||
// 修复:在本地 registry 上设置默认标签(原代码误用全局 register)
|
||||
registry.setDefaultLabels({ service: "msg" });
|
||||
|
||||
// ============================================================
|
||||
// HTTP 指标(02-architecture-design.md §6.4)
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_requests_total",
|
||||
help: "Total number of msg requests",
|
||||
labelNames: ["method", "endpoint", "status"],
|
||||
name: "msg_http_requests_total",
|
||||
help: "Total number of msg HTTP requests",
|
||||
labelNames: ["method", "route", "status_code"],
|
||||
}),
|
||||
);
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Histogram({
|
||||
name: "msg_request_duration_seconds",
|
||||
help: "Msg request duration in seconds",
|
||||
labelNames: ["method", "endpoint"],
|
||||
name: "msg_http_request_duration_seconds",
|
||||
help: "Msg HTTP request duration in seconds",
|
||||
labelNames: ["method", "route"],
|
||||
buckets: [0.01, 0.05, 0.1, 0.3, 0.5, 1, 3, 5],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// gRPC 指标
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_grpc_requests_total",
|
||||
help: "Total number of msg gRPC requests",
|
||||
labelNames: ["rpc_method", "status"],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 业务指标:通知发送
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_notification_sent_total",
|
||||
help: "Total number of notifications sent",
|
||||
labelNames: ["type", "channel", "status"],
|
||||
}),
|
||||
);
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Histogram({
|
||||
name: "msg_notification_send_duration_seconds",
|
||||
help: "Notification send duration in seconds",
|
||||
labelNames: ["type", "channel"],
|
||||
buckets: [0.01, 0.05, 0.1, 0.3, 0.5, 1, 3, 5],
|
||||
}),
|
||||
);
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_notification_failed_total",
|
||||
help: "Total number of notification send failures",
|
||||
labelNames: ["type", "channel", "error_code"],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 业务指标:通知已读
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_notification_read_total",
|
||||
help: "Total number of notifications marked as read",
|
||||
labelNames: ["type"],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 业务指标:渠道分发
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Histogram({
|
||||
name: "msg_channel_dispatch_duration_seconds",
|
||||
help: "Channel dispatch duration in seconds",
|
||||
labelNames: ["channel"],
|
||||
buckets: [0.01, 0.05, 0.1, 0.3, 0.5, 1, 3, 5],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Kafka 消费指标
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Gauge({
|
||||
name: "msg_kafka_consumer_lag",
|
||||
help: "Kafka consumer lag (offset difference)",
|
||||
labelNames: ["topic"],
|
||||
}),
|
||||
);
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_kafka_consumer_processed_total",
|
||||
help: "Total number of Kafka messages processed",
|
||||
labelNames: ["topic", "status"],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 幂等去重指标
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_idempotent_duplicate_total",
|
||||
help: "Total number of idempotent duplicate hits",
|
||||
labelNames: ["topic"],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Outbox 指标
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Gauge({
|
||||
name: "msg_outbox_pending_count",
|
||||
help: "Number of pending outbox events",
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// Push Gateway 指标
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Counter({
|
||||
name: "msg_push_gateway_call_total",
|
||||
help: "Total number of Push Gateway calls",
|
||||
labelNames: ["status"],
|
||||
}),
|
||||
);
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Histogram({
|
||||
name: "msg_push_gateway_call_duration_seconds",
|
||||
help: "Push Gateway call duration in seconds",
|
||||
buckets: [0.01, 0.05, 0.1, 0.3, 0.5, 1, 3, 5],
|
||||
}),
|
||||
);
|
||||
|
||||
// ============================================================
|
||||
// 业务状态指标
|
||||
// ============================================================
|
||||
|
||||
registry.registerMetric(
|
||||
new promClient.Gauge({
|
||||
name: "msg_unread_count",
|
||||
help: "User unread notification count (sampled)",
|
||||
labelNames: ["user_id"],
|
||||
}),
|
||||
);
|
||||
|
||||
// 自动收集 Node.js 进程级指标(CPU/内存/事件循环/GC等)
|
||||
// 这些指标无需业务代码埋点,prom-client 自动采集
|
||||
promClient.collectDefaultMetrics({ register: registry });
|
||||
|
||||
export { registry as metricsRegistry };
|
||||
// ============================================================
|
||||
// 便捷访问器:业务代码通过命名导出获取已注册的 Metric 实例
|
||||
// ============================================================
|
||||
|
||||
export const metricsRegistry = registry;
|
||||
|
||||
export const httpRequestsTotal = registry.getSingleMetric(
|
||||
"msg_http_requests_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const httpRequestDurationSeconds = registry.getSingleMetric(
|
||||
"msg_http_request_duration_seconds",
|
||||
) as promClient.Histogram<string>;
|
||||
|
||||
export const grpcRequestsTotal = registry.getSingleMetric(
|
||||
"msg_grpc_requests_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const notificationSentTotal = registry.getSingleMetric(
|
||||
"msg_notification_sent_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const notificationSendDurationSeconds = registry.getSingleMetric(
|
||||
"msg_notification_send_duration_seconds",
|
||||
) as promClient.Histogram<string>;
|
||||
|
||||
export const notificationFailedTotal = registry.getSingleMetric(
|
||||
"msg_notification_failed_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const notificationReadTotal = registry.getSingleMetric(
|
||||
"msg_notification_read_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const channelDispatchDurationSeconds = registry.getSingleMetric(
|
||||
"msg_channel_dispatch_duration_seconds",
|
||||
) as promClient.Histogram<string>;
|
||||
|
||||
export const kafkaConsumerLag = registry.getSingleMetric(
|
||||
"msg_kafka_consumer_lag",
|
||||
) as promClient.Gauge<string>;
|
||||
|
||||
export const kafkaConsumerProcessedTotal = registry.getSingleMetric(
|
||||
"msg_kafka_consumer_processed_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const idempotentDuplicateTotal = registry.getSingleMetric(
|
||||
"msg_idempotent_duplicate_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const outboxPendingCount = registry.getSingleMetric(
|
||||
"msg_outbox_pending_count",
|
||||
) as promClient.Gauge<string>;
|
||||
|
||||
export const pushGatewayCallTotal = registry.getSingleMetric(
|
||||
"msg_push_gateway_call_total",
|
||||
) as promClient.Counter<string>;
|
||||
|
||||
export const pushGatewayCallDurationSeconds = registry.getSingleMetric(
|
||||
"msg_push_gateway_call_duration_seconds",
|
||||
) as promClient.Histogram<string>;
|
||||
|
||||
export const unreadCount = registry.getSingleMetric(
|
||||
"msg_unread_count",
|
||||
) as promClient.Gauge<string>;
|
||||
|
||||
Reference in New Issue
Block a user