feat(go): add realtime pipeline observability

This commit is contained in:
lingniu
2026-07-03 15:06:27 +08:00
parent 28c81611a1
commit b8299faefa
10 changed files with 636 additions and 6 deletions

View File

@@ -102,7 +102,8 @@ func TestAsyncSecondaryRealtimeUpdaterDoesNotBlockPrimaryPath(t *testing.T) {
env := envelope.FrameEnvelope{Protocol: envelope.ProtocolGB32960, VIN: "VIN001"}
primary := &contextCheckingRealtimeUpdater{}
secondary := &blockingRealtimeUpdater{started: make(chan struct{}), release: make(chan struct{})}
updater := newAsyncSecondaryRealtimeUpdater(primary, secondary, 8, 1)
registry := metrics.NewRegistry()
updater := newAsyncSecondaryRealtimeUpdater(primary, secondary, 8, 1, registry)
defer updater.Close()
start := time.Now()
@@ -121,6 +122,26 @@ func TestAsyncSecondaryRealtimeUpdaterDoesNotBlockPrimaryPath(t *testing.T) {
t.Fatal("secondary update was not started asynchronously")
}
close(secondary.release)
if text := registry.Render(); !strings.Contains(text, `vehicle_realtime_async_queue_total{protocol="GB32960",status="queued",store="mysql"} 1`) {
t.Fatalf("async queue metric missing:\n%s", text)
}
}
func TestStoreMetricUpdaterRecordsStoreUpdateResults(t *testing.T) {
registry := metrics.NewRegistry()
env := envelope.FrameEnvelope{Protocol: envelope.ProtocolJT808, VIN: "VIN001"}
updater := storeMetricUpdater{
store: "redis",
delegate: &contextCheckingRealtimeUpdater{},
registry: registry,
}
if err := updater.Update(context.Background(), env); err != nil {
t.Fatalf("Update() error = %v", err)
}
if text := registry.Render(); !strings.Contains(text, `vehicle_realtime_store_updates_total{protocol="JT808",status="ok",store="redis"} 1`) {
t.Fatalf("store update metric missing:\n%s", text)
}
}
func TestKafkaTopicsFromEnvDefaultsToGoRawTopics(t *testing.T) {
@@ -174,6 +195,18 @@ func TestRealtimeAPIExposesPostRawFrameQueryRoute(t *testing.T) {
}
}
func TestRealtimeAPIExposesOperationalRealtimeRoutes(t *testing.T) {
source, err := os.ReadFile("main.go")
if err != nil {
t.Fatalf("read main.go: %v", err)
}
for _, want := range []string{`"/api/realtime/online"`, `"/api/debug/pipeline"`} {
if !strings.Contains(string(source), want) {
t.Fatalf("realtime api should expose operational route %s", want)
}
}
}
type contextCheckingRealtimeUpdater struct {
ctxErr error
count int