Files

80 lines
2.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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())
}