176 lines
4 KiB
Markdown
176 lines
4 KiB
Markdown
|
|
# @lilith/health-client
|
||
|
|
|
||
|
|
Health check utilities and indicators for the lilith platform services.
|
||
|
|
|
||
|
|
## Features
|
||
|
|
|
||
|
|
- **Health Indicators**: Database, Redis, and HTTP health checks
|
||
|
|
- **Metrics Collection**: CPU, memory, request rate, error rate tracking
|
||
|
|
- **Type-Safe**: Full TypeScript support with strict typing
|
||
|
|
- **NestJS Integration**: Injectable services and decorators
|
||
|
|
- **Standardized**: Consistent health check format across all services
|
||
|
|
|
||
|
|
## Installation
|
||
|
|
|
||
|
|
```bash
|
||
|
|
pnpm add @lilith/health-client
|
||
|
|
```
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
|
||
|
|
### Basic Health Check
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { Injectable } from '@nestjs/common';
|
||
|
|
import { Pool } from 'pg';
|
||
|
|
import Redis from 'ioredis';
|
||
|
|
import {
|
||
|
|
DatabaseHealthIndicator,
|
||
|
|
RedisHealthIndicator,
|
||
|
|
HealthService,
|
||
|
|
MetricsCollector,
|
||
|
|
} from '@lilith/health-client';
|
||
|
|
|
||
|
|
@Injectable()
|
||
|
|
export class AppHealthService {
|
||
|
|
constructor(
|
||
|
|
private readonly dbIndicator: DatabaseHealthIndicator,
|
||
|
|
private readonly redisIndicator: RedisHealthIndicator,
|
||
|
|
private readonly healthService: HealthService,
|
||
|
|
private readonly db: Pool,
|
||
|
|
private readonly redis: Redis,
|
||
|
|
) {}
|
||
|
|
|
||
|
|
async checkHealth() {
|
||
|
|
// Create health check promises
|
||
|
|
const checks = [
|
||
|
|
this.dbIndicator.check('database', { connection: this.db }),
|
||
|
|
this.redisIndicator.check('redis', { connection: this.redis }),
|
||
|
|
];
|
||
|
|
|
||
|
|
// Aggregate results
|
||
|
|
const health = await this.healthService.check(checks, {
|
||
|
|
serviceName: 'platform',
|
||
|
|
version: '1.0.0',
|
||
|
|
includeMetrics: true,
|
||
|
|
});
|
||
|
|
|
||
|
|
return health;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Health Controller
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { Controller, Get } from '@nestjs/common';
|
||
|
|
import { AppHealthService } from './app-health.service';
|
||
|
|
|
||
|
|
@Controller('health')
|
||
|
|
export class HealthController {
|
||
|
|
constructor(private readonly healthService: AppHealthService) {}
|
||
|
|
|
||
|
|
@Get()
|
||
|
|
async check() {
|
||
|
|
return this.healthService.checkHealth();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### Response Format
|
||
|
|
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"status": "healthy",
|
||
|
|
"service": "platform",
|
||
|
|
"version": "1.0.0",
|
||
|
|
"timestamp": "2025-12-20T10:00:00.000Z",
|
||
|
|
"uptime": 86400,
|
||
|
|
"dependencies": [
|
||
|
|
{
|
||
|
|
"name": "database",
|
||
|
|
"type": "database",
|
||
|
|
"status": "healthy",
|
||
|
|
"responseTime": 12,
|
||
|
|
"lastCheck": "2025-12-20T10:00:00.000Z"
|
||
|
|
},
|
||
|
|
{
|
||
|
|
"name": "redis",
|
||
|
|
"type": "redis",
|
||
|
|
"status": "healthy",
|
||
|
|
"responseTime": 3,
|
||
|
|
"lastCheck": "2025-12-20T10:00:00.000Z"
|
||
|
|
}
|
||
|
|
],
|
||
|
|
"metrics": {
|
||
|
|
"cpu": 23.5,
|
||
|
|
"memory": 312,
|
||
|
|
"requestsPerMinute": 1245,
|
||
|
|
"errorRate": 0.01,
|
||
|
|
"avgResponseTime": 145
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Available Indicators
|
||
|
|
|
||
|
|
### DatabaseHealthIndicator
|
||
|
|
|
||
|
|
Checks PostgreSQL database connectivity:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
await dbIndicator.check('database', {
|
||
|
|
connection: pool, // pg.Pool or connection string
|
||
|
|
timeout: 5000, // optional, default 5000ms
|
||
|
|
query: 'SELECT 1', // optional, default 'SELECT 1'
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
### RedisHealthIndicator
|
||
|
|
|
||
|
|
Checks Redis connectivity:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
await redisIndicator.check('redis', {
|
||
|
|
connection: redisClient, // ioredis instance or connection string
|
||
|
|
timeout: 3000, // optional, default 3000ms
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
### HttpHealthIndicator
|
||
|
|
|
||
|
|
Checks HTTP service availability:
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
await httpIndicator.check('external-api', {
|
||
|
|
url: 'https://api.example.com/health',
|
||
|
|
timeout: 5000, // optional, default 5000ms
|
||
|
|
expectedStatus: 200, // optional, default 200
|
||
|
|
headers: { Authorization: 'Bearer token' }, // optional
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## Metrics Collection
|
||
|
|
|
||
|
|
The `MetricsCollector` automatically tracks:
|
||
|
|
|
||
|
|
- **CPU**: Current CPU usage percentage
|
||
|
|
- **Memory**: Heap memory usage in MB
|
||
|
|
- **Requests Per Minute**: Average request rate
|
||
|
|
- **Error Rate**: Percentage of failed requests
|
||
|
|
- **Avg Response Time**: Average response time in milliseconds
|
||
|
|
|
||
|
|
Metrics are automatically included in health checks unless `includeMetrics: false` is specified.
|
||
|
|
|
||
|
|
## Health Status
|
||
|
|
|
||
|
|
Health status is determined automatically:
|
||
|
|
|
||
|
|
- **healthy**: All dependencies are healthy with good response times
|
||
|
|
- **degraded**: Some dependencies have slower response times but are functional
|
||
|
|
- **unhealthy**: One or more dependencies are down or failing
|
||
|
|
|
||
|
|
## License
|
||
|
|
|
||
|
|
MIT
|