package metrics import ( "net/http" "net/http/httptest" "strings" "testing" "time" ) // /metrics 文本端点:注入计数/观测后可被抓取,指标名与 label 齐全。 func TestHandlerExposesInstruments(t *testing.T) { RequestsTotal.WithLabelValues("c1", "m1", "success").Inc() RequestsTotal.WithLabelValues("none", "m1", "error").Inc() RequestDuration.WithLabelValues("c1").Observe(0.42) ChannelFailures.WithLabelValues("c1", "rate_limited").Inc() RecorderQueueDepth.Set(7) FrozenBalance.Set(0.00246) srv := httptest.NewServer(Handler()) defer srv.Close() resp, err := http.Get(srv.URL) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("status = %d", resp.StatusCode) } buf := make([]byte, 1<<16) n, _ := resp.Body.Read(buf) body := string(buf[:n]) for _, want := range []string{ "openteam_proxy_requests_total{", `channel="c1"`, `status="success"`, "openteam_proxy_request_duration_seconds", "openteam_channel_failures_total", "openteam_usage_queue_depth 7", "openteam_frozen_balance 0.00246", "go_goroutines", // Go 运行时指标一并暴露 } { if !strings.Contains(body, want) { t.Errorf("metrics 输出缺少 %q", want) } } // 直方图观测应产生 bucket 样本 if !strings.Contains(body, `openteam_proxy_request_duration_seconds_bucket`) && n < len(buf) { // 一次 Read 可能读不完,重读剩余部分再断言 rest := make([]byte, 1<<16) n2, _ := resp.Body.Read(rest) body += string(rest[:n2]) if !strings.Contains(body, "openteam_proxy_request_duration_seconds_bucket") { t.Errorf("metrics 输出缺少直方图 bucket 样本") } } _ = time.Second }