141 lines
4.5 KiB
JavaScript
141 lines
4.5 KiB
JavaScript
const axios = require('axios');
|
|
|
|
// Service health monitoring
|
|
class ServiceHealthMonitor {
|
|
constructor() {
|
|
this.serviceStatus = {};
|
|
this.healthCheckInterval = null;
|
|
this.healthCheckFrequency = parseInt(process.env.HEALTH_CHECK_FREQUENCY) || 30000; // 30 seconds
|
|
}
|
|
|
|
// Initialize health monitoring for all services
|
|
async initializeHealthMonitoring() {
|
|
const serviceTargets = {
|
|
USER_AUTH_URL: process.env.USER_AUTH_URL || 'http://localhost:8011',
|
|
TEMPLATE_MANAGER_URL: process.env.TEMPLATE_MANAGER_URL || 'http://localhost:8009',
|
|
REQUIREMENT_PROCESSOR_URL: process.env.REQUIREMENT_PROCESSOR_URL || 'http://localhost:8001',
|
|
TECH_STACK_SELECTOR_URL: process.env.TECH_STACK_SELECTOR_URL || 'http://localhost:8002',
|
|
ARCHITECTURE_DESIGNER_URL: process.env.ARCHITECTURE_DESIGNER_URL || 'http://localhost:8003',
|
|
CODE_GENERATOR_URL: process.env.CODE_GENERATOR_URL || 'http://localhost:8004',
|
|
TEST_GENERATOR_URL: process.env.TEST_GENERATOR_URL || 'http://localhost:8005',
|
|
DEPLOYMENT_MANAGER_URL: process.env.DEPLOYMENT_MANAGER_URL || 'http://localhost:8006',
|
|
DASHBOARD_URL: process.env.DASHBOARD_URL || 'http://localhost:8008',
|
|
SELF_IMPROVING_GENERATOR_URL: process.env.SELF_IMPROVING_GENERATOR_URL || 'http://localhost:8007',
|
|
};
|
|
|
|
// Initial health check
|
|
await this.checkAllServices(serviceTargets);
|
|
|
|
// Start periodic health checks
|
|
this.startPeriodicHealthChecks(serviceTargets);
|
|
|
|
console.log('✅ Service health monitoring initialized');
|
|
}
|
|
|
|
// Check health of all services
|
|
async checkAllServices(serviceTargets) {
|
|
const healthPromises = Object.entries(serviceTargets).map(async ([serviceName, serviceUrl]) => {
|
|
try {
|
|
const startTime = Date.now();
|
|
const response = await axios.get(`${serviceUrl}/health`, {
|
|
timeout: 5000,
|
|
headers: { 'User-Agent': 'API-Gateway-Health-Check' }
|
|
});
|
|
|
|
const responseTime = Date.now() - startTime;
|
|
|
|
this.serviceStatus[serviceName] = {
|
|
status: response.status === 200 ? 'healthy' : 'unhealthy',
|
|
url: serviceUrl,
|
|
responseTime: responseTime,
|
|
lastChecked: new Date().toISOString(),
|
|
error: null
|
|
};
|
|
} catch (error) {
|
|
this.serviceStatus[serviceName] = {
|
|
status: 'unhealthy',
|
|
url: serviceUrl,
|
|
responseTime: null,
|
|
lastChecked: new Date().toISOString(),
|
|
error: error.message
|
|
};
|
|
}
|
|
});
|
|
|
|
await Promise.allSettled(healthPromises);
|
|
}
|
|
|
|
// Start periodic health checks
|
|
startPeriodicHealthChecks(serviceTargets) {
|
|
if (this.healthCheckInterval) {
|
|
clearInterval(this.healthCheckInterval);
|
|
}
|
|
|
|
this.healthCheckInterval = setInterval(async () => {
|
|
await this.checkAllServices(serviceTargets);
|
|
}, this.healthCheckFrequency);
|
|
}
|
|
|
|
// Stop health monitoring
|
|
stopHealthMonitoring() {
|
|
if (this.healthCheckInterval) {
|
|
clearInterval(this.healthCheckInterval);
|
|
this.healthCheckInterval = null;
|
|
}
|
|
}
|
|
|
|
// Get current service status
|
|
getServiceStatus() {
|
|
const totalServices = Object.keys(this.serviceStatus).length;
|
|
const healthyServices = Object.values(this.serviceStatus).filter(s => s.status === 'healthy').length;
|
|
|
|
return {
|
|
summary: {
|
|
total_services: totalServices,
|
|
healthy_services: healthyServices,
|
|
unhealthy_services: totalServices - healthyServices,
|
|
overall_health: healthyServices === totalServices ? 'healthy' : 'degraded'
|
|
},
|
|
services: this.serviceStatus,
|
|
last_updated: new Date().toISOString()
|
|
};
|
|
}
|
|
}
|
|
|
|
// Create singleton instance
|
|
const healthMonitor = new ServiceHealthMonitor();
|
|
|
|
// Middleware to get service status
|
|
const getServiceStatus = (req, res) => {
|
|
const status = healthMonitor.getServiceStatus();
|
|
res.json({
|
|
success: true,
|
|
...status
|
|
});
|
|
};
|
|
|
|
// Middleware to check if a specific service is healthy
|
|
const checkServiceHealth = (serviceName) => {
|
|
return (req, res, next) => {
|
|
const serviceStatus = healthMonitor.serviceStatus[serviceName];
|
|
|
|
if (!serviceStatus || serviceStatus.status !== 'healthy') {
|
|
return res.status(503).json({
|
|
success: false,
|
|
message: `Service ${serviceName} is currently unavailable`,
|
|
service_status: serviceStatus || { status: 'unknown' },
|
|
retry_after: 30
|
|
});
|
|
}
|
|
|
|
next();
|
|
};
|
|
};
|
|
|
|
module.exports = {
|
|
healthMonitor,
|
|
initializeHealthMonitoring: () => healthMonitor.initializeHealthMonitoring(),
|
|
getServiceStatus,
|
|
checkServiceHealth
|
|
};
|