MasterController
Health Checks
Liveness, readiness, and a full report — shaped like ASP.NET Core’s health checks.
master.useHealthChecks() mounts three endpoints (AddHealthChecks() + MapHealthChecks with predicates): /health/live says the process is up, /health/ready runs the checks tagged ready, and /health runs all of them. Readiness turns Unhealthy as soon as graceful shutdown begins, so load balancers drain.
Setup#
server.js
master.useHealthChecks({
path: '/health', livePath: '/health/live', readyPath: '/health/ready',
checks: {
db: { check: () => ctx.db.canConnect(), tags: ['ready'] },
redis: { check: pingRedis, tags: ['ready'], critical: false, timeoutMs: 2000 },
},
authorize: (ctx) => ctx.request.socket.remoteAddress === '127.0.0.1',
});
// add or remove checks later (e.g. from a component or hosted service)
master.healthChecks.add('queue', () => ({ status: 'Healthy', data: { depth: 3 } }), { tags: ['ready'] });
master.healthChecks.remove('queue');path(/health),livePath(/health/live),readyPath(/health/ready) — passfalseto disable one.checks—{ name: fn | { check, tags, timeoutMs, critical, description } }.criticaldefaults totrue;timeoutMsto 5000 (timeoutMsat the top level changes the default).authorize(ctx)— optional gate; a falsy result answers 403 ProblemDetails. Useful to keep the full report on the internal network.
Writing a check#
javascript
// a check returns any of these (sync or async):
() => true // Healthy
() => false // Unhealthy (or Degraded when critical: false)
() => ({ healthy: false, description: 'replica lag 9s' }) // same, with text
() => ({ status: 'Degraded', data: { lagSec: 9 } }) // explicit status + data
async () => { await db.raw('select 1'); } // throwing -> Unhealthy/Degraded with errorEndpoints#
| Endpoint | Runs | Status |
|---|---|---|
/health/live | no checks | 200 while the process runs; 503 once master.stop() begins |
/health/ready | checks tagged ready | 503 when any critical check fails; 200 Degraded for non-critical failures |
/health | all checks | 200 for Healthy/Degraded, 503 for Unhealthy |
GET /health
{
"status": "Degraded",
"totalDurationMs": 14,
"uptimeSec": 86412,
"checks": {
"db": { "status": "Healthy", "durationMs": 11 },
"redis": { "status": "Degraded", "durationMs": 3, "error": "ECONNREFUSED" },
"queue": { "status": "Healthy", "durationMs": 0, "data": { "depth": 3 } }
}
}A check that exceeds its timeoutMs is reported with error: "timed out after …". During shutdown an extra host entry ("shutting down") is added and readiness reports Unhealthy.
Kubernetes
Point
livenessProbe at /health/live and readinessProbe at /health/ready; pair with master.useGracefulShutdown() from Hosted Services so pods drain before the server closes. The endpoints are served by a pipeline middleware ahead of routing, so they are anonymous by default — use the authorize option if they must be restricted.