Monitoreo de aplicaciones con Node.js, Grafana y Prometheus

diego.coder26
10 min readJan 4, 2024

Artículo básico de conexión entre Node.js, Grafana y Prometeus. Conceptos y código.

Recomendaciones

Antes de empezar a estudiar el monitoreo de aplicaciones en Node.js con Grafana y Prometheus, se recomienda contar con algunos conocimientos previos antes de leer este artículo, por lo cual, dejo la invitación a revisar los siguientes enlaces de apoyo opcionales:

Artículos de Node.js

25 stories

¿Qué es Grafana?

Grafana es una plataforma de código abierto para la visualización y análisis de datos. Se utiliza comúnmente para crear paneles interactivos y dashboards que muestran información en tiempo real sobre diversos sistemas y servicios. Grafana es compatible con una amplia variedad de fuentes de datos, como bases de datos, sistemas de monitoreo y otros servicios.

Algunas de las características clave de Grafana incluyen:

  1. Conectividad con múltiples fuentes de datos: Grafana puede conectarse a diversas fuentes de datos, como bases de datos SQL, series temporales, sistemas de monitoreo, API REST, y más. Esto permite a los usuarios consolidar datos de diferentes fuentes en un único dashboard.
  2. Creación de dashboards interactivos: Los usuarios pueden diseñar dashboards personalizados con paneles interactivos que muestran gráficos, tablas, mapas y otros elementos visuales. Estos dashboards pueden ser compartidos y exportados.
  3. Soporte para alertas: Grafana permite la configuración de alertas basadas en umbrales y condiciones específicas. Esto es útil para recibir notificaciones en tiempo real cuando ciertos eventos o métricas superan valores predeterminados.
  4. Amplia comunidad y ecosistema: Grafana cuenta con una comunidad activa que contribuye con plugins, integraciones y mejoras constantes. Esto ha llevado a un ecosistema vibrante que amplía las capacidades de la plataforma.
  5. Escalabilidad: Grafana es escalable y puede utilizarse para monitorear desde sistemas pequeños hasta infraestructuras empresariales complejas.

¿Qué es Prometheus?

Prometheus es un sistema de monitoreo y alerta de código abierto diseñado para supervisar sistemas y servicios en entornos de computación distribuida. Prometheus se ha vuelto muy popular en el ecosistema de la nube y es especialmente conocido por su integración con contenedores y orquestadores como Kubernetes.

Algunas características clave de Prometheus son:

  1. Modelo de datos multidimensional: Prometheus utiliza un modelo de datos multidimensional, que permite etiquetar las series temporales. Esto facilita la consulta y la agregación de datos de manera flexible, lo que resulta muy útil en entornos dinámicos y distribuidos.
  2. Recopilación de métricas mediante scraping: Prometheus recopila métricas de los sistemas y servicios mediante un proceso llamado “scraping”. Realiza solicitudes regulares a puntos de enlace HTTP específicos para obtener información sobre el rendimiento y el estado de las aplicaciones.
  3. Lenguaje de consulta PromQL: Prometheus utiliza un lenguaje de consulta llamado PromQL que permite a los usuarios expresar consultas complejas para analizar y visualizar datos. Esto incluye funciones para agregación, filtrado y manipulación de series temporales.
  4. Almacenamiento de series temporales a corto plazo: Prometheus almacena datos en series temporales a corto plazo en su propia base de datos local. Este enfoque facilita la consulta eficiente de datos recientes.
  5. Alertas y notificaciones: Prometheus admite la configuración de reglas de alerta basadas en la evaluación de expresiones PromQL. Puede enviar notificaciones cuando se detectan condiciones de alerta.
  6. Integración con Grafana: Prometheus se integra comúnmente con Grafana, la plataforma de visualización de datos mencionada anteriormente. Grafana permite crear dashboards visuales a partir de datos recopilados por Prometheus.

Grafana y Prometheus la combinación perfecta

Actualmente, Grafana y Prometheus son ampliamente reconocidos y preferidos como la combinación líder en el ámbito del monitoreo y la visualización en tiempo real. Esta popularidad se basa en sus capacidades complementarias y en la forma eficaz en que abordan las necesidades de los entornos de computación modernos.

Prometheus sirve como un sistema de monitoreo altamente especializado que almacena datos en series temporales. Este enfoque se adapta especialmente bien a escenarios en los que se requiere un monitoreo detallado y en tiempo real. Cada serie temporal en Prometheus está compuesta por una métrica y un conjunto de etiquetas que proporcionan contexto adicional. La clave única asociada con cada serie temporal permite un acceso rápido y eficiente a los datos en función del tiempo.

Prometheus captura datos en tiempo real, Grafana los consume y los presenta de manera atractiva en paneles personalizables.

