@qrvey/health-checker

An health check library for validating the availability of core service dependencies like Redis, PostgreSQL, RabbitMQ, and Elasticsearch.
Installation
npm install @qrvey/health-checker
Or with yarn:
yarn add @qrvey/health-checker
Supported Health Check Types
| PostgreSQL | database |
| Redis | cache |
| RabbitMQ | eventBroker |
| Elasticsearch | warehouse |
Usage
const {
HealthCheckService,
} = require('@qrvey/health-checker');
HealthCheckService.check(['cache', 'database', 'eventBroker', 'warehouse']).then((result) => {
console.log(result);
});
You can also check specific dependencies only:
HealthCheckService.check(['cache']).then((result) => {
console.log(result);
});
Usage with Fastify
You can expose the health check as a simple route in your Fastify app.
Basic Example: health.routes.js
const {
HealthCheckService,
} = require('@qrvey/health-checker');
const Fastify = require('fastify');
async function healthRoutes(fastify, _options) {
fastify.get('/health', async (_request, reply) => {
const dependencies = ['database', 'eventBroker', 'warehouse'];
const result = await HealthCheckService.check(dependencies);
const httpStatus = result.status === "FAILED" ? 503 : 200;
return reply.code(httpStatus).send(result);
});
}
const app = Fastify({ logger: true });
app.register(healthRoutes);
app.listen({ port: 3000 });
Basic Example Output
GET /health
{
"status": "OK",
"details": {
"database": "OK",
"eventBroker": "OK",
"warehouse": "OK"
}
}
Validating Queue Subscriptions (Optional)
If you want to explicitly validate that your service is subscribed to one or more RabbitMQ queues, you can pass an additional params object to the check method.
fastify.get('/health', async (_request, reply) => {
const dependencies = ['eventBroker'];
const params = {
eventBroker: {
queues: ['queue_name_1', 'queue_name_2'],
},
}
const result = await HealthCheckService.check(dependencies, params);
const httpStatus = result.status === "FAILED" ? 503 : 200;
return reply.code(httpStatus).send(result);
});
#### Warehouse Health Check Failure Conditions
The warehouse checker marks the cluster as `FAILED` if any of these conditions are met:
- **CPU Usage** ≥ configured threshold (default: 85%)
- **JVM Heap Usage** ≥ configured threshold (default: 90%)
- **Disk Usage** ≥ configured threshold (default: 85%)
- **Circuit Breakers** near limit (ratio > 80%)
- **Thread Pool Rejections** detected
- **Cluster Status** is red (customizable)
- **Unassigned Shards** > 0 (customizable)
#### Environment-Specific Configurations
```js
const params = {
warehouse: {
thresholds: {
cpuUsagePercent: 90,
jvmHeapPercent: 95,
circuitBreakerPercent: 90
},
customClusterStatusCheck: (status) => status !== 'red',
skipRules: { skipUnassignedShardsCheck: true },
}
};
Sample output
GET /health
{
"status": "OK",
"details": {
"eventBroker": "OK"
}
}
Warehouse Health Check Sample Outputs
Basic Success Response
GET /health
{
"status": "OK",
"details": {
"warehouse": "OK"
}
}
Detailed Success Response (with returnClusterStats: true)
GET /health
{
"status": "OK",
"durationMs": 460,
"metadata": {
"checkTimestamp": "2025-10-01T15:14:21.787Z",
"clusterStats": {
"clusterName": "elasticsearch",
"status": "green",
"nodes": {
"total": 2,
"successful": 2,
"failed": 0
},
"cpuUsagePercent": 57.5,
"jvmHeapUsagePercent": 47.5,
"diskUsagePercent": 21.518163805507996,
"activePrimaryShards": 776,
"activeShards": 1552,
"relocatingShards": 0,
"initializingShards": 0,
"unassignedShards": 0,
"circuitBreakersException": false,
"threadPoolRejections": false
}
}
}
Failure Response
GET /health
{
"status": "FAILED",
"details": {
"warehouse": {
"status": "FAILED",
"metadata": {
"clusterStats": {
"clusterName": "my-elasticsearch-cluster",
"status": "red",
"cpuUsagePercent": 88,
"jvmHeapUsagePercent": 95,
"diskUsagePercent": 90,
"circuitBreakersTripped": true,
"threadPoolRejections": false,
"unassignedShards": 15
},
"checkTimestamp": "2025-10-01T10:30:00.000Z"
}
}
}
}
Other Configuration
Multi-Environment Setup
const getHealthParams = (env) => {
const baseParams = {
eventBroker: {
queues: process.env.REQUIRED_QUEUES?.split(',') || []
}
};
if (env === 'development') {
return {
...baseParams,
warehouse: {
thresholds: {
cpuUsagePercent: 90,
jvmHeapPercent: 95,
circuitBreakerPercent: 90
},
skipRules: { skipUnassignedShardsCheck: true }
}
};
}
if (env === 'production') {
return {
...baseParams,
warehouse: {
thresholds: {
cpuUsagePercent: 70,
jvmHeapPercent: 85,
circuitBreakerPercent: 75
},
returnClusterStats: true
}
};
}
return baseParams;
};
fastify.get('/health', async (_request, reply) => {
const dependencies = ['database', 'eventBroker', 'warehouse'];
const params = getHealthParams(process.env.NODE_ENV);
const result = await HealthCheckService.check(dependencies, params);
const httpStatus = result.status === "FAILED" ? 503 : 200;
return reply.code(httpStatus).send(result);
});
API Reference
HealthCheckService
The main service for performing health checks.
HealthCheckService.check(dependencies, params?)
- dependencies:
string[] - Array of dependency keys to check
- params:
object - Optional parameters for specific health checkers
- Returns:
Promise<HealthCheckResult>
interface HealthCheckResult {
status: 'OK' | 'FAILED';
details: Record<string, any>;
}
Individual Health Checkers
You can also import and use individual health checkers directly:
const {
RabbitMQHealthChecker,
WarehouseHealthChecker,
DatabaseHealthChecker,
CacheHealthChecker
} = require('@qrvey/health-checker');
const warehouseResult = await WarehouseHealthChecker.check({
thresholds: { cpuUsagePercent: 70 }
});
const brokerResult = await RabbitMQHealthChecker.check({
queues: ['important-queue']
});
Environment Variables Reference
ELASTICSEARCH_HOST | warehouse | Elasticsearch/OpenSearch host | localhost |
ELASTICSEARCH_PORT | warehouse | Elasticsearch port | 9200 |
ELASTICSEARCH_PROTOCOL | warehouse | HTTP protocol | http |
ELASTICSEARCH_AUTH_USER | warehouse | Basic Auth username (self-managed ES) | - |
ELASTICSEARCH_AUTH_PASSWORD | warehouse | Basic Auth password (self-managed ES) | - |
ELASTICSEARCH_TIMEOUT | warehouse | Request timeout (ms) | 5000 |
RABBITMQ_HTTP_HOST | eventBroker | RabbitMQ management API host | - |
RABBITMQ_USER | eventBroker | RabbitMQ username | - |
RABBITMQ_PASSWORD | eventBroker | RabbitMQ password | - |
HOSTNAME | eventBroker | Consumer tag hostname | - |
Development
Running Tests
Unit Tests
yarn workspace @qrvey/health-checker test
Integration Tests
Prerequisites:
- Access to a running Elasticsearch/OpenSearch instance (local or remote)
- Running Redis, RabbitMQ, and PostgreSQL services
Setup:
- Configure
integration.test.env with your Elasticsearch credentials:
ELASTICSEARCH_HOST=https://your-elasticsearch-domain.com
ELASTICSEARCH_PORT=443
ELASTICSEARCH_AUTH_USER=your_username
ELASTICSEARCH_AUTH_PASSWORD=your_password
- Start local services (Redis, RabbitMQ, PostgreSQL):
docker-compose -f integration.test.docker-compose.yml --env-file integration.test.env up -d
- Run integration tests (automatically loads
integration.test.env):
yarn workspace @qrvey/health-checker test:integration
docker-compose -f integration.test.docker-compose.yml down -v
Services in Integration Tests
| Elasticsearch | Configure in .env | Your credentials |
| RabbitMQ | localhost:5672, 15672 | guest:guest |
| Redis | localhost:6379 | - |
| PostgreSQL | localhost:5432 | test_user:test_pass |
License
MIT