【问题标题】:How do I track number of requests of all rest api如何跟踪所有休息 api 的请求数
【发布时间】:2022-10-05 00:49:16
【问题描述】:

我想跟踪每个 API 的请求数和失败数。我已经为一个 api 做到了这一点。

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

// Create a Registry which registers the metrics
const register = new client.Registry()

// Add a default label which is added to all metrics
register.setDefaultLabels({
  app: 'example-nodejs-app'
})

// Enable the collection of default metrics
client.collectDefaultMetrics({ register })

// Create a histogram metric
const httpRequestDurationMicroseconds = new client.Histogram({
  name: 'http_request_duration_seconds',
  help: 'Duration of HTTP requests in microseconds',
  labelNames: ['method', 'route', 'code'],
  buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10]
})

// Register the histogram
register.registerMetric(httpRequestDurationMicroseconds)

// Define the HTTP server
const server = http.createServer(async (req, res) => {
    // Start the timer
  const end = httpRequestDurationMicroseconds.startTimer()

  // Retrieve route from request object
  const route = url.parse(req.url).pathname

  if (route === '/order') {
    await createOrderHandler(req, res)
  }

  if (route === '/products') {
    await fetchProducts(req, res)
  }

  // End timer and add labels
  end({ route, code: res.statusCode, method: req.method })
})

// Start the HTTP server which exposes the metrics on http://localhost:8080/metrics
server.listen(8080)

我如何为所有 api 实现这一点?

【问题讨论】:

    标签: node.js prometheus grafana


    【解决方案1】:

    您可以为成功和失败的 api 添加计数器

    const http = require('http')
    const url = require('url')
    const client = require('prom-client')
    
    // Create a Registry which registers the metrics
    const register = new client.Registry()
    
    // Add a default label which is added to all metrics
    register.setDefaultLabels({
        app: 'example-nodejs-app'
    })
    
    // Enable the collection of default metrics
    client.collectDefaultMetrics({register})
    
    // Create a histogram metric
    const httpRequestDurationMicroseconds = new client.Histogram({
        name: 'http_request_duration_seconds',
        help: 'Duration of HTTP requests in microseconds',
        labelNames: ['method', 'route', 'code'],
        buckets: [0.1, 0.3, 0.5, 0.7, 1, 3, 5, 7, 10]
    })
    let counts = {
        success: 0,
        fail: 0,
    };
    
    // Register the histogram
    register.registerMetric(httpRequestDurationMicroseconds)
    
    // Define the HTTP server
    const server = http.createServer(async (req, res) => {
        // Start the timer
        const end = httpRequestDurationMicroseconds.startTimer()
    
        // Retrieve route from request object
        const route = url.parse(req.url).pathname
    
        try {
            if (route === '/order') {
                await createOrderHandler(req, res)
            }
    
            if (route === '/products') {
                await fetchProducts(req, res)
            }
    
            if (route === '/get-counts') {
                counts.success--;
                res.writeHead(200, {'Content-Type': 'application/json'});
                res.write(JSON.stringify(counts, null, 4));
                res.end();
            }
            
            if (res.statusCode === 200) {
                counts.success++;
            } else {
                counts.fail++;
            }
        } catch (e) {
            res.writeHead(500, {'Content-Type': 'text/plain'});
            res.write(e.toString());
            res.end();
            counts.fail++;
        }
    
        // End timer and add labels
        end({route, code: res.statusCode, method: req.method})
    })
    
    // Start the HTTP server which exposes the metrics on http://localhost:8080/metrics
    server.listen(8080);
    
    

    请求的总数将是成功和失败计数器的加法。

    【讨论】:

      【解决方案2】:

      您可以监听resfinish 事件,当您调用res.end 时将触发该事件。

      这是一个简单的例子

      import { createServer } from 'http'
      
      const reqMap = new Map()
      
      const updateCounts = (reqStats, statusCode) => {
        if (statusCode >= 400) reqStats.failures++
        else if (statusCode >= 200) reqStats.successes++
        else reqStats.misc++
      }
      
      const server = createServer((req, res) => {
        res.on('finish', () => {
          if (res.headersSent && req.url) {
            const reqStats = reqMap.get(req.url)
            if (reqStats) {
              updateCounts(reqStats, res.statusCode)
            } else {
              const newReqStats = { failures: 0, successes: 0, misc: 0 }
              updateCounts(newReqStats, res.statusCode)
              reqMap.set(req.url, newReqStats)
            }
            console.log(reqMap)
          }
        })
      
        try {
          const num = Math.random()
          if (num < 0.55) throw new Error('bad number')
          res.writeHead(200, { 'Content-Type': 'application/json' })
          res.end(JSON.stringify({ num }) + '
      ')
        } catch (err) {
          res.writeHead(500, { 'Content-Type': 'application/json' })
          res.end(JSON.stringify({ name: err.name, message: err.message }) + '
      ')
        }
      })
      
      server.on('error', console.error)
      
      server.listen(8000, () => console.log('listening on', server.address()))
      
      

      reqMap 会有这样的东西。

      Map(5) {
        '/asda/asd899a' => { failures: 1, successes: 0, misc: 0 },
        '/somepath/asd' => { failures: 0, successes: 1, misc: 0 },
        '/coyb' => { failures: 0, successes: 1, misc: 0 },
        '/casd' => { failures: 3, successes: 3, misc: 0 },
        '/etst' => { failures: 5, successes: 4, misc: 0 }
      }
      
      

      【讨论】:

        【解决方案3】:

        我认为https://github.com/yaorg/node-measured 可能会回答您的问题,我理解它的实现类似于 Node.js 中的 Metrics (of Java world )。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-01-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-04
          相关资源
          最近更新 更多