UNPKG

@texagon/nestjs-health

Version:

A comprehensive health monitoring package for NestJS applications with metrics and Kubernetes-ready health checks

101 lines (83 loc) 3 kB
import { Injectable, Logger } from "@nestjs/common"; import { HealthCheckError, HealthIndicator, HealthIndicatorResult, } from "@nestjs/terminus"; import * as os from "os"; interface SystemHealth { memoryHealthy: boolean; diskHealthy: boolean; cpuHealthy: boolean; serviceHealthy: boolean; } @Injectable() export class HealthService extends HealthIndicator { private readonly logger = new Logger(HealthService.name); private isShuttingDown = false; // Thresholds for health checks private readonly memoryThreshold = 0.9; // 90% memory usage is considered unhealthy private readonly cpuThreshold = 0.95; // 95% CPU usage is considered unhealthy private readonly uptimeMinThreshold = 10; // System should be up for at least 10 seconds constructor() { super(); process.on("SIGTERM", () => { this.logger.log( "SIGTERM received, marking service as unhealthy for graceful shutdown", ); this.isShuttingDown = true; }); } async isHealthy(): Promise<HealthIndicatorResult> { // Check multiple aspects of system health const health = await this.checkSystemHealth(); // Only consider unhealthy if service is shutting down or multiple checks fail const isHealthy = health.serviceHealthy && (health.memoryHealthy || health.cpuHealthy); const result = this.getStatus("service", isHealthy, { version: process.env.npm_package_version || "0.0.1", timestamp: new Date().toISOString(), memoryHealthy: health.memoryHealthy, cpuHealthy: health.cpuHealthy, diskHealthy: health.diskHealthy, }); if (isHealthy) { return result; } throw new HealthCheckError("Health check failed", result); } /** * Performs multiple health checks on the system */ private async checkSystemHealth(): Promise<SystemHealth> { // Check if service is in shutdown state const serviceHealthy = !this.isShuttingDown; // Check memory usage const memoryUsage = process.memoryUsage(); const totalMemory = os.totalmem(); const memoryHealthy = memoryUsage.rss / totalMemory < this.memoryThreshold; // Check CPU load const cpuLoad = os.loadavg()[0] / os.cpus().length; const cpuHealthy = cpuLoad < this.cpuThreshold; // For now, assume disk is healthy (we don't have direct disk checks here) const diskHealthy = true; return { memoryHealthy, cpuHealthy, diskHealthy, serviceHealthy, }; } async checkDependencies(): Promise<HealthIndicatorResult> { const isHealthy = true; return this.getStatus("dependencies", isHealthy); } async getMemoryStats(): Promise<HealthIndicatorResult> { const memoryUsage = process.memoryUsage(); return this.getStatus("memory", true, { heapUsed: Math.round(memoryUsage.heapUsed / 1024 / 1024) + "MB", heapTotal: Math.round(memoryUsage.heapTotal / 1024 / 1024) + "MB", rss: Math.round(memoryUsage.rss / 1024 / 1024) + "MB", }); } }