应使用echo中间件在next(c)前后用time.now()埋点计时,存起始时间到c.set(),结束后取c.response().status()和耗时,写入prometheus histogram并按route标签分组。

如何用Echo中间件统计每个API的响应时间
直接在 echo.Echo 实例上注册自定义中间件是最轻量、最可控的方式。Echo 的 MiddlewareFunc 能精确捕获请求进入和响应写出的时间点,比依赖日志解析或外部 APM 更可靠。
关键点在于:必须在 c.Response().Writer 写入前记录结束时间,并读取 c.Response().Status() 获取真实状态码——因为 c.Get("status") 可能被后续中间件覆盖。
- 使用
time.Now()记录起始时间,存入c.Request().Context()或c.Set()(推荐后者,避免 context 传播开销) - 在
next(c)后立即调用c.Response().Status()和c.Response().Size(),再算耗时 - 避免在中间件里做阻塞操作(如直连数据库写监控),应发到 channel 或异步队列
- 示例片段:
func ResponseTimeMiddleware() echo.MiddlewareFunc { return func(next echo.Handler) echo.Handler { return echo.HandlerFunc(func(c echo.Context) error { start := time.Now() c.Set("start_time", start) err := next(c) status := c.Response().Status() size := c.Response().Size() duration := time.Since(start) // 发送指标到 metrics collector... return err }) } }
为什么用 Prometheus + Histogram 而不是 Summary 统计延迟
Summary 会在客户端计算分位数,但 Echo 是服务端程序,每个实例的延迟分布不具备全局代表性;而 Histogram 允许服务端打点、Prometheus 服务端聚合,支持按 path、status 等标签多维下钻,更适合 API 级别诊断。
Echo框架 5.1.0 版本源码包下载,适合关注 RealIP 行为变化、StartConfig.Listener、NewDefaultFS 和观测性中间件入口的开发团队。
-
promhttp暴露指标时,Histogram 的bucket边界必须覆盖你关心的延迟区间(比如[0.005, 0.01, 0.025, 0.05, 0.1, 0.2, 0.5, 1, 2, 5]秒) - 务必为每个
c.Path()或路由名加route标签,否则所有接口延迟混在一起,报警时无法定位具体接口 - 不要用
http_request_duration_seconds这种通用名,自定义命名如echo_http_request_duration_seconds_bucket,避免与其它框架冲突 - 注意 Histogram 的
_sum和_count是必需的,Prometheus 用它们算平均值(rate(..._sum[1m]) / rate(..._count[1m]))
怎样配置 Alertmanager 实现“连续3次超200ms”报警
Prometheus 的 for 语句只表示“持续满足条件”,不等于“连续N次”。要实现“连续3次采样超阈值”,得靠 PromQL 的偏移和聚合技巧。
- 基础查询:
rate(echo_http_request_duration_seconds_sum{job="api"}[1m]) / rate(echo_http_request_duration_seconds_count{job="api"}[1m]) > 0.2判断平均延迟超标 - 但更准的是看 P95:
histogram_quantile(0.95, sum(rate(echo_http_request_duration_seconds_bucket{job="api"}[1m])) by (le, route)) > 0.2 - 要“连续3次”:用
count_over_time+ offset,例如:(count_over_time((histogram_quantile(0.95, sum(rate(echo_http_request_duration_seconds_bucket[1m])) by (le, route)) > 0.2)[3m:1m]) == 3)
- Alertmanager 的
group_by: [route]必须包含route,否则不同接口报警会合并成一条,失去可操作性
本地开发时如何快速验证延迟监控是否生效
不用等线上流量,用 curl 配合 time 和 Prometheus 的 /metrics 端点就能闭环验证。
- 启动 Echo 服务时确保已注册
promhttp.Handler到/metrics路由 - 用
time curl -s http://localhost:8080/some/api > /dev/null看真实耗时,再立刻查curl http://localhost:8080/metrics | grep echo_http_request_duration_seconds - 重点检查
_bucket{le="0.2"}对应的计数是否增加,以及_sum/_count是否合理(比如 300ms 请求,_sum应 ≈_count × 0.3) - 故意让某个 handler
time.Sleep(300 * time.Millisecond),再观察 histogram bucket 分布是否右移
实际部署时最容易被忽略的是:Histogram 的 le 标签边界没对齐业务 SLO,或者 Alertmanager 的 repeat_interval 设得太短,导致同一问题每分钟发 10 条企业微信消息。先跑通单条请求的指标链路,再谈聚合和告警。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










