UNPKG

@texagon/nestjs-health

Version:

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

157 lines 7.19 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var MetricsService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetricsService = void 0; const common_1 = require("@nestjs/common"); const os = require("os"); let MetricsService = MetricsService_1 = class MetricsService { constructor() { this.logger = new common_1.Logger(MetricsService_1.name); this.maxHistoryPoints = 100; this.resourceMetrics = []; this.requestMetrics = []; this.maxMemoryUsage = { rss: 0, heapTotal: 0, heapUsed: 0, external: 0, arrayBuffers: 0, }; this.minMemoryUsage = { rss: Number.MAX_SAFE_INTEGER, heapTotal: Number.MAX_SAFE_INTEGER, heapUsed: Number.MAX_SAFE_INTEGER, external: Number.MAX_SAFE_INTEGER, arrayBuffers: Number.MAX_SAFE_INTEGER, }; this.maxCpuUsage = { user: 0, system: 0, percent: 0, }; this.requestStats = { total: 0, byMethod: {}, byStatusCode: {}, avgResponseTime: 0, maxResponseTime: 0, minResponseTime: Number.MAX_SAFE_INTEGER, }; this.lastCpuUsage = process.cpuUsage(); this.lastCpuUsageTime = Date.now(); setInterval(() => this.collectResourceMetrics(), 5000); this.logger.log("Metrics service initialized"); } recordRequest(method, path, statusCode, responseTime) { const timestamp = Date.now(); this.requestMetrics.push({ timestamp, method, path, statusCode, responseTime, }); if (this.requestMetrics.length > this.maxHistoryPoints) { this.requestMetrics.shift(); } this.requestStats.total++; this.requestStats.byMethod[method] = (this.requestStats.byMethod[method] || 0) + 1; const statusRange = `${Math.floor(statusCode / 100)}xx`; this.requestStats.byStatusCode[statusRange] = (this.requestStats.byStatusCode[statusRange] || 0) + 1; this.requestStats.byStatusCode[statusCode.toString()] = (this.requestStats.byStatusCode[statusCode.toString()] || 0) + 1; const prevTotal = this.requestStats.avgResponseTime * (this.requestStats.total - 1); this.requestStats.avgResponseTime = (prevTotal + responseTime) / this.requestStats.total; this.requestStats.maxResponseTime = Math.max(this.requestStats.maxResponseTime, responseTime); this.requestStats.minResponseTime = Math.min(this.requestStats.minResponseTime, responseTime); } collectResourceMetrics() { try { const memoryUsage = process.memoryUsage(); const currentTime = Date.now(); const cpuUsage = process.cpuUsage(); const userDiff = cpuUsage.user - this.lastCpuUsage.user; const systemDiff = cpuUsage.system - this.lastCpuUsage.system; const timeDiff = currentTime - this.lastCpuUsageTime; const cpuPercent = (userDiff + systemDiff) / (timeDiff * 10); const metrics = { timestamp: currentTime, memory: { rss: memoryUsage.rss, heapTotal: memoryUsage.heapTotal, heapUsed: memoryUsage.heapUsed, external: memoryUsage.external, arrayBuffers: memoryUsage.arrayBuffers, }, cpu: { user: cpuUsage.user, system: cpuUsage.system, percent: cpuPercent, }, loadAvg: os.loadavg(), freeMemory: os.freemem(), }; this.maxMemoryUsage.rss = Math.max(this.maxMemoryUsage.rss, memoryUsage.rss); this.maxMemoryUsage.heapTotal = Math.max(this.maxMemoryUsage.heapTotal, memoryUsage.heapTotal); this.maxMemoryUsage.heapUsed = Math.max(this.maxMemoryUsage.heapUsed, memoryUsage.heapUsed); this.maxMemoryUsage.external = Math.max(this.maxMemoryUsage.external, memoryUsage.external); this.maxMemoryUsage.arrayBuffers = Math.max(this.maxMemoryUsage.arrayBuffers || 0, memoryUsage.arrayBuffers || 0); this.minMemoryUsage.rss = Math.min(this.minMemoryUsage.rss, memoryUsage.rss); this.minMemoryUsage.heapTotal = Math.min(this.minMemoryUsage.heapTotal, memoryUsage.heapTotal); this.minMemoryUsage.heapUsed = Math.min(this.minMemoryUsage.heapUsed, memoryUsage.heapUsed); this.minMemoryUsage.external = Math.min(this.minMemoryUsage.external, memoryUsage.external); this.minMemoryUsage.arrayBuffers = Math.min(this.minMemoryUsage.arrayBuffers, memoryUsage.arrayBuffers || 0); this.maxCpuUsage.user = Math.max(this.maxCpuUsage.user, cpuUsage.user); this.maxCpuUsage.system = Math.max(this.maxCpuUsage.system, cpuUsage.system); this.maxCpuUsage.percent = Math.max(this.maxCpuUsage.percent, cpuPercent); this.resourceMetrics.push(metrics); if (this.resourceMetrics.length > this.maxHistoryPoints) { this.resourceMetrics.shift(); } this.lastCpuUsage = cpuUsage; this.lastCpuUsageTime = currentTime; } catch (error) { this.logger.error(`Error collecting metrics: ${error.message}`); } } getMetrics() { return { current: this.resourceMetrics.length > 0 ? this.resourceMetrics[this.resourceMetrics.length - 1] : null, max: { memory: this.maxMemoryUsage, cpu: this.maxCpuUsage, }, min: { memory: this.minMemoryUsage, }, requests: { stats: this.requestStats, recent: this.requestMetrics.slice(-10), }, history: { resources: this.resourceMetrics, }, }; } }; exports.MetricsService = MetricsService; exports.MetricsService = MetricsService = MetricsService_1 = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", []) ], MetricsService); //# sourceMappingURL=metrics.service.js.map