UNPKG

@ahmedhegazee/nestjs-telescope

Version:

Advanced observability and monitoring solution for NestJS applications with ML-powered analytics, enterprise features, and production-ready scaling

305 lines 13 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 __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var HealthController_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.HealthController = void 0; const common_1 = require("@nestjs/common"); const swagger_1 = require("@nestjs/swagger"); const telescope_service_1 = require("../services/telescope.service"); const metrics_service_1 = require("../services/metrics.service"); const resilient_bridge_service_1 = require("../../devtools/bridge/resilient-bridge.service"); let HealthController = HealthController_1 = class HealthController { constructor(telescopeService, metricsService, resilientBridge, config) { this.telescopeService = telescopeService; this.metricsService = metricsService; this.resilientBridge = resilientBridge; this.config = config; this.logger = new common_1.Logger(HealthController_1.name); this.startTime = Date.now(); } async getHealth() { const timestamp = new Date(); const uptime = Date.now() - this.startTime; try { const telescopeHealth = await this.checkTelescopeHealth(); const metricsHealth = await this.checkMetricsHealth(); const bridgeHealth = await this.checkBridgeHealth(); const storageHealth = await this.checkStorageHealth(); const metrics = this.metricsService.getMetrics(); const bridgeMetrics = this.resilientBridge.getStreamMetrics(); const circuitBreakers = this.resilientBridge.getCircuitBreakerStatus(); const services = { telescope: telescopeHealth, metrics: metricsHealth, bridge: bridgeHealth, storage: storageHealth }; const overallStatus = this.determineOverallStatus(services); return { status: overallStatus, timestamp, uptime, version: process.env.npm_package_version || '1.0.0', services, metrics: { totalEntries: metrics.totalEntries, errorRate: metrics.errorRate, averageProcessingTime: metrics.averageProcessingTime, throughput: metrics.throughput }, circuitBreakers }; } catch (error) { this.logger.error('Health check failed:', error); return { status: 'unhealthy', timestamp, uptime, version: process.env.npm_package_version || '1.0.0', services: { telescope: { status: 'unhealthy', message: 'Health check failed', lastChecked: timestamp }, metrics: { status: 'unhealthy', message: 'Health check failed', lastChecked: timestamp }, bridge: { status: 'unhealthy', message: 'Health check failed', lastChecked: timestamp }, storage: { status: 'unhealthy', message: 'Health check failed', lastChecked: timestamp } }, metrics: { totalEntries: 0, errorRate: 100, averageProcessingTime: 0, throughput: 0 } }; } } async getDetailedHealth() { const basicHealth = await this.getHealth(); const comprehensiveStatus = this.resilientBridge.getComprehensiveStatus(); const performanceReport = this.metricsService.getPerformanceReport(); return { ...basicHealth, diagnostics: { bridge: comprehensiveStatus.bridge, circuitBreakers: comprehensiveStatus.circuitBreakers, streamMetrics: comprehensiveStatus.streamMetrics, configuration: comprehensiveStatus.configuration, performanceReport } }; } async getMetrics() { const metrics = this.metricsService.getMetrics(); const streamMetrics = this.resilientBridge.getStreamMetrics(); const performanceReport = this.metricsService.getPerformanceReport(); return { timestamp: new Date(), uptime: Date.now() - this.startTime, metrics, streamMetrics, performanceReport }; } async getCircuitBreakers() { const circuitBreakers = this.resilientBridge.getCircuitBreakerStatus(); const bridgeHealth = this.resilientBridge.getHealthStatus(); return { timestamp: new Date(), circuitBreakers, bridgeHealth }; } async checkTelescopeHealth() { try { const isEnabled = this.config.enabled; const watchers = this.config.watchers || {}; const activeWatchers = Object.keys(watchers).filter(key => { const watcher = watchers[key]; return typeof watcher === 'boolean' ? watcher : watcher?.enabled === true; }); if (!isEnabled) { return { status: 'degraded', message: 'Telescope is disabled', lastChecked: new Date() }; } return { status: 'healthy', message: `${activeWatchers.length} watchers active`, details: { activeWatchers }, lastChecked: new Date() }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { status: 'unhealthy', message: `Telescope check failed: ${errorMessage}`, lastChecked: new Date() }; } } async checkMetricsHealth() { try { const metrics = this.metricsService.getMetrics(); const performanceReport = this.metricsService.getPerformanceReport(); if (!performanceReport.status.isHealthy) { return { status: 'degraded', message: 'Performance issues detected', details: { alerts: performanceReport.status.alerts }, lastChecked: new Date() }; } return { status: 'healthy', message: `${metrics.totalEntries} entries processed`, details: { errorRate: metrics.errorRate.toFixed(2), throughput: metrics.throughput.toFixed(2) }, lastChecked: new Date() }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { status: 'unhealthy', message: `Metrics check failed: ${errorMessage}`, lastChecked: new Date() }; } } async checkBridgeHealth() { try { const bridgeHealth = this.resilientBridge.getHealthStatus(); if (!bridgeHealth.isHealthy) { return { status: 'degraded', message: 'Bridge issues detected', details: { issues: bridgeHealth.issues }, lastChecked: new Date() }; } return { status: 'healthy', message: 'Bridge operating normally', details: { circuitBreakers: Object.keys(bridgeHealth.circuitBreakers).length, lastHealthCheck: bridgeHealth.lastHealthCheckAt }, lastChecked: new Date() }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { status: 'unhealthy', message: `Bridge check failed: ${errorMessage}`, lastChecked: new Date() }; } } async checkStorageHealth() { try { const storageConfig = this.config.storage; if (!storageConfig) { return { status: 'unhealthy', message: 'Storage not configured', lastChecked: new Date() }; } const circuitBreakers = this.resilientBridge.getCircuitBreakerStatus(); const storageBreaker = circuitBreakers.storage; if (storageBreaker && storageBreaker.state === 'open') { return { status: 'unhealthy', message: 'Storage circuit breaker open', details: { circuitBreaker: storageBreaker }, lastChecked: new Date() }; } return { status: 'healthy', message: `Storage driver: ${storageConfig.driver}`, details: { driver: storageConfig.driver, batchEnabled: storageConfig.batch?.enabled || false }, lastChecked: new Date() }; } catch (error) { const errorMessage = error instanceof Error ? error.message : 'Unknown error'; return { status: 'unhealthy', message: `Storage check failed: ${errorMessage}`, lastChecked: new Date() }; } } determineOverallStatus(services) { const statuses = Object.values(services).map(service => service.status); if (statuses.includes('unhealthy')) { return 'unhealthy'; } if (statuses.includes('degraded')) { return 'degraded'; } return 'healthy'; } }; exports.HealthController = HealthController; __decorate([ (0, common_1.Get)(), (0, swagger_1.ApiOperation)({ summary: 'Get overall health status' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Health check successful' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], HealthController.prototype, "getHealth", null); __decorate([ (0, common_1.Get)('detailed'), (0, swagger_1.ApiOperation)({ summary: 'Get detailed health status with full diagnostics' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Detailed health check successful' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], HealthController.prototype, "getDetailedHealth", null); __decorate([ (0, common_1.Get)('metrics'), (0, swagger_1.ApiOperation)({ summary: 'Get performance metrics' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Metrics retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], HealthController.prototype, "getMetrics", null); __decorate([ (0, common_1.Get)('circuit-breakers'), (0, swagger_1.ApiOperation)({ summary: 'Get circuit breaker status' }), (0, swagger_1.ApiResponse)({ status: 200, description: 'Circuit breaker status retrieved successfully' }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], HealthController.prototype, "getCircuitBreakers", null); exports.HealthController = HealthController = HealthController_1 = __decorate([ (0, swagger_1.ApiTags)('Health'), (0, common_1.Controller)('telescope/health'), __param(3, (0, common_1.Inject)('TELESCOPE_CONFIG')), __metadata("design:paramtypes", [telescope_service_1.TelescopeService, metrics_service_1.MetricsService, resilient_bridge_service_1.ResilientBridgeService, Object]) ], HealthController); //# sourceMappingURL=health.controller.js.map