Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
@doodle/server / src / middlewares / metrics.js
Size: Mime:
const Client = require('prom-client');

const { register, Counter, Histogram } = Client;

/**
 *
 */
const Metrics = {
  /**
   *
   * @param {*} param0
   */
  createRequestsCounter({ metricsPrefix } = {}) {
    const counterRequests = new Counter({
      name: `${metricsPrefix}_requests_total`,
      help: 'The total number of HTTP requests, handled by the nodejs application',
      labelNames: ['code', 'method'],
    });

    return (req, res, next) => {
      res.on('finish', () => {
        if (!res.locals.ignoreMetrics) {
          counterRequests.inc({ code: res.statusCode, method: req.method });
        }
      });

      next();
    };
  },

  /**
   *
   * @param {*} param0
   */
  createDurationHistogram({ metricsPrefix } = {}) {
    const histogramRequestsMs = new Histogram({
      name: `${metricsPrefix}_requests_duration_ms`,
      help: 'Histogram of all request response times in ms buckets, handled by the nodejs application',
      buckets: [5, 10, 25, 50, 100, 300, 500, 1200, 2500, 5000, 10000],
      labelNames: ['code', 'method'],
    });

    return (req, res, next) => {
      const startTime = process.hrtime();

      // https://nodejs.org/api/http.html#http_event_finish Fires when
      // response is handed off to operating system for transmission over
      // the network. Does not mean that the user has received anything.
      res.on('finish', () => {
        if (!res.locals.ignoreMetrics) {
          const diffTime = process.hrtime(startTime);
          const diffTimeMs = Math.round((diffTime[0] * 1e9 + diffTime[1]) / 1000000);
          histogramRequestsMs.labels(res.statusCode, req.method).observe(diffTimeMs);
        }
      });

      next();
    };
  },

  ignoreMetrics(req, res, next) {
    res.locals.ignoreMetrics = true;
    next();
  },

  /**
   *
   * @param {Object} app Express application
   * @param {Object} options Middleware options
   * @param {Object} options.metricsPrefix the metrics name prefix (i.e. `${metricsPrefix}_requests_duration_ms`)
   * @param {Object} options.metricsPath Path to serve the metrics
   */
  initialize(app, { metricsPrefix = 'http', metricsPath = '/metrics' }) {
    Client.collectDefaultMetrics();

    app.use(this.createRequestsCounter({ metricsPrefix }));
    app.use(this.createDurationHistogram({ metricsPrefix }));

    app.get(metricsPath, this.ignoreMetrics, (req, res) => {
      res.set('Content-Type', register.contentType);
      res.end(register.metrics());
    });
  },
};

module.exports = Metrics;