最直接方式是用prometheus/client_golang注册指标并挂载promhttp.Handler()到/metrics;必须调用MustRegister(),指标为全局单例,禁用弃用的prometheus.Handler()。
prometheus.ClientGolang 暴露指标端点最直接Go 服务暴露监控指标,首选官方维护的 prometheus/client_golang。它不负责采集,只提供注册、收集和 HTTP 暴露能力。你要做的,是初始化一个 promhttp.Handler() 并挂到 HTTP 路由上。
prometheus.MustRegister() 注册你定义的指标(如 prometheus.NewCounterVec),否则指标不会出现在 /metrics
Counter 或 Gauge —— 它们是全局单例,重复注册会 panicpromhttp.Handler(),不能用 http.DefaultServeMux 直接返回 prometheus.Handler()(后者已弃用)package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
var (
httpRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "http_requests_total",
Help: "Total number of HTTP requests.",
},
[]string{"method", "status"},
)
)
func init() {
prometheus.MustRegister(httpRequestsTotal)
}
func handler(w http.ResponseWriter, r *http.Request) {
httpRequestsTotal.WithLabelValues(r.Method, "200").Inc()
w.WriteHeader(200)
}
func main() {
http.HandleFunc("/", handler)
http.Handle("/metrics", promhttp.Handler()) // 注意这里
http.ListenAndServe(":8080", nil)
}
Counter、Gauge、Histogram、Summary 不是随便换着用的。Prometheus 查询函数(如 rate()、increase())只对 Counter 有意义;用 Gauge 记请求数量,rate()
会返回 0 或负值。
Counter:只增不减,适合累计量(如请求总数、错误总数)Gauge:可增可减,适合瞬时值(如当前 goroutine 数、内存使用 MB)Histogram:分桶统计,适合延迟(latency)、响应大小等分布类指标;生成 _sum、_count、_bucket 多个时间序列Summary:客户端计算分位数(如 p95),但无法聚合,多实例场景下基本不用常见误用:Histogram 的 Buckets 设太宽(如 []float64{0.1, 0.2, 5})导致大部分请求挤在最后一个桶,p99 失真;应按实际延迟分布设,比如 []float64{0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10}(单位秒)
指标名要带语义前缀(如 myapp_http_request_duration_seconds),避免用 metric1 这类名称;label 不是越多越好,高基数(cardinality)label(如 user_id、request_id)会让 series 数量爆炸,拖慢 Prometheus 查询和存储。
method、status、path 是合理 label;ip 和 user_agent 通常不该加(除非明确需要)path="/api/v1/users/"+id),这等于为每个 ID 创建新 seriesInc())别加太多 label,写入压力会陡增curl localhost:8080/metrics 看不到指标?先查三件事暴露端点后 curl 返回空或 404,不是代码写错了就是没跑起来。
http.ListenAndServe() 没 panic,且端口没被占用(lsof -i :8080)MustRegister(),未注册的指标不会出现在 /metrics 输出中os.Exit() 或 panic 后没 recover,导致进程提前退出另外,promhttp.Handler() 默认只响应 GET 和 OPTIONS,用 POST curl 会 405;调试就老实用 curl -v http://localhost:8080/metrics。