172 lines
4.7 KiB
TypeScript
172 lines
4.7 KiB
TypeScript
import { Hono } from 'hono';
|
|
|
|
export class HealthController {
|
|
private app: Hono;
|
|
|
|
constructor() {
|
|
this.app = new Hono();
|
|
this.setupRoutes();
|
|
}
|
|
|
|
private setupRoutes() {
|
|
// Basic health check
|
|
this.app.get('/', async (c) => {
|
|
return c.json({
|
|
service: 'data-catalog',
|
|
status: 'healthy',
|
|
timestamp: new Date().toISOString(),
|
|
version: process.env.SERVICE_VERSION || '1.0.0'
|
|
});
|
|
});
|
|
|
|
// Detailed health check
|
|
this.app.get('/detailed', async (c) => {
|
|
try {
|
|
const healthStatus = {
|
|
service: 'data-catalog',
|
|
status: 'healthy',
|
|
timestamp: new Date().toISOString(),
|
|
version: process.env.SERVICE_VERSION || '1.0.0',
|
|
uptime: process.uptime(),
|
|
memory: process.memoryUsage(),
|
|
dependencies: {
|
|
database: await this.checkDatabase(),
|
|
search: await this.checkSearchService(),
|
|
eventBus: await this.checkEventBus()
|
|
}
|
|
};
|
|
|
|
// Determine overall status based on dependencies
|
|
const hasUnhealthyDependencies = Object.values(healthStatus.dependencies)
|
|
.some(dep => dep.status !== 'healthy');
|
|
|
|
if (hasUnhealthyDependencies) {
|
|
healthStatus.status = 'degraded';
|
|
}
|
|
|
|
const statusCode = healthStatus.status === 'healthy' ? 200 : 503;
|
|
return c.json(healthStatus, statusCode);
|
|
} catch (error) {
|
|
console.error('Health check error:', error);
|
|
return c.json({
|
|
service: 'data-catalog',
|
|
status: 'unhealthy',
|
|
timestamp: new Date().toISOString(),
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
}, 503);
|
|
}
|
|
});
|
|
|
|
// Readiness check
|
|
this.app.get('/ready', async (c) => {
|
|
try {
|
|
// Check if service is ready to accept requests
|
|
const readyChecks = await Promise.all([
|
|
this.checkDatabase(),
|
|
this.checkSearchService()
|
|
]);
|
|
|
|
const isReady = readyChecks.every(check => check.status === 'healthy');
|
|
|
|
if (isReady) {
|
|
return c.json({
|
|
service: 'data-catalog',
|
|
ready: true,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
} else {
|
|
return c.json({
|
|
service: 'data-catalog',
|
|
ready: false,
|
|
timestamp: new Date().toISOString(),
|
|
checks: readyChecks
|
|
}, 503);
|
|
}
|
|
} catch (error) {
|
|
console.error('Readiness check error:', error);
|
|
return c.json({
|
|
service: 'data-catalog',
|
|
ready: false,
|
|
timestamp: new Date().toISOString(),
|
|
error: error instanceof Error ? error.message : 'Unknown error'
|
|
}, 503);
|
|
}
|
|
});
|
|
|
|
// Liveness check
|
|
this.app.get('/live', async (c) => {
|
|
return c.json({
|
|
service: 'data-catalog',
|
|
alive: true,
|
|
timestamp: new Date().toISOString()
|
|
});
|
|
});
|
|
}
|
|
|
|
private async checkDatabase(): Promise<{ name: string; status: string; responseTime?: number }> {
|
|
const start = Date.now();
|
|
try {
|
|
// Simulate database check
|
|
// In real implementation, this would ping the actual database
|
|
await new Promise(resolve => setTimeout(resolve, 10));
|
|
|
|
return {
|
|
name: 'database',
|
|
status: 'healthy',
|
|
responseTime: Date.now() - start
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
name: 'database',
|
|
status: 'unhealthy',
|
|
responseTime: Date.now() - start
|
|
};
|
|
}
|
|
}
|
|
|
|
private async checkSearchService(): Promise<{ name: string; status: string; responseTime?: number }> {
|
|
const start = Date.now();
|
|
try {
|
|
// Simulate search service check
|
|
// In real implementation, this would check search index health
|
|
await new Promise(resolve => setTimeout(resolve, 5));
|
|
|
|
return {
|
|
name: 'search',
|
|
status: 'healthy',
|
|
responseTime: Date.now() - start
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
name: 'search',
|
|
status: 'unhealthy',
|
|
responseTime: Date.now() - start
|
|
};
|
|
}
|
|
}
|
|
|
|
private async checkEventBus(): Promise<{ name: string; status: string; responseTime?: number }> {
|
|
const start = Date.now();
|
|
try {
|
|
// Simulate event bus check
|
|
// In real implementation, this would check message broker connectivity
|
|
await new Promise(resolve => setTimeout(resolve, 3));
|
|
|
|
return {
|
|
name: 'eventBus',
|
|
status: 'healthy',
|
|
responseTime: Date.now() - start
|
|
};
|
|
} catch (error) {
|
|
return {
|
|
name: 'eventBus',
|
|
status: 'unhealthy',
|
|
responseTime: Date.now() - start
|
|
};
|
|
}
|
|
}
|
|
|
|
public getApp(): Hono {
|
|
return this.app;
|
|
}
|
|
}
|