UNPKG

datapilot-cli

Version:

Enterprise-grade streaming multi-format data analysis with comprehensive statistical insights and intelligent relationship detection - supports CSV, JSON, Excel, TSV, Parquet - memory-efficient, cross-platform

354 lines 12.9 kB
"use strict"; /** * Health Check System * Production monitoring and health endpoints */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.healthEndpoints = exports.globalHealthChecker = void 0; const memory_manager_1 = require("../utils/memory-manager"); const error_handler_1 = require("../utils/error-handler"); const version_1 = require("../utils/version"); class HealthChecker { startTime; requestCount = 0; successfulRequests = 0; failedRequests = 0; responseTimes = []; constructor() { this.startTime = Date.now(); } /** * Perform comprehensive health check */ async checkHealth() { const checks = []; const startTime = Date.now(); // Memory health check checks.push(await this.checkMemoryHealth()); // Error rate check checks.push(await this.checkErrorRate()); // Performance check checks.push(await this.checkPerformance()); // Dependencies check (file system, etc.) checks.push(await this.checkDependencies()); // Calculate summary const passing = checks.filter((c) => c.status === 'pass').length; const failing = checks.filter((c) => c.status === 'fail').length; const warnings = checks.filter((c) => c.status === 'warn').length; // Determine overall status let status; if (failing > 0) { status = 'unhealthy'; } else if (warnings > 0) { status = 'degraded'; } else { status = 'healthy'; } return { status, timestamp: new Date().toISOString(), uptime: Date.now() - this.startTime, version: process.env.npm_package_version || (0, version_1.getDataPilotVersion)(), checks, summary: { total: checks.length, passing, failing, warnings, }, }; } /** * Get detailed monitoring metrics */ getMetrics() { const memoryUsage = memory_manager_1.globalMemoryManager.getMemoryStats(); const errorStats = error_handler_1.globalErrorHandler.getErrorStatistics(); const cpuUsage = process.cpuUsage(); return { memory: { heapUsed: Math.round(memoryUsage.current.heapUsed / (1024 * 1024)), heapTotal: Math.round(memoryUsage.current.heapTotal / (1024 * 1024)), external: Math.round(memoryUsage.current.external / (1024 * 1024)), rss: Math.round(memoryUsage.current.rss / (1024 * 1024)), percentUsed: Math.round((memoryUsage.current.heapUsed / memoryUsage.current.heapTotal) * 100), }, performance: { uptime: Date.now() - this.startTime, cpuUsage, eventLoopDelay: this.measureEventLoopDelay(), }, errors: { total: errorStats.totalErrors, last24h: this.getErrorsLast24h(), byCategory: errorStats.byCategory, bySeverity: errorStats.bySeverity, }, requests: { total: this.requestCount, successful: this.successfulRequests, failed: this.failedRequests, averageResponseTime: this.getAverageResponseTime(), }, }; } /** * Record request metrics */ recordRequest(success, responseTime) { this.requestCount++; if (success) { this.successfulRequests++; } else { this.failedRequests++; } this.responseTimes.push(responseTime); // Keep only last 1000 response times if (this.responseTimes.length > 1000) { this.responseTimes.shift(); } } /** * Check memory health */ async checkMemoryHealth() { const start = Date.now(); try { const memoryUsage = memory_manager_1.globalMemoryManager.getMemoryStats(); const percentUsed = Math.round((memoryUsage.current.heapUsed / memoryUsage.current.heapTotal) * 100); let status; let message; if (percentUsed < 70) { status = 'pass'; message = `Memory usage normal (${percentUsed.toFixed(1)}%)`; } else if (percentUsed < 85) { status = 'warn'; message = `Memory usage elevated (${percentUsed.toFixed(1)}%)`; } else { status = 'fail'; message = `Memory usage critical (${percentUsed.toFixed(1)}%)`; } return { name: 'memory', status, message, duration: Date.now() - start, metadata: { heapUsedMB: Math.round(memoryUsage.current.heapUsed / (1024 * 1024)), heapTotalMB: Math.round(memoryUsage.current.heapTotal / (1024 * 1024)), percentUsed, }, }; } catch (error) { return { name: 'memory', status: 'fail', message: `Memory check failed: ${error instanceof Error ? error.message : 'Unknown error'}`, duration: Date.now() - start, }; } } /** * Check error rate */ async checkErrorRate() { const start = Date.now(); try { const errorStats = error_handler_1.globalErrorHandler.getErrorStatistics(); const last24hErrors = this.getErrorsLast24h(); const errorRate = this.requestCount > 0 ? (this.failedRequests / this.requestCount) * 100 : 0; let status; let message; if (errorRate < 5) { status = 'pass'; message = `Error rate normal (${errorRate.toFixed(1)}%)`; } else if (errorRate < 15) { status = 'warn'; message = `Error rate elevated (${errorRate.toFixed(1)}%)`; } else { status = 'fail'; message = `Error rate critical (${errorRate.toFixed(1)}%)`; } return { name: 'error_rate', status, message, duration: Date.now() - start, metadata: { errorRate, totalErrors: errorStats.totalErrors, last24hErrors, }, }; } catch (error) { return { name: 'error_rate', status: 'fail', message: `Error rate check failed: ${error instanceof Error ? error.message : 'Unknown error'}`, duration: Date.now() - start, }; } } /** * Check performance metrics */ async checkPerformance() { const start = Date.now(); try { const avgResponseTime = this.getAverageResponseTime(); const eventLoopDelay = this.measureEventLoopDelay(); let status; let message; if (avgResponseTime < 1000 && eventLoopDelay < 10) { status = 'pass'; message = `Performance normal (${avgResponseTime}ms avg response)`; } else if (avgResponseTime < 5000 && eventLoopDelay < 50) { status = 'warn'; message = `Performance degraded (${avgResponseTime}ms avg response)`; } else { status = 'fail'; message = `Performance critical (${avgResponseTime}ms avg response)`; } return { name: 'performance', status, message, duration: Date.now() - start, metadata: { averageResponseTime: avgResponseTime, eventLoopDelay, uptime: Date.now() - this.startTime, }, }; } catch (error) { return { name: 'performance', status: 'fail', message: `Performance check failed: ${error instanceof Error ? error.message : 'Unknown error'}`, duration: Date.now() - start, }; } } /** * Check system dependencies */ async checkDependencies() { const start = Date.now(); try { // Test file system access const fs = await Promise.resolve().then(() => __importStar(require('fs'))); const tmpDir = require('os').tmpdir(); // Try to write a test file await fs.promises.writeFile(`${tmpDir}/datapilot-health-check`, 'test'); await fs.promises.unlink(`${tmpDir}/datapilot-health-check`); return { name: 'dependencies', status: 'pass', message: 'All dependencies accessible', duration: Date.now() - start, metadata: { fileSystem: 'accessible', nodeVersion: process.version, }, }; } catch (error) { return { name: 'dependencies', status: 'fail', message: `Dependency check failed: ${error instanceof Error ? error.message : 'Unknown error'}`, duration: Date.now() - start, }; } } /** * Simple readiness check */ isReady() { const memoryUsage = memory_manager_1.globalMemoryManager.getMemoryStats(); const percentUsed = Math.round((memoryUsage.current.heapUsed / memoryUsage.current.heapTotal) * 100); return percentUsed < 90; } /** * Simple liveness check */ isAlive() { return true; // If this code is running, the process is alive } getErrorsLast24h() { // This would require timestamp tracking in error handler // For now, return approximate based on total errors const errorStats = error_handler_1.globalErrorHandler.getErrorStatistics(); return Math.floor(errorStats.totalErrors * 0.1); // Rough estimate } getAverageResponseTime() { if (this.responseTimes.length === 0) return 0; const sum = this.responseTimes.reduce((a, b) => a + b, 0); return Math.round(sum / this.responseTimes.length); } measureEventLoopDelay() { // Simple event loop delay measurement const start = process.hrtime.bigint(); setImmediate(() => { const delta = process.hrtime.bigint() - start; return Number(delta / BigInt(1000000)); // Convert to milliseconds }); return 0; // Placeholder - would need async implementation } } // Global health checker instance exports.globalHealthChecker = new HealthChecker(); // Health check endpoints for production monitoring exports.healthEndpoints = { '/health': () => exports.globalHealthChecker.checkHealth(), '/health/ready': () => ({ ready: exports.globalHealthChecker.isReady() }), '/health/live': () => ({ alive: exports.globalHealthChecker.isAlive() }), '/metrics': () => exports.globalHealthChecker.getMetrics(), }; //# sourceMappingURL=health-checker.js.map