← 中文资源

简体中文版本

为 Prometheus 暴露应用指标端点

用 prom-client 暴露受令牌保护的 /metrics,记录默认 Node.js 指标和低基数请求直方图,并配置 Prometheus 抓取验证。

阅读英文原文

概述

日志描述单次请求发生了什么,指标回答整个服务是否健康。延迟直方图可以计算 p50、p95 和 p99,错误率可以触发 SLO 告警。先保留一小组指标:请求耗时、按状态类别的请求数、需要时的并发请求数,以及 prom-client 的默认运行时指标。标签是设计重点:路由标签必须使用 Express 路由模板 /orders/:id,不能用 req.path 中的真实订单 ID,否则每个 ID 都会生成新时间序列,最终压垮 Prometheus。状态也应按 2xx、4xx、5xx 分组。

步骤

安装 prom-client,只创建一个 Registry:

import client from 'prom-client';

export const register = new client.Registry();
client.collectDefaultMetrics({ register, prefix: 'nodejs_' });

export const httpDuration = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP request duration in seconds',
  labelNames: ['method', 'route', 'status'],
  buckets: [0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5],
  registers: [register],
});

中间件在 res.on('finish') 中记录 req.route 模板和状态类别。/metrics 路由本身跳过统计,避免递归。端点使用 METRICS_TOKEN 校验 Bearer 令牌,未授权返回 403,成功时设置 register.contentType 并返回 await register.metrics()。

Prometheus 配置增加抓取任务,令牌从文件读取:

scrape_configs:
  - job_name: orders-api
    scrape_interval: 15s
    metrics_path: /metrics
    authorization:
      type: Bearer
      credentials_file: /etc/prometheus/orders-api-token
    static_configs:
      - targets: ["orders-api.default.svc.cluster.local:3000"]

验证

运行 promtool check config 并用 curl -X POST http://localhost:9090/-/reload 重载。查询 targets API,orders-api 应为 up 且 lastError 为空。生成若干请求并等待两个抓取周期后执行:

histogram_quantile(0.95, sum by (le) (rate(http_request_duration_seconds_bucket[5m])))

应返回数值;若为 NaN,说明窗口内没有样本。最后确认不带令牌请求 /metrics 返回 403,带令牌时能看到 http_request_duration_seconds_count。

注意事项

进程内指标在重启后清零,长期历史需要 remote write 或远端存储。拉取模型要求 Prometheus 能访问每个实例,短生命周期批处理任务应使用 Pushgateway。静态 Bearer 令牌是共享密钥,应配合网络策略并定期轮换。不要用 req.originalUrl 或用户输入做标签,也不要把单次 p95 尖峰直接当成事故;低流量窗口的分位数噪声很大。