Table of Contents
Monitorización de aplicaciones



Instalar Grafana y Prometheus
Lanzaremos Grafana y Prometheus como contenedores docker, configurados en una red para que puedan verse el uno al otro. Al mismo tiempo publicaremos los puertos sobre la máquina local para poder acceder a sus interfaces web:
version: "3" services: prometheus: image: prom/prometheus ports: - 9090:9090 volumes: - ./prometheus_data:/prometheus - ./prometheus.yml:/etc/prometheus/prometheus.yml command: - "--config.file=/etc/prometheus/prometheus.yml" extra_hosts: - "host.docker.internal:192.168.1.120" # coloca aqui la IP local de tu equipo networks: - localprom grafana: image: grafana/grafana-enterprise ports: - 3000:3000 volumes: - ./grafana_data:/var/lib/grafana extra_hosts: - "host.docker.internal:192.168.1.120" # coloca aqui la IP local de tu equipo networks: - localprom depends_on: - prometheus networks: localprom: driver: bridge
Hay que tener en cuenta que:
Grafana
quedará accesible en http://localhost:3000Prometheus
quedará accesible en http://localhost:9090
A su vez dejaremos este fichero, prometheus.yml
en la carpeta raíz de nuestro proyecto. Ahi configuramos donde escuchan prometheus y el servicio que estamos monitorizando:
- prometheus.yml
global: scrape_interval: 5s scrape_configs: - job_name: "prometheus_service" static_configs: - targets: ["host.docker.internal:9090"] - job_name: "nodejs_service" static_configs: - targets: ["host.docker.internal:8080"]
Integrar Grafana con Node.js
Ahora tendremos que facilitar un endpoint /metrics
en nuestro servicio para que Prometheus pueda extraer las métricas de nuestro servicio haciendo peticiones al mismo.
Primero, añadimos la librería de Prometheus para nuestra aplicación:
"dependencies": { . . . "prom-client": "^15.1.3" },
Y definimos una serie de métricas en el fichero config/metrics.js
. Más adelante las haremos accesible como respuesta en el endpoint /metrics
que vamos a publicar:
- config/metrics.js
'use strict'; const promClient = require('prom-client'); // Crea un histograma para registrar la duración de las peticiones HTTP en segundos const httpRequestDurationSeconds = new promClient.Histogram({ name: 'http_request_duration_seconds', help: 'Duration of HTTP requests in seconds', labelNames: ['method', 'path', 'code'], }); // Crea un contador de peticiones HTTP totales const httpRequestsTotal = new promClient.Counter({ name: 'http_requests_total', help: 'How many HTTP requests processed, partitioned by status code, method, and HTTP path', labelNames: ['method', 'path', 'code'], }); // Crea una medición de las peticiones HTTP en vuelo const inFlightRequests = new promClient.Gauge({ name: 'http_requests_in_flight', help: 'Current number of in-flight HTTP requests', }); module.exports = { httpRequestDurationSeconds, httpRequestsTotal, inFlightRequests, };
En nuestro fichero principal, app.js
, configuraremos lo necesario para recoger las métricas que hemos configurado antes y publicaremos el nuevo endpoint /metrics
que las dejará accesibles para Prometheus, que es quién las recoge y almacena.
También llamaremos a promClient.collectDefaultMetrics()
que recoge algunas métricas ya establecidas por defecto que quizás nos pueda interesar también mostrar en los Dashboards que haremos con Grafana.
- apps.js
const promClient = require('prom-client'); const { httpRequestDurationSeconds, httpRequestsTotal, inFlightRequests } = require('./config/metrics'); . . . // Recoge métricas por defecto promClient.collectDefaultMetrics(); . . . // Recoger las métricas configuradas en config/metrics app.use((req, res, next) => { // Anota la request en vuelo inFlightRequests.inc(); // Inicia un timer para comenzar a calcular la duración de la request const end = httpRequestDurationSeconds.startTimer(); const method = req.method; const path = req.route ? req.route.path : req.path; // Cada vez que una request termina, se recogen las métricas configuradas res.on('finish', () => { const statusCode = res.statusCode; // Captura la duración de la petición end({ method, path, code: statusCode }); // Incrementa el contador de peticiones HTTP httpRequestsTotal.inc({ code: statusCode, method: method.toLowerCase(), path: path }); // Decrementa el contador de peticiones en vuelo inFlightRequests.dec(); }); next(); }); // Define el endpoint que usará prometheus para recoger las métricas app.get('/metrics', async(req, res) => { try { res.set('Content-Type', promClient.register.contentType); res.end(await promClient.register.metrics()); } catch (error) { res.status(500).end(error); } }); . . . app.use('/', cities); . . .
En http://localhost:8080/metrics ya podremos visualizar las métricas (como texto plano)

Comprobar la configuración de Prometheus
Antes de seguir, para comprobar que todo está funcionando bien, podemos echar un vistazo en Prometheus y verificar que tiene acceso a las métricas que nuestro servicio publica a través del endpoint /metrics
que acabamos de configurar:
Status → Targets

Configurar un dashboard en Grafana
Añadir Prometheus como connection
Ahora, accediendo al interfaz web de Grafana (http://localhost:3000), configuraremos a Prometheus como un nuevo conector ya que proporcionará datos para los Dashboards que queremos diseñar en Grafana.
Accedemos a Connection → Add new connection → Prometheus

Y pulsamos Save & test
para darlo por configurado