根本原因是业务指标未注册进DefaultRegisterer:Beego不自动注册自定义指标,必须在init/main中调用prometheus.MustRegister()显式注册,且仅一次;若只声明不注册或重复注册,/metrics将为空或panic。

Beego中暴露/metrics端点返回空指标?
根本原因不是Prometheus没抓到,而是你定义的业务指标压根没注册进默认注册器。Beego本身不自动注册任何业务指标,promhttp.Handler()只暴露prometheus.DefaultRegisterer里已注册的内容。运行时指标(如go_goroutines)能看见,是因为prometheus.NewGoCollector()被显式注册了;但http_requests_total这类自定义指标如果只声明不注册,/metrics里永远为空。
实操建议:
- 在
main.go或init()函数里调用prometheus.MustRegister(),且仅调用一次 - 避免在多个包的
init()中重复注册同名指标,否则启动 panic:"duplicate metrics collector registration attempted" - 若用
promauto.NewCounterVec(),它会自动注册到DefaultRegisterer,但前提是没被其他包提前破坏注册器状态(比如另一个包也调用了MustRegister同名指标) - 调试时可加
prometheus.Unregister(yourCounter)再重注册,或改用prometheus.NewRegistry()隔离测试
Beego HTTP中间件里怎么统计status code和延迟?
Beego的过滤器(Filter)机制天然适合埋点,但直接用原生ctx.ResponseWriter拿不到真实状态码——因为Beego内部可能在AfterExec阶段才写入响应头。必须包装ResponseWriter才能捕获最终status和耗时。
实操建议:
- 在
BeforeExec位置记录开始时间,在FinishRouter位置计算耗时并上报,此时ctx.Output.Status已确定 - 别用
ctx.ResponseWriter.WriteHeader()判断状态码,要用ctx.Output.Status(Beego封装后的字段) - 延迟直方图(
http_request_duration_seconds)的Buckets别照搬默认值,按你API实际P99延迟设:高频接口推荐[]float64{0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5} - 标签维度控制在3个以内(如
method、path、status),避免高基数导致Prometheus内存暴涨
Beego配置Prometheus抓取目标时常见错误
Prometheus配置文件里targets写localhost:8080在本地开发能通,但上K8s或Docker后必然失败——容器网络里localhost指向自身,不是你的Beego服务。
实操建议:
- 抓取目标必须写服务发现地址,K8s环境用
beego-service.default.svc.cluster.local:8080,Docker Compose用beego-app:8080 -
scrape_interval别设太短(如1s),Beego默认HTTP handler无并发限流,高频抓取可能拖慢业务请求 - 务必加
honor_labels: true,否则Beego打的path="/api/user"会被Prometheus覆盖成instance标签 - 在Beego路由里显式禁用
/metrics的OPTIONS方法:beego.Router("/metrics", &controllers.MetricsController{}, "get:Get")
如何安全添加BasicAuth保护/metrics端点?
Beego不内置HTTP Basic Auth中间件,但可以用标准net/http方式包装handler,比自己解析Header更可靠。
实操建议:
- 不要在Beego控制器里手写
ctx.Input.Header("Authorization")校验,容易绕过或漏判 - 用
http.HandlerFunc包装promhttp.Handler(),再挂到Beego路由:authHandler := basicAuth(http.HandlerFunc(promhttp.Handler().ServeHTTP))<br>beego.Handler("/metrics", authHandler) - 密码别硬编码,从环境变量读:
os.Getenv("METRICS_USER")和os.Getenv("METRICS_PASS") - 生产环境禁止把
/metrics暴露在公网,Nginx层加allow 10.0.0.0/8;或类似IP白名单
promhttp.Handler()初始化,或在Beego路由注册前就调用了MustRegister(),都会导致指标丢失且无任何报错提示。


















