Echo框架本身不内置监控中间件,echo.New()创建的是干净实例,必须显式注册Prometheus中间件并挂载/metrics路由,否则curl该路径返回404;漏注册、错用WrapHandler、未调MustRegister或registry为空均导致指标缺失。

为什么 echo.New() 默认不带 Prometheus 中间件
Echo 框架本身不内置任何监控中间件,echo.New() 创建的实例是“干净”的,没有任何指标采集逻辑。Prometheus 监控必须显式注册中间件,否则 /metrics 路由根本不存在,curl localhost:8080/metrics 会直接返回 404。
常见错误现象:启动服务后 Prometheus 抓不到数据,curl 返回 404 或空响应,但日志里又没报错——大概率是漏了中间件注册或路由挂载。
- 必须手动引入
github.com/prometheus/client_golang/prometheus/promhttp提供的 HTTP handler - 必须用
e.Use()注册指标收集中间件(如prometheus.New(echo.WrapHandler(promhttp.Handler()))不行,这是错的) - 推荐使用社区维护的
github.com/itsjamie/echo-prometheus,它提供prometheus.NewMetrics()中间件,自动记录请求延迟、状态码、方法等基础指标
如何正确挂载 /metrics 路由并暴露指标
不能只加中间件,还要确保 /metrics 这个路径被明确注册为 handler,否则 Prometheus 抓取端点不存在。
实操建议:
立即学习“go语言免费学习笔记(深入)”;
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
- 用
github.com/itsjamie/echo-prometheus时,先调用prometheus.NewMetrics()创建中间件,再e.Use(mw) - 然后单独注册路由:
e.GET("/metrics", echo.WrapHandler(promhttp.Handler())) - 注意:不要用
echo.WrapHandler包裹中间件本身——中间件是给e.Use()的,/metrics是独立 endpoint,必须用promhttp.Handler()直接响应 - 如果用了自定义 registry(比如传入
prometheus.NewRegistry()),记得把promhttp.HandlerFor(reg, promhttp.HandlerOpts{})作为 handler 传给GET("/metrics")
示例关键片段:
import (
"github.com/itsjamie/echo-prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
mw := prometheus.NewMetrics()
e.Use(mw)
e.GET("/metrics", echo.WrapHandler(promhttp.Handler()))
echo-prometheus 中间件默认统计哪些指标
它默认导出三类核心指标,全部以 echo_ 为前缀,符合 Prometheus 命名惯例:
-
echo_http_request_duration_seconds_bucket:按状态码、方法、路径标签分组的请求延迟直方图(含_sum和_count) -
echo_http_request_total:按状态码、方法、路径计数的 Counter -
echo_go_goroutines:Go runtime 当前 goroutine 数(无需额外配置)
注意路径标签(path)默认是原始 URL 路径,不是 Echo 的路由 pattern。例如访问 /api/users/:id 会被记为 /api/users/123,容易导致 label 爆炸。如需按 pattern 统计,得自己实现 LabelFunc 并传给 NewMetricsWithOptions()。
为什么 curl /metrics 返回空或格式错误
最常见原因是 Content-Type 不对或 handler 被其他中间件拦截。Prometheus 抓取要求响应头必须是 Content-Type: text/plain; version=0.0.4; charset=utf-8。
- 检查是否误用了
echo.HTTPErrorHandler拦截了/metrics请求(比如全局 error handler 对 200 也做了重写) - 确认没在
/metrics路由上挂载其他中间件(如 JWT 鉴权),这会导致 handler 被跳过或 panic - 用
curl -v http://localhost:8080/metrics看响应头,若Content-Type不是text/plain,说明 handler 没走promhttp.Handler() - 若返回空但状态码是 200,可能是 registry 为空——检查是否真的有请求触发过指标打点(首次请求后指标才初始化)
复杂点在于:Echo 的中间件执行顺序敏感,/metrics 必须绕过所有业务中间件;而指标中间件本身又必须在日志、恢复等中间件之后,才能捕获真实状态码和耗时。这个顺序容易被忽略。

