NOTA 🤠: Prometheus puede tener limitaciones en la personalización avanzada de paneles y dashboards. Por esta razón, se recurre a Grafana para la visualización. La capacidad de Grafana para conectarse a varias fuentes de información y su flexibilidad en la personalización de dashboards la convierten en una característica altamente apreciada y utilizada entre los desarrolladores.

Ejemplo demo de una conexión entre Node.js con Grafana y Prometheus

En el siguiente ejemplo vamos a capturar métricas en tiempo real de Nodejs con Express. En este servicio visualizaremos componentes claves de CPU, Memoria RAM y cantidad de peticiones que recibe nuestro servicio.

Prerrequisitos:

  • Tener instalado Nodejs, Grafana y Prometheus en nuestra computadora local.
  • (Opcional) Tener instalado Docker para poder levantar los servicios de Grafana y Prometheus.

NOTA 😀: En este artículo utilizaremos Docker para poder definir y ejecutar las aplicaciones de Grafana y Prometheus.

1- Creación de nuestro proyecto: Para comenzar debemos ejecutar los siguientes comandos en nuestra terminal:

> mkdir nodejs-grafana-prometheus
> cd nodejs-grafana-prometheus
> npm init -y
> npm install express prom-client

Explicación de las dependencias:

  • express: Framework web para Node.js. Utilizado para construir aplicaciones web y servicios API de manera eficiente y sencilla.
  • prom-client: Biblioteca oficial de Prometheus para instrumentar aplicaciones Node.js. Utilizado para medir y rastrear métricas en aplicaciones Node.js, exponiendo métricas compatibles con Prometheus.

2- Posterior a nuestras dependencias, crearemos un archivo base index.js, que incluirá el siguiente código:

const express = require("express");
const promClient = require("prom-client");

const app = express();
const port = 3002;

const collectDefaultMetrics = promClient.collectDefaultMetrics;
collectDefaultMetrics();

const requestCounter = new promClient.Counter({
name: "http_requests_total",
help: "Total number of HTTP requests",
labelNames: ["method", "status_code"],
});

app.get("/", (req, res) => {
requestCounter.inc({ method: req.method, status_code: res.statusCode });
res.send("Hello World!");
});

app.get("/metrics", async (req, res) => {
res.set("Content-Type", promClient.register.contentType);
res.end(await promClient.register.metrics());
});

app.listen(port, () => {
console.log(`App listening at http://localhost:${port}`);
});

Explicación del código:

  1. Importación de módulos: Se importan las bibliotecas express y prom-client. express se utiliza para construir una aplicación web, mientras que prom-client es una biblioteca de Prometheus para instrumentar aplicaciones y exponer métricas.
  2. Configuración de la aplicación Express: Se crea una instancia de la aplicación Express y se establece el puerto en el que la aplicación escuchará las solicitudes (en este caso, el puerto 3002).
  3. Recopilación automática de métricas: Se configura la recopilación automática de métricas predeterminadas utilizando collectDefaultMetrics. Esto incluye métricas del sistema, como el uso de CPU y memoria.
  4. Creación de un contador de métricas: Se crea un contador llamado “http_requests_total” utilizando la biblioteca prom-client. Este contador rastreará el número total de solicitudes HTTP, y tiene etiquetas adicionales para el método de solicitud (GET, POST, etc.) y el código de estado.
  5. Manejo de la ruta principal (“/”): Cuando se recibe una solicitud en la ruta principal (“/”), el contador de métricas se incrementa. Esto significa que se registra la información de la solicitud (método y código de estado) en el contador.
  6. Exposición de métricas en la ruta “/metrics”: Se define una ruta adicional (“/metrics”) para exponer las métricas en un formato compatible con Prometheus. Cuando Prometheus realiza un raspado en esta ruta, recopila y almacena las métricas para su posterior análisis y visualización.
  7. Iniciar la aplicación: La aplicación se inicia y comienza a escuchar en el puerto especificado (3002). Cuando se accede a la ruta principal (“/”), se registra la métrica en el contador, y las métricas pueden ser consultadas por Prometheus accediendo a la ruta “/metrics”.

Para levantar nuestro servicio ejecutar el siguiente comando en la raíz de nuestro proyecto:

> node index.js

Ahora con nuestro proyecto levantado, al consultar la ruta GET /metrics veremos el siguiente mensaje:

NOTA 😀: Esta información está en un formato que Prometheus puede entender y capturar para su registro.

3- Por último levantaremos los servicios de Grafana y Prometheus con Docker compose: En la raíz de nuestro proyecto debemos crear el archivo docker-compose.yml con las siguientes configuraciones:

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"
networks:
- localprom

grafana:
image: grafana/grafana
ports:
- 3000:3000
volumes:
- ./grafana_data:/var/lib/grafana
networks:
- localprom
depends_on:
- prometheus

networks:
localprom:
driver: bridge

# docker-compose up -d (Start services)
# docker-compose down (Down services)

También debemos crear el archivo prometheus.yml en la raíz de nuestro proyecto con las siguientes configuraciones:

global:
scrape_interval: 5s

scrape_configs:
- job_name: "prometheus_service"
static_configs:
- targets: ["host.docker.internal:9090"] # Windows
# - targets: ["docker.for.mac.localhost:9090"] # macOs

- job_name: "nodejs_service"
static_configs:
- targets: ["host.docker.internal:3002"] # Windows
# - targets: ["docker.for.mac.localhost:9090"] # macOs

El archivo prometheus.yml es el archivo de configuración principal de Prometheus. Este archivo define cómo Prometheus debe recopilar métricas de los objetivos que supervisa y cómo debe almacenar y procesar esos datos.

  • La sección global incluye configuraciones globales que se aplican a todo el servidor Prometheus. La configuración scrape_interval define el intervalo de tiempo entre cada raspado (scrape) de los objetivos configurados. En otras palabras, determina con qué frecuencia Prometheus recopilará métricas de los servicios o aplicaciones que está supervisando.
  • La sección scrape_configs define los objetivos que Prometheus debe supervisar y cómo debe obtener métricas de ellos. Cada objetivo tiene un job_name que identifica la tarea de scraping. A su vez, es una práctica común que prometheus se esté observando a sí mismo, es por eso que en la declaración se apunta al puerto de Prometheus.

🛑 Dado que los objetivos no se ejecutan dentro del contenedor de Prometheus, no se puede acceder a ellos a través de localhost. Se debe acceder a ellos a través de la IP privada del host o reemplazando localhost con docker.for.mac.localhost (macOS) u host.docker.internal (Windows).

NOTA 😬: También existe sección alerting permite la configuración de reglas de alerta basadas en condiciones específicas de las métricas, la cual no veremos en este artículo.

Ahora utilizaremos comando docker-compose para levantar el servicio de Grafana y Prometheus

> docker-compose up -d

Accediendo a Prometheus

Una vez ya teniendo nuestro servidor de Node.js ejecutándose, ingresaremos a nuestro navegador con la dirección de http://localhost:9090. En esta ruta se encuentra el servicio de Prometheus (según la configuración de nuestro Docker compose).

Una vez en el panel principal, debemos seleccionar la opción “Status/Targets” del panel superior.

En el apartado de Targets debemos asegurarnos de que Prometheus esté monitoreando las instancias correctas y recopilando las métricas deseadas.

Por último, volviendo al panel principal podemos realizar consultas basándonos en las configuraciones y labels. En apartado de “Graph” podemos ver la evolución sobre la base de valor y tiempo.

Accediendo a Grafana

Una vez ya teniendo nuestro servidor de Node.js ejecutándose y Prometheus, ingresaremos a nuestro navegador con la dirección de http://localhost:3000. En esta ruta se encuentra el servicio de Grafana (según la configuración de nuestro Docker compose).

Al iniciar un servidor con Grafana por primera vez, nos pedirá un usuario y contraseña. Los cuales por defecto tienen el valor de:

  • Usuario: admin
  • Contraseña: admin

Estas credenciales son proporcionadas para facilitar el acceso inicial, posteriormente Grafana nos solicitará cambiar las credenciales.

Una vez en el panel principal de Grafana, debemos seleccionar nuestra fuente de datos o “data source”.

Posterior seleccionar “Prometheus” como nuestra fuente de datos.

También agregar el servidor de Prometheus, en este caso sería “http://host.docker.internal:9090” (Windows) o “http://docker.for.mac.localhost:9090” (macOs). Debemos recordar el nombre del datasource, en este caso es “prometheus-1”.

Para finalizar la configuración, debemos bajar hasta llegar a la última sección del formulario y dar clic en el botón “Save & test”. Si todo sale correctamente nos aparecerá un mensaje de una conexión exitosa.

Para visualizar nuestras métricas debemos seleccionar en el menú izquierdo principal llamado “Explore”.

Luego debemos seleccionar nuestro datasource según el nombre y luego seleccionar las métricas a elección.

Una vez seleccionado la métrica, debemos darle clic al botón “Run Query” para ejecutar la consulta.

En el gráfico, se muestra una línea de tiempo que representa nuestro servicio de Node.js y Prometheus, centrándonos en la métrica “process_cpu_seconds_total”. Para concluir, podemos crear paneles comparativos para visualizar la información que necesitamos. Con esto, hemos establecido una conexión completa entre estas tres tecnologías.

Código fuente

Gracias por haber llegado hasta aquí, si encuentras esto útil, no olvides aplaudir 👏 . Suscríbete para obtener más contenido 🔔.

Si necesita ayuda adicional, comunícate conmigo 🤠.

Muchas gracias por leer, agradezco su tiempo.

--

--

diego.coder26

Hello, my name is Diego! 👦, I am Software Engineer that writes about computer science, mathematics, and personal growth. 👉 😃 linktr.ee/diego.coder