La Santa Trinidad: Prometheus + Grafana + Express

TODOS LOS CONCEPTOS AQUÍ EXPLICADOS ESTÁN REFLEJADOS EN ESTE REPOSITORIO

Introducción

Una parte fundamental en el mundo del desarrollo es tener la capacidad de controlar el estado de nuestros sistemas en cualquier momento, con información clara y representada de forma concisa.

En esta entrada vamos a ver cómo medir ciertas métricas, recolectarlas y finalmente representarlas en paneles muy visuales.

Un punto clave en todo este engranaje es entender cómo y en qué sentido fluye la información. Y digo esto porque yo mismo tenía un concepto erróneo de cómo ocurría al pensar que era el generador de métricas, típicamente un servidor, el que enviaba la información al sistemas que las recolecta, en este caso Prometheus y es todo lo contrario. Como veremos más adelante es el propio Prometheus el que se encarga de escanear una lista de hosts en buscas de métricas.

Para nuestra prueba vamos a usar Docker Compose y asi simular un entorno bastante parecido a lo que sería un entorno de producción.

Los principales imágenes que vamos a usar serán:

Métricas

Como ya podíamos esperar los datos siempre se van a generar dónde llega el tráfico, por lo que hablaremos siempre de servidores.

Para tratar de plasmar estos conceptos en un ejemplo real usare un servidor en Node con una API en Express y un paquete llamado express prometheus bundle el cual out-of-the-box nos va a dar una serie de métricas típicas.

import promBundle from 'express-prom-bundle'
import promClient from 'prom-client'
import express from 'express'
import os from 'os'
import pidusage from 'pidusage'

const cpuGauge = new promClient.Gauge({ name: 'nodejs_cpu', help: 'cpu usage' })
const memoryGauge = new promClient.Gauge({
  name: 'nodejs_memory',
  help: 'memory usage',
})

setInterval(async () => {
  const stats = await pidusage(process.pid)
  memoryGauge.set(stats.memory / 1024 / 1024)
  cpuGauge.set(stats.cpu)
}, 10000)

promClient.collectDefaultMetrics()

const app = express()

const metricsMiddleware = promBundle({ includeMethod: true })

app.use(metricsMiddleware)
app.listen(8080)

Con este código ya seremos capaces de tener una serie de métricas básicas en http://localhost:3000/metrics

metrics

Prometheus

Una vez que tenemos métricas llega el momento de recolectarlas para poder analizarlas y empezar a jugar con ellas. En este punto entra Prometheus el cual es el encargado de escanear una serie de hosts, obtener las métricas y almacenarlas.

Para que sea capaz de encontrar los equipos a escanear es necesario pasarle un fichero de configuración en formato yaml con la siguiente configuración:

...
scrape_configs:
 - job_name: prometheus
   ...
   static_configs:
     - targets:
         - server:8080
...

En el repositorio están todos los ficheros completos por si necesitas mas información

consumer

Grafana

Por último, ya tenemos las métricas y las hemos recogido, sólo nos queda representar los datos de la forma más útil posible y nada mejor que Grafana para conseguirlo.

Esta parte es bastante sencilla ya que primer debemos incluir una nueva fuente de datos en ajustes, en nuestro caso nuestro Prometheus:

consumer

Y posteriormente crear un nuevo panel con una de nuestras métricas como por ejemplo rate(nodes_js_cpu[2m])

consumer

Conclusiones

Y con esto ya estaría! Espero que os haya resultado útil como punto de partida ver cómo podemos montar un sistema de monitorización.