metrics.ts 1.48 KB
Newer Older
1 2 3 4 5
import prometheus, {
  collectDefaultMetrics,
  DefaultMetricsCollectorConfiguration,
  Registry,
} from 'prom-client'
6 7 8 9
import express from 'express'
import { Server } from 'net'

import { Logger } from './logger'
10 11

export interface MetricsOptions {
12
  prefix?: string
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
  labels?: Object
}

export class Metrics {
  options: MetricsOptions
  client: typeof prometheus
  registry: Registry

  constructor(options: MetricsOptions) {
    this.options = options

    const metricsOptions: DefaultMetricsCollectorConfiguration = {
      prefix: options.prefix,
      labels: options.labels,
    }

    this.client = prometheus
    this.registry = prometheus.register

    // Collect default metrics (event loop lag, memory, file descriptors etc.)
    collectDefaultMetrics(metricsOptions)
  }
}
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68

export interface MetricsServerOptions {
  logger: Logger
  registry: Registry
  port?: number
  route?: string
  hostname?: string
}

export const createMetricsServer = async (
  options: MetricsServerOptions
): Promise<Server> => {
  const logger = options.logger.child({ component: 'MetricsServer' })

  const app = express()

  const route = options.route || '/metrics'
  app.get(route, async (_, res) => {
    res.status(200).send(await options.registry.metrics())
  })

  const port = options.port || 7300
  const hostname = options.hostname || '127.0.0.1'
  const server = app.listen(port, hostname, () => {
    logger.info('Metrics server started', {
      port,
      hostname,
      route,
    })
  })

  return server
}