@texagon/nestjs-health
Version:
A comprehensive health monitoring package for NestJS applications with metrics and Kubernetes-ready health checks
157 lines • 7.19 kB
JavaScript
"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