Day 4:可观测性——Metrics/Tracing/Logging三件套
今天做什么
网关跑起来了,但你得知道它运行得怎么样。加三件套:Prometheus 指标、请求追踪、结构化日志。
代码
go
package main
import (
"log/slog"
"net/http"
"os"
"time"
"github.com/google/uuid"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// ===== Prometheus 指标 =====
var (
requestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{Name: "gateway_requests_total"},
[]string{"model", "status"},
)
requestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "gateway_request_duration_seconds",
Buckets: []float64{0.1, 0.5, 1, 2, 5, 10},
},
[]string{"model"},
)
queueLength = prometheus.NewGauge(
prometheus.GaugeOpts{Name: "gateway_queue_length"},
)
)
func init() {
prometheus.MustRegister(requestsTotal, requestDuration, queueLength)
}
// ===== 带可观测性的中间件 =====
func (g *Gateway) ObservabilityMiddleware(next http.Handler) http.Handler {
logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// 注入 traceId
traceID := uuid.New().String()
ctx := context.WithValue(r.Context(), "trace_id", traceID)
r = r.WithContext(ctx)
start := time.Now()
// 记录指标
model := r.Header.Get("X-Routed-Model")
requestsTotal.WithLabelValues(model, "started").Inc()
// 处理请求
next.ServeHTTP(w, r)
// 记录耗时
duration := time.Since(start).Seconds()
requestDuration.WithLabelValues(model).Observe(duration)
// 结构化日志
logger.Info("request_completed",
"trace_id", traceID,
"model", model,
"duration_ms", duration*1000,
"queue_len", len(g.queue.queue),
)
})
}
// ===== 暴露指标 =====
func main() {
gw := NewGateway()
// Prometheus 指标端点
http.Handle("/metrics", promhttp.Handler())
// 网关路由 + 中间件
handler := gw.ObservabilityMiddleware(
http.HandlerFunc(gw.ServeHTTP))
http.Handle("/v1/chat/completions", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}运行
bash
go run main.go
# 查看指标
curl http://localhost:8080/metrics
# gateway_requests_total{model="gpt-3.5-turbo",status="started"} 1234
# gateway_request_duration_seconds_bucket{model="gpt-3.5-turbo",le="0.5"} 800Day 4 完成。网关现在可观测了。

