Skip to content
Snippets Groups Projects
Select Git revision
  • 1d9b180872e5150bb62d5584e825a55d53cf8038
  • main default protected
2 results

index.ts

Blame
  • index.ts 1.79 KiB
    import * as express from 'express'
    import Prometheus = require('prom-client')
    
    export class Metrics {
      private readonly _options: any
      public readonly _httpRequestDurationMicroseconds: any
      public readonly _numOfRequests: any
      public readonly _numOfErrors: any
    
      constructor (options: any) {
        this._options = options
        this._httpRequestDurationMicroseconds = new Prometheus.Histogram({
          name: 'http_request_duration_ms',
          help: 'Duration of HTTP requests in ms',
          labelNames: ['method', 'route', 'code'],
          buckets: [0.10, 5, 15, 50, 100, 200, 300, 400, 500]
        })
        this._numOfRequests = new Prometheus.Counter({
          name: 'numOfRequests',
          help: 'Number of requests made to a route',
          labelNames: ['route']
        })
        this._numOfErrors = new Prometheus.Counter({
          name: 'numOfErrors',
          help: 'Number of errors',
          labelNames: ['error']
        })
        // TODO: config: ignore routes, disable metrics
      }
    
      public start (req: express.Request, res: express.Response, next: express.NextFunction): void {
        res.locals.startEpoch = Date.now()
        res.on('finish', () => {
          if (req.originalUrl !== '/_metrics' && req.originalUrl !== './favicon.ico') {
            const responseTimeInMs = Date.now() - res.locals.startEpoch
            this._httpRequestDurationMicroseconds
              .labels(req.method, req.originalUrl, res.statusCode.toString())
              .observe(responseTimeInMs)
            this._numOfRequests.inc({ route: req.originalUrl })
            if (res.statusCode >= 400) {
              this._numOfErrors.inc({ error: res.statusCode })
            }
          }
        })
        next()
      }
    
      public endpoint (req: express.Request, res: express.Response): void {
        res.set('Content-Type', Prometheus.register.contentType)
        res.end(Prometheus.register.metrics())
      }
    }
    
    export default Metrics