// Package monitor 运行监控(方案系统管理模块补足)。 // // 提供 Prometheus 指标采集中间件,覆盖 4 金指标: // - Latency:请求延迟直方图 // - Traffic:请求总量计数器 // - Errors:错误响应计数器 // - Saturation:并发在途请求 gauge // // 使用方式: // r := gin.Default() // r.Use(monitor.Middleware()) // r.GET("/metrics", monitor.Handler()) package monitor import ( "strconv" "time" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" "github.com/prometheus/client_golang/prometheus/promhttp" ) var ( // httpDuration 请求延迟直方图(Latency)。 httpDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: "tcs_http_request_duration_seconds", Help: "HTTP 请求延迟(秒)", Buckets: []float64{0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10}, }, []string{"method", "path", "status"}) // httpRequests 请求总量计数器(Traffic)。 httpRequests = promauto.NewCounterVec(prometheus.CounterOpts{ Name: "tcs_http_requests_total", Help: "HTTP 请求总量", }, []string{"method", "path", "status"}) // httpErrors 错误响应计数器(Errors)。 httpErrors = promauto.NewCounterVec(prometheus.CounterOpts{ Name: "tcs_http_errors_total", Help: "HTTP 错误响应总量(状态码 >= 400)", }, []string{"method", "path", "status"}) // httpInFlight 并发在途请求(Saturation)。 httpInFlight = promauto.NewGauge(prometheus.GaugeOpts{ Name: "tcs_http_in_flight_requests", Help: "当前在途 HTTP 请求数", }) ) // Middleware 返回 Gin 中间件,采集 Prometheus 指标。 func Middleware() gin.HandlerFunc { return func(c *gin.Context) { start := time.Now() httpInFlight.Inc() c.Next() httpInFlight.Dec() status := strconv.Itoa(c.Writer.Status()) elapsed := time.Since(start).Seconds() path := c.FullPath() if path == "" { path = "unknown" } httpDuration.WithLabelValues(c.Request.Method, path, status).Observe(elapsed) httpRequests.WithLabelValues(c.Request.Method, path, status).Inc() if c.Writer.Status() >= 400 { httpErrors.WithLabelValues(c.Request.Method, path, status).Inc() } } } // Handler 返回 Prometheus metrics 暴露端点。 func Handler() gin.HandlerFunc { return gin.WrapH(promhttp.Handler()) }