You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于prom-client为所有REST API实现请求数及失败数追踪?

扩展REST API全量追踪方案

要实现所有API的请求数量、失败数量以及耗时追踪,你可以按以下步骤修改现有代码:

1. 新增请求计数类指标

在现有耗时直方图基础上,添加两个计数器:

  • 统计所有请求的总次数
  • 统计失败请求(状态码≥400)的次数

2. 统一处理所有路由的指标上报

不管请求匹配到哪个路由,甚至是未匹配的404请求,都要确保指标被正确采集,同时捕获处理过程中的异常,避免指标遗漏。

修改后的完整代码

const http = require('http')
const url = require('url')
const client = require('prom-client')

// 创建指标注册器
const register = new client.Registry()
register.setDefaultLabels({ app: 'example-nodejs-app' })
client.collectDefaultMetrics({ register })

// 原有耗时直方图
const httpRequestDurationSeconds = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'HTTP请求耗时(秒)',
  labelNames: ['method', 'route', 'code'],
  buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10]
})

// 新增请求总次数计数器
const httpRequestsTotal = new client.Counter({
  name: 'http_requests_total',
  help: 'HTTP请求总次数',
  labelNames: ['method', 'route', 'code']
})

// 新增失败请求计数器
const httpRequestsFailedTotal = new client.Counter({
  name: 'http_requests_failed_total',
  help: 'HTTP失败请求次数(状态码≥400)',
  labelNames: ['method', 'route', 'code']
})

// 注册所有指标
register.registerMetric(httpRequestDurationSeconds)
register.registerMetric(httpRequestsTotal)
register.registerMetric(httpRequestsFailedTotal)

// 路由处理映射表(可根据实际业务扩展)
const routeHandlers = {
  '/order': createOrderHandler,
  '/products': fetchProducts
}

// HTTP服务器逻辑
const server = http.createServer(async (req, res) => {
  const endTimer = httpRequestDurationSeconds.startTimer()
  const route = url.parse(req.url).pathname
  let statusCode = 200

  try {
    // 匹配路由处理函数,未匹配则返回404
    const handler = routeHandlers[route]
    if (handler) {
      await handler(req, res)
    } else {
      statusCode = 404
      res.writeHead(404, { 'Content-Type': 'application/json' })
      res.end(JSON.stringify({ error: 'Route not found' }))
    }
    // 从响应对象获取最终状态码(如果handler里修改过)
    statusCode = res.statusCode || statusCode
  } catch (error) {
    // 捕获处理过程中的异常,标记为500错误
    statusCode = 500
    res.writeHead(500, { 'Content-Type': 'application/json' })
    res.end(JSON.stringify({ error: 'Internal server error' }))
    console.error('Request error:', error)
  } finally {
    // 上报所有指标
    const labels = { method: req.method, route, code: statusCode }
    endTimer(labels)
    httpRequestsTotal.inc(labels)
    
    // 统计失败请求
    if (statusCode >= 400) {
      httpRequestsFailedTotal.inc(labels)
    }
  }
})

// 暴露metrics端点
server.on('request', (req, res) => {
  if (req.url === '/metrics') {
    res.setHeader('Content-Type', register.contentType)
    register.metrics().then(data => res.end(data))
  }
})

server.listen(8080)

// 示例处理函数(保持原有业务逻辑)
async function createOrderHandler(req, res) {
  // 你的订单创建逻辑
  res.writeHead(201, { 'Content-Type': 'application/json' })
  res.end(JSON.stringify({ message: 'Order created' }))
}

async function fetchProducts(req, res) {
  // 你的商品查询逻辑
  res.writeHead(200, { 'Content-Type': 'application/json' })
  res.end(JSON.stringify({ products: [] }))
}

关键修改说明

  • 路由映射表:用routeHandlers统一管理路由与处理函数的对应关系,方便后续扩展新API
  • 异常捕获:用try/catch/finally确保即使处理函数抛出异常,也能正确上报指标
  • 全路由覆盖:未匹配到的路由自动返回404并统计,不会遗漏任何请求
  • 失败请求判定:通过状态码≥400来标记失败请求,包含4xx客户端错误和5xx服务端错误
  • 指标统一上报:所有指标的上报逻辑放在finally块中,保证无论请求成功或失败都会执行

内容的提问来源于stack exchange,提问作者Ajay S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 16:15:30