Criando Health Check para microserviços

Veja formas de acompanhar a saúde da sua aplicação em produção!

Criando Health Check para microserviços
Photo by Douglas Lopes / Unsplash

Se você utiliza microserviço em algum ponto da sua solução, saiba que é muito importante monitorar cada um separadamente, observando se a aplicação está rodando, tempo de resposta e teste de componentes relacionados (banco de dados por exemplo).
Vou mostrar como criar um endpoint para heath check dentro do Nodejs com express (não vamos abordar nada que não possa ser passado para outra linguagem e framework).

Vamos imaginar que temos um microserviço simples, que retorna uma coleção de dados quando executamos uma chamada na rota raiz:
https://health-check-tuliocll.herokuapp.com/
Imaginando que esse serviço seja fundamental para o funcionamento da minha aplicação, vamos querer receber alertas e até acompanhar algumas métricas sobre sua disponibilidade, para isso, vamos começar criando dados para que possamos coletar informações.

generated with Summaryze Forem 🌱

Criando projeto

Vou iniciar um projeto super simples em Nodejs com express, junto ao projeto, vou criar um arquivo json contendo a lista de todos os meus posts aqui no dev.to, para simular um banco de dados, ficando dessa forma:

image

E minha rota:

image

Criando Health Check

Agora, vou criar um novo arquivo de rota e registra-lo no express, o conteúdo desse meu novo arquivo será:

image

Bom, aqui eu criei uma rota chamada /health-check e nela estou simplesmente retornando dados básicos da minha aplicação, entre eles: uptime (que pega o tempo que o processo tem rodando) e message (que é onde posso informar alguma mensagem para ser tratada em um dashboard depois).
Podemos visualizar nosso health check aqui: https://health-check-tuliocll.herokuapp.com/health-check

Melhorando

Podemos melhorar bastante o nosso Health Check, primeiramente, caso o nosso microserviço tenha um banco de dados como dependência, deveríamos tentar conectar nesse banco e retornar a resposta dessa tentativa, a mesma coisa caso utilizamos algo como Redis ou algum serviço externo.
Um exemplo legal seria:

const express = require("express");

const router = express.Router();

router.get("/health-check", (_, res) => {

  const bdCheck = bd.connect();
  const redisTest = redis.test();

  let status = bdCheck && redisTest
  

  const healthcheck = {
    uptime: process.uptime(),
    message: status ? "OK" : "ERROR",
    timestamp: Date.now(),
    checks: [
      {
        name: "Banco de dados",
        type: "internal",
        status: bdCheck,
      },
      {
        name: "Redis",
        type: "internal",
        status: redisTest
      }
    ]
  };

  res.send(healthcheck);
});

module.exports = router;

Dessa forma, vamos ter no nosso health check a informação de todos os componentes que são necessários para o nosso serviço rodar, e caso tenha problema em algum deles, vamos ser mais assertivos na correção:

image

Visualizando dados

Para sermos mais eficiente ainda, podemos integrar nossa resposta a alguma plataforma/dashboard que receba esses dados e monte de forma mais intuitiva e simples e que faça chamadas a esse endpoints em intervalos de tempo, criando alertas para caso algo saia do esperado.
Para isso temos diversas alternativas:

Zabbix

image


Uma excelente alternativa, muito robusto, código aberto e você pode hospedar sua própria instancia do serviço.

Freshping

Uma alternativa freemium muito competente, apesar de ter suas limitações, consegue fazer o acompanhamento do serviço, criar alertas e permite algumas personalizações:

image

Concluindo

Existem diversas bibliotecas que automatizam algumas dessas capturas também, como o Terminus, que além de ter o health check ajuda com graceful shutdown (Ainda quero escrever sobre).
Como de costume o código utilizado aqui está no github e você pode consultar aqui.