package gateway import ( "context" "errors" "strings" "time" "lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope" "lingniu-vehicle-ingest/go/vehicle-gateway/internal/metrics" ) var gatewayIdentityDurationBucketsMS = []float64{1, 5, 10, 25, 50, 100, 250, 500, 1000, 5000} var gatewayFieldsCountBuckets = []float64{1, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000} func identityErrorStatus(err error) string { if errors.Is(err, context.DeadlineExceeded) { return "timeout" } return "error" } func recordGatewayIdentityDuration(registry *metrics.Registry, protocol envelope.Protocol, status string, elapsed time.Duration) { if registry == nil { return } elapsedMS := float64(elapsed.Nanoseconds()) / float64(time.Millisecond) labels := metrics.Labels{ "protocol": string(protocol), "status": status, } registry.SetGauge("vehicle_gateway_identity_duration_ms", labels, elapsedMS) registry.ObserveHistogram("vehicle_gateway_identity_duration_ms_histogram", labels, gatewayIdentityDurationBucketsMS, elapsedMS) } func recordGatewayIdentityCacheStatus(registry *metrics.Registry, protocol envelope.Protocol, env envelope.FrameEnvelope) { if registry == nil { return } status := identityCacheStatus(env) if status == "" { return } registry.IncCounter("vehicle_gateway_identity_cache_total", metrics.Labels{ "protocol": string(protocol), "cache_status": status, }) } func identityCacheStatus(env envelope.FrameEnvelope) string { identity, ok := env.Parsed["identity"].(map[string]any) if !ok { return "" } status, ok := identity["cache_status"].(string) if !ok { return "" } return strings.TrimSpace(status) } func annotateIdentityError(env *envelope.FrameEnvelope, err error) { if env == nil || err == nil { return } if env.Parsed == nil { env.Parsed = map[string]any{} } identity, _ := env.Parsed["identity"].(map[string]any) if identity == nil { identity = map[string]any{} } if _, ok := identity["resolved"]; !ok { identity["resolved"] = strings.TrimSpace(env.VIN) != "" } identity["error"] = err.Error() env.Parsed["identity"] = identity } func recordGatewayFieldsMetric(registry *metrics.Registry, protocol envelope.Protocol, status string) { if registry == nil { return } registry.IncCounter("vehicle_gateway_fields_total", metrics.Labels{ "protocol": string(protocol), "status": status, }) } func recordGatewayFieldsCount(registry *metrics.Registry, protocol envelope.Protocol, status string, fieldCount int) { if registry == nil { return } if fieldCount < 0 { fieldCount = 0 } labels := metrics.Labels{ "protocol": string(protocol), "status": status, } value := float64(fieldCount) registry.SetGauge("vehicle_gateway_fields_count", labels, value) registry.ObserveHistogram("vehicle_gateway_fields_count_histogram", labels, gatewayFieldsCountBuckets, value) }