Verificações de integridade
As verificações de integridade são realizadas para garantir que seu aplicativo esteja em um estado íntegro durante a execução em produção. Isso pode incluir o monitoramento do espaço em disco disponível no servidor, a memória consumida pelo seu aplicativo ou testar a conexão do banco de dados.
O AdonisJS fornece um punhado de verificações de integridade integradas e a capacidade de criar e registrar verificações de integridade personalizadas.
Configurando verificações de integridade
Você pode configurar verificações de integridade em seu aplicativo executando o seguinte comando. O comando criará um arquivo start/health.ts
e configurará verificações de integridade para uso de memória e espaço em disco usado. Sinta-se à vontade para modificar este arquivo e remover/adicionar verificações de integridade adicionais.
NOTA
Certifique-se de ter instalado @adonisjs/core@6.12.1
antes de usar o comando a seguir.
node ace configure health_checks
// start/health.ts
import { HealthChecks, DiskSpaceCheck, MemoryHeapCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck(),
new MemoryHeapCheck(),
])
Expondo um endpoint
Uma abordagem comum para executar verificações de integridade é expor um endpoint HTTP que um serviço de monitoramento externo pode executar ping para coletar os resultados da verificação de integridade.
Então, vamos definir uma rota dentro do arquivo start/routes.ts
e vincular o HealthChecksController
a ele. O arquivo health_checks_controller.ts
é criado durante a configuração inicial e fica dentro do diretório app/controllers
.
// start/routes.ts
import router from '@adonisjs/core/services/router'
const HealthChecksController = () => import('#controllers/health_checks_controller')
router.get('/health', [HealthChecksController])
Relatório de exemplo
O método healthChecks.run
executará todas as verificações e retornará um relatório detalhado como um objeto JSON. O relatório tem as seguintes propriedades:
{
"isHealthy": true,
"status": "warning",
"finishedAt": "2024-06-20T07:09:35.275Z",
"debugInfo": {
"pid": 16250,
"ppid": 16051,
"platform": "darwin",
"uptime": 16.271809083,
"version": "v21.7.3"
},
"checks": [
{
"name": "Disk space check",
"isCached": false,
"message": "Disk usage is 76%, which is above the threshold of 75%",
"status": "warning",
"finishedAt": "2024-06-20T07:09:35.275Z",
"meta": {
"sizeInPercentage": {
"used": 76,
"failureThreshold": 80,
"warningThreshold": 75
}
}
},
{
"name": "Memory heap check",
"isCached": false,
"message": "Heap usage is under defined thresholds",
"status": "ok",
"finishedAt": "2024-06-20T07:09:35.265Z",
"meta": {
"memoryInBytes": {
"used": 41821592,
"failureThreshold": 314572800,
"warningThreshold": 262144000
}
}
}
]
}
isHealthy
Um booleano para saber se todas as verificações foram aprovadas. O valor será definido como false
se uma ou mais verificações falharem.
status
Relata o status após executar todas as verificações. Será um dos seguintes.
ok
: todas as verificações foram aprovadas com sucesso.warning
: uma ou mais verificações relataram um aviso.error
: uma ou mais verificações falharam.
finishedAt
A data e hora em que os testes foram concluídos.
checks
Uma matriz de objetos contendo o relatório detalhado de todas as verificações realizadas.
debugInfo
As informações de depuração podem ser usadas para identificar o processo e a duração em que ele está em execução. Elas incluem as seguintes propriedades.
pid
: O ID do processo.ppid
: O ID do processo do processo pai que gerencia seu processo de aplicativo AdonisJS.platform
: A plataforma na qual o aplicativo está em execução.uptime
: A duração (em segundos) em que o aplicativo está em execução.version
: Versão do Node.js.
Protegendo o endpoint
Você pode proteger o endpoint /health
do acesso público usando o middleware auth ou criando um middleware personalizado que verifica um segredo de API específico dentro do cabeçalho da solicitação. Por exemplo:
import router from '@adonisjs/core/services/router'
const HealthChecksController = () => import('#controllers/health_checks_controller')
router
.get('/health', [HealthChecksController])
.use(({ request, response }, next) => {
if (request.header('x-monitoring-secret') === 'some_secret_value') {
return next()
}
response.unauthorized({ message: 'Unauthorized access' })
})
Verificações de integridade disponíveis
A seguir está a lista de verificações de integridade disponíveis que você pode configurar no arquivo start/health.ts
.
DiskSpaceCheck
O DiskSpaceCheck
calcula o espaço em disco usado no seu servidor e relata um aviso/erro quando um certo limite é excedido.
import { HealthChecks, DiskSpaceCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck()
])
Por padrão, o limite de aviso é definido como 75% e o limite de falha é definido como 80%. No entanto, você também pode definir limites personalizados.
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck()
.warnWhenExceeds(80) // avisa quando usado acima de 80%
.failWhenExceeds(90), // falha quando usado acima de 90%
])
MemoryHeapCheck
O MemoryHeapCheck
monitora o tamanho do heap relatado pelo método process.memoryUsage() e relata um aviso/erro quando um certo limite é excedido.
import { HealthChecks, MemoryHeapCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new MemoryHeapCheck()
])
Por padrão, o limite de aviso é definido como 250 MB e o limite de falha é definido como 300 MB. No entanto, você também pode definir limites personalizados.
export const healthChecks = new HealthChecks().register([
new MemoryHeapCheck()
.warnWhenExceeds('300 mb')
.failWhenExceeds('700 mb'),
])
MemoryRSSCheck
O MemoryRSSCheck
monitora o tamanho do conjunto residente relatado pelo método process.memoryUsage() e relata um aviso/erro quando um certo limite é excedido.
import { HealthChecks, MemoryRSSCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new MemoryRSSCheck()
])
Por padrão, o limite de aviso é definido como 320 MB e o limite de falha é definido como 350 MB. No entanto, você também pode definir limites personalizados.
export const healthChecks = new HealthChecks().register([
new MemoryRSSCheck()
.warnWhenExceeds('600 mb')
.failWhenExceeds('800 mb'),
])
DbCheck
O DbCheck
é fornecido pelo pacote @adonisjs/lucid
para monitorar a conexão com um banco de dados SQL. Você pode importá-lo e usá-lo da seguinte maneira.
import db from '@adonisjs/lucid/services/db'
import { DbCheck } from '@adonisjs/lucid/database'
import { HealthChecks, DiskSpaceCheck, MemoryHeapCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck(),
new MemoryHeapCheck(),
new DbCheck(db.connection()),
])
A seguir está um relatório de exemplo da verificação de integridade do banco de dados.
// Exemplo de relatório
{
"name": "Database health check (postgres)",
"isCached": false,
"message": "Successfully connected to the database server",
"status": "ok",
"finishedAt": "2024-06-20T07:18:23.830Z",
"meta": {
"connection": {
"name": "postgres",
"dialect": "postgres"
}
}
}
A classe DbCheck
aceita uma conexão de banco de dados para monitoramento. Registre esta verificação várias vezes para cada conexão se quiser monitorar várias conexões. Por exemplo:
// Monitorando múltiplas conexões
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck(),
new MemoryHeapCheck(),
new DbCheck(db.connection()),
new DbCheck(db.connection('mysql')),
new DbCheck(db.connection('pg')),
])
DbConnectionCountCheck
O DbConnectionCountCheck
monitora as conexões ativas no servidor de banco de dados e relata um aviso/erro quando um determinado limite é excedido. Esta verificação é suportada apenas para bancos de dados PostgreSQL e MySQL.
import db from '@adonisjs/lucid/services/db'
import { DbCheck, DbConnectionCountCheck } from '@adonisjs/lucid/database'
import { HealthChecks, DiskSpaceCheck, MemoryHeapCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck(),
new MemoryHeapCheck(),
new DbCheck(db.connection()),
new DbConnectionCountCheck(db.connection())
])
A seguir está um relatório de exemplo da verificação de integridade da contagem de conexões do banco de dados.
// Exemplo de relatório
{
"name": "Connection count health check (postgres)",
"isCached": false,
"message": "There are 6 active connections, which is under the defined thresholds",
"status": "ok",
"finishedAt": "2024-06-20T07:30:15.840Z",
"meta": {
"connection": {
"name": "postgres",
"dialect": "postgres"
},
"connectionsCount": {
"active": 6,
"warningThreshold": 10,
"failureThreshold": 15
}
}
}
Por padrão, o limite de aviso é definido como 10 conexões e o limite de falha é definido como 15 conexões. No entanto, você também pode definir limites personalizados.
new DbConnectionCountCheck(db.connection())
.warnWhenExceeds(4)
.failWhenExceeds(10)
RedisCheck
O RedisCheck
é fornecido pelo pacote @adonisjs/redis
para monitorar a conexão com um banco de dados Redis (incluindo Cluster). Você pode importar e usar da seguinte forma.
import redis from '@adonisjs/redis/services/main'
import { RedisCheck } from '@adonisjs/redis'
import { HealthChecks, DiskSpaceCheck, MemoryHeapCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck(),
new MemoryHeapCheck(),
new RedisCheck(redis.connection()),
])
A seguir está um exemplo de relatório da verificação de integridade do banco de dados.
// Exemplo de relatório
{
"name": "Redis health check (main)",
"isCached": false,
"message": "Successfully connected to the redis server",
"status": "ok",
"finishedAt": "2024-06-22T05:37:11.718Z",
"meta": {
"connection": {
"name": "main",
"status": "ready"
}
}
}
A classe RedisCheck
aceita uma conexão redis para monitorar. Registre esta verificação várias vezes para cada conexão se quiser monitorar várias conexões. Por exemplo:
// Monitoramento de múltiplas conexões
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck(),
new MemoryHeapCheck(),
new RedisCheck(redis.connection()),
new RedisCheck(redis.connection('cache')),
new RedisCheck(redis.connection('locks')),
])
RedisMemoryUsageCheck
O RedisMemoryUsageCheck
monitora o consumo de memória do servidor redis e relata um aviso/erro quando um determinado limite é excedido.
import redis from '@adonisjs/redis/services/main
import { RedisCheck, RedisMemoryUsageCheck } from '@adonisjs/redis'
import { HealthChecks, DiskSpaceCheck, MemoryHeapCheck } from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck(),
new MemoryHeapCheck(),
new RedisCheck(redis.connection()),
new RedisMemoryUsageCheck(redis.connection())
])
A seguir está um exemplo de relatório da verificação de integridade do uso de memória redis.
// Exemplo de relatório
{
"name": "Redis memory consumption health check (main)",
"isCached": false,
"message": "Redis memory usage is 1.06MB, which is under the defined thresholds",
"status": "ok",
"finishedAt": "2024-06-22T05:36:32.524Z",
"meta": {
"connection": {
"name": "main",
"status": "ready"
},
"memoryInBytes": {
"used": 1109616,
"warningThreshold": 104857600,
"failureThreshold": 125829120
}
}
}
Por padrão, o limite de aviso é definido como 100 MB e o limite de falha é definido como 120 MB. No entanto, você também pode definir limites personalizados.
new RedisMemoryUsageCheck(db.connection())
.warnWhenExceeds('200MB')
.failWhenExceeds('240MB')
Resultados de cache
As verificações de integridade são executadas sempre que você chama o método healthChecks.run
(também conhecido como visita o endpoint /health
). Você pode querer executar ping no endpoint /health
com frequência, mas evite executar determinadas verificações em cada visita.
Por exemplo, monitorar o espaço em disco a cada minuto não é muito útil, mas rastrear a memória a cada minuto pode ser útil.
Portanto, permitimos que você armazene em cache os resultados de verificações de integridade individuais ao registrá-las. Por exemplo:
import {
HealthChecks,
MemoryRSSCheck,
DiskSpaceCheck,
MemoryHeapCheck,
} from '@adonisjs/core/health'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck().cacheFor('1 hour'),
new MemoryHeapCheck(), // não armazenar em cache
new MemoryRSSCheck(), // não armazenar em cache
])
Criando uma verificação de integridade personalizada
Você pode criar uma verificação de integridade personalizada como uma classe JavaScript que adere à interface HealthCheckContract. Você pode definir uma verificação de integridade em qualquer lugar dentro do seu projeto ou pacote e importá-la dentro do arquivo start/health.ts
para registrá-la.
import { Result, BaseCheck } from '@adonisjs/core/health'
import type { HealthCheckResult } from '@adonisjs/core/types/health'
export class ExampleCheck extends BaseCheck {
async run(): Promise<HealthCheckResult> {
/**
* As verificações a seguir são apenas para fins de referência
*/
if (checkPassed) {
return Result.ok('Success message to display')
}
if (checkFailed) {
return Result.failed('Error message', errorIfAny)
}
if (hasWarning) {
return Result.warning('Warning message')
}
}
}
Conforme mostrado no exemplo acima, você pode usar a classe Result para criar resultados de verificação de integridade. Opcionalmente, você pode mesclar metadados para o resultado da seguinte forma.
Result.ok('Database connection is healthy').mergeMetaData({
connection: {
dialect: 'pg',
activeCount: connections,
},
})
Registrando verificação de integridade personalizada
Você pode importar sua classe de verificação de integridade personalizada dentro do arquivo start/health.ts
e registrá-la criando uma nova instância de classe.
import { ExampleCheck } from '../app/health_checks/example.js'
export const healthChecks = new HealthChecks().register([
new DiskSpaceCheck().cacheFor('1 hour'),
new MemoryHeapCheck(),
new MemoryRSSCheck(),
new ExampleCheck()
])