feat(go): expose runtime ingest metrics
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
|
||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
|
||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/health"
|
||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/metrics"
|
||||
"lingniu-vehicle-ingest/go/vehicle-gateway/internal/observability"
|
||||
)
|
||||
|
||||
@@ -33,6 +34,7 @@ func main() {
|
||||
os.Exit(1)
|
||||
}
|
||||
defer conn.Close()
|
||||
registry := metrics.NewRegistry()
|
||||
health.Start(ctx, logger, health.NewServer(env("HEALTH_ADDR", ""), "nats-kafka-bridge", []health.Check{
|
||||
{Name: "nats", Check: func(context.Context) error {
|
||||
if conn.Status() != nats.CONNECTED {
|
||||
@@ -40,7 +42,7 @@ func main() {
|
||||
}
|
||||
return nil
|
||||
}},
|
||||
}))
|
||||
}, registry))
|
||||
js, err := conn.JetStream()
|
||||
if err != nil {
|
||||
logger.Error("nats jetstream init failed", "error", err)
|
||||
@@ -78,7 +80,7 @@ func main() {
|
||||
"durable", cfg.NATSDurable,
|
||||
"filter", cfg.NATSFilter,
|
||||
"kafka_brokers", strings.Join(cfg.KafkaBrokers, ","))
|
||||
runBridge(ctx, logger, sub, writer, cfg)
|
||||
runBridge(ctx, logger, registry, sub, writer, cfg)
|
||||
}
|
||||
|
||||
type config struct {
|
||||
@@ -135,7 +137,7 @@ type bridgeMessage struct {
|
||||
ack func() error
|
||||
}
|
||||
|
||||
func runBridge(ctx context.Context, logger *slog.Logger, sub natsPullSubscription, writer kafkaBatchWriter, cfg config) {
|
||||
func runBridge(ctx context.Context, logger *slog.Logger, registry *metrics.Registry, sub natsPullSubscription, writer kafkaBatchWriter, cfg config) {
|
||||
for {
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
@@ -161,7 +163,7 @@ func runBridge(ctx context.Context, logger *slog.Logger, sub natsPullSubscriptio
|
||||
})
|
||||
}
|
||||
operationCtx, cancel := context.WithTimeout(context.WithoutCancel(ctx), cfg.OperationWait)
|
||||
err = bridgeBatch(operationCtx, writer, bridgeMessages, cfg.Route)
|
||||
err = bridgeBatch(operationCtx, registry, writer, bridgeMessages, cfg.Route)
|
||||
cancel()
|
||||
if err != nil {
|
||||
logger.Error("bridge batch failed", "count", len(bridgeMessages), "error", err)
|
||||
@@ -194,32 +196,56 @@ func ensureStream(js nats.JetStreamContext, cfg config) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func bridgeBatch(ctx context.Context, writer kafkaBatchWriter, messages []bridgeMessage, route map[string]string) error {
|
||||
func bridgeBatch(ctx context.Context, registry *metrics.Registry, writer kafkaBatchWriter, messages []bridgeMessage, route map[string]string) error {
|
||||
if len(messages) == 0 {
|
||||
return nil
|
||||
}
|
||||
kafkaMessages := make([]kafka.Message, 0, len(messages))
|
||||
for _, message := range messages {
|
||||
addBridgeSubjectMetric(registry, "vehicle_bridge_messages_total", message.subject, "received")
|
||||
topic, ok := route[message.subject]
|
||||
if !ok || topic == "" {
|
||||
addBridgeSubjectMetric(registry, "vehicle_bridge_messages_total", message.subject, "route_error")
|
||||
return fmt.Errorf("kafka topic not configured for nats subject %q", message.subject)
|
||||
}
|
||||
kafkaMessages = append(kafkaMessages, kafkaMessage(topic, message.data))
|
||||
}
|
||||
if err := writer.WriteMessages(ctx, kafkaMessages...); err != nil {
|
||||
for _, message := range kafkaMessages {
|
||||
addBridgeTopicMetric(registry, "vehicle_bridge_kafka_writes_total", message.Topic, "error")
|
||||
}
|
||||
return err
|
||||
}
|
||||
for _, message := range kafkaMessages {
|
||||
addBridgeTopicMetric(registry, "vehicle_bridge_kafka_writes_total", message.Topic, "ok")
|
||||
}
|
||||
for _, message := range messages {
|
||||
if message.ack == nil {
|
||||
continue
|
||||
}
|
||||
if err := message.ack(); err != nil {
|
||||
addBridgeSubjectMetric(registry, "vehicle_bridge_nats_acks_total", message.subject, "error")
|
||||
return err
|
||||
}
|
||||
addBridgeSubjectMetric(registry, "vehicle_bridge_nats_acks_total", message.subject, "ok")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addBridgeSubjectMetric(registry *metrics.Registry, name string, subject string, status string) {
|
||||
if registry == nil {
|
||||
return
|
||||
}
|
||||
registry.IncCounter(name, metrics.Labels{"subject": subject, "status": status})
|
||||
}
|
||||
|
||||
func addBridgeTopicMetric(registry *metrics.Registry, name string, topic string, status string) {
|
||||
if registry == nil {
|
||||
return
|
||||
}
|
||||
registry.IncCounter(name, metrics.Labels{"topic": topic, "status": status})
|
||||
}
|
||||
|
||||
func kafkaMessage(topic string, data []byte) kafka.Message {
|
||||
var env envelope.FrameEnvelope
|
||||
message := kafka.Message{Topic: topic, Value: data}
|
||||
|
||||
Reference in New Issue
Block a user