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
JavaScript
;
/**
* 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