@sebspark/health-check
v2.2.3
Published
An easy way to add health check routes to your API.
Keywords
Readme
@sebspark/health-check
An easy way to add health check routes to your API.
Features
- Exposes standard health endpoints under
/health/health/ping– always returns{ status: "ok" }/health/live– liveness probe with system and process info/health/ready– readiness probe with dependency checks/health– combined view
- Supports critical and non-critical dependencies
- Throttled dependency checks to avoid overload
Usage
import express from 'express'
import { HealthMonitor, DependencyMonitor } from '@sebspark/health-check'
const app = express()
const monitor = new HealthMonitor()
// Critical inline dependency: Database
monitor.addDependency('db', new DependencyMonitor({
impact: 'critical',
healthyLimitMs: 50, // ≤ 50ms and 'ok' ⇒ ok
timeoutLimitMs: 500, // > 500ms ⇒ error (aborted)
syncCall: async () => {
try {
const latencyMs = await db.ping() // throws on failure
// When syncCall returns 'ok' but took > healthyLimitMs, monitor marks it 'degraded'
return 'ok'
} catch (err) {
return err as Error // treated as 'error'
}
},
}))
// Non-critical polled dependency: External API
monitor.addDependency('externalApi', new DependencyMonitor({
impact: 'non_critical',
pollRate: 10_000, // run every 10s and cache the result
healthyLimitMs: 250, // ≤ 250ms and 'ok' ⇒ ok
timeoutLimitMs: 1000, // > 1000ms ⇒ error (request times out)
syncCall: async () => {
try {
const res = await fetch('https://status.example.com/health', { method: 'GET' })
// 'ok' within healthyLimitMs ⇒ ok; 'ok' but slower ⇒ degraded; non-2xx ⇒ degraded
return res.ok ? 'ok' : 'degraded'
} catch (err) {
return err as Error
}
},
}))
// Critical async dependency: Pub/Sub round-trip (ping/pong)
monitor.addDependency('pubsub', new DependencyMonitor({
impact: 'critical',
pollRate: 15_000, // start a new async round-trip every 15s
healthyLimitMs: 100, // pong within 100ms ⇒ ok; slower ⇒ degraded
timeoutLimitMs: 1000, // no pong by 1s ⇒ error
asyncCall: async (report) => {
const topic = pubsub.topic('health-topic')
const sub = topic.subscription('health-sub')
// listen for a single pong
const onMessage = (msg: any) => {
try {
const data = JSON.parse(msg.data.toString())
if (data.type === 'pong') {
report('ok') // monitor classifies ok/degraded based on elapsed time
} else {
report('degraded')
}
} catch (e) {
report(e as Error)
} finally {
sub.removeListener('message', onMessage)
}
}
sub.on('message', onMessage)
// publish ping
await topic.publishMessage({ data: Buffer.from(JSON.stringify({ type: 'ping' })) })
},
}))
app.use(monitor.router)
app.listen(3000, () => {
console.log('Server running on http://localhost:3000')
})OpenAPI specification
JSON
{
"tags": [
{
"name": "health",
"description": "Health endpoints."
}
],
"paths": {
"/health": {
"get": {
"tags": [
"health"
],
"summary": "Comprehensive health summary",
"description": "Combined view of status, system/process metrics, and readiness summary. Includes links to all child endpoints.",
"security": [],
"responses": {
"200": {
"description": "Health summary envelope.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HealthCheck_HealthSummary_Entity"
}
}
}
}
}
}
},
"/health/ping": {
"get": {
"tags": [
"health"
],
"summary": "Status ping",
"description": "Basic health status. Links back to parent /health.",
"security": [],
"responses": {
"200": {
"description": "Status entity.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HealthCheck_Status_Entity"
}
}
}
}
}
}
},
"/health/live": {
"get": {
"tags": [
"health"
],
"summary": "Liveness",
"description": "Liveness signal with system and process metrics. Links back to parent /health.",
"security": [],
"responses": {
"200": {
"description": "Liveness entity.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HealthCheck_Liveness_Entity"
}
}
}
}
}
}
},
"/health/ready": {
"get": {
"tags": [
"health"
],
"summary": "Readiness",
"description": "Readiness including dependency checks and summary. Links back to parent /health.",
"security": [],
"responses": {
"200": {
"description": "Readiness entity.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HealthCheck_Readiness_Entity"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Verb": {
"type": "string",
"enum": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE"
],
"description": "HTTP method for the link."
},
"Link": {
"type": "object",
"description": "A hypermedia link.",
"properties": {
"href": {
"type": "string",
"format": "uri-reference",
"description": "Target URL."
},
"method": {
"$ref": "#/components/schemas/Verb"
}
},
"required": [
"href",
"method"
]
},
"HealthCheck_StatusValue": {
"type": "string",
"enum": [
"ok",
"degraded",
"error"
],
"description": "Health status value."
},
"HealthCheck_Impact": {
"type": "string",
"enum": [
"critical",
"non_critical"
],
"description": "Operational impact if the dependency fails."
},
"HealthCheck_Mode": {
"type": "string",
"enum": [
"inline",
"polled",
"async"
],
"description": "How the dependency is checked."
},
"HealthCheck_Status": {
"type": "object",
"properties": {
"status": {
"$ref": "#/components/schemas/HealthCheck_StatusValue"
}
},
"required": [
"status"
]
},
"HealthCheck_System": {
"type": "object",
"properties": {
"hostname": {
"type": "string"
},
"platform": {
"type": "string",
"description": "NodeJS.Platform",
"enum": [
"aix",
"android",
"darwin",
"freebsd",
"linux",
"openbsd",
"sunos",
"win32"
]
},
"release": {
"type": "string"
},
"arch": {
"type": "string",
"description": "e.g., x64, arm64"
},
"uptime": {
"type": "number",
"description": "Seconds."
},
"loadavg": {
"type": "array",
"items": {
"type": "number"
},
"minItems": 3,
"maxItems": 3,
"description": "Load averages for 1, 5, 15 minutes."
},
"totalmem": {
"type": "number"
},
"freemem": {
"type": "number"
},
"memUsedRatio": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"cpus": {
"type": "object",
"properties": {
"count": {
"type": "integer",
"minimum": 1
},
"model": {
"type": "string"
},
"speedMHz": {
"type": "number"
}
},
"required": [
"count"
]
}
},
"required": [
"hostname",
"platform",
"release",
"arch",
"uptime",
"loadavg",
"totalmem",
"freemem",
"memUsedRatio",
"cpus"
]
},
"HealthCheck_MemoryUsage": {
"type": "object",
"description": "Process memory usage (NodeJS.MemoryUsage).",
"properties": {
"rss": {
"type": "number"
},
"heapTotal": {
"type": "number"
},
"heapUsed": {
"type": "number"
},
"external": {
"type": "number"
},
"arrayBuffers": {
"type": "number"
}
},
"additionalProperties": {
"type": "number"
}
},
"HealthCheck_Process": {
"type": "object",
"properties": {
"pid": {
"type": "integer"
},
"node": {
"type": "string",
"description": "Node.js version string."
},
"uptime": {
"type": "number",
"description": "Seconds."
},
"memory": {
"$ref": "#/components/schemas/HealthCheck_MemoryUsage"
}
},
"required": [
"pid",
"node",
"uptime",
"memory"
]
},
"HealthCheck_Liveness": {
"allOf": [
{
"$ref": "#/components/schemas/HealthCheck_Status"
},
{
"type": "object",
"properties": {
"timestamp": {
"type": "string",
"format": "date-time"
},
"system": {
"$ref": "#/components/schemas/HealthCheck_System"
},
"process": {
"$ref": "#/components/schemas/HealthCheck_Process"
}
},
"required": [
"timestamp",
"system",
"process"
]
}
]
},
"HealthCheck_Freshness": {
"type": "object",
"properties": {
"lastChecked": {
"type": "string",
"format": "date-time"
},
"lastSuccess": {
"type": [
"string",
"null"
],
"format": "date-time"
}
},
"required": [
"lastChecked",
"lastSuccess"
]
},
"HealthCheck_Observed": {
"type": "object",
"properties": {
"latencyMs": {
"type": [
"number",
"null"
]
}
},
"additionalProperties": true
},
"HealthCheck_CheckError": {
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
]
},
"HealthCheck_DependencyCheck": {
"allOf": [
{
"$ref": "#/components/schemas/HealthCheck_Status"
},
{
"type": "object",
"properties": {
"impact": {
"$ref": "#/components/schemas/HealthCheck_Impact"
},
"mode": {
"$ref": "#/components/schemas/HealthCheck_Mode"
},
"freshness": {
"$ref": "#/components/schemas/HealthCheck_Freshness"
},
"observed": {
"$ref": "#/components/schemas/HealthCheck_Observed"
},
"details": {
"type": "object",
"additionalProperties": true
},
"error": {
"oneOf": [
{
"$ref": "#/components/schemas/HealthCheck_CheckError"
},
{
"type": "null"
}
]
},
"since": {
"type": [
"string",
"null"
],
"format": "date-time"
}
},
"required": [
"impact",
"mode",
"freshness"
]
}
]
},
"HealthCheck_ReadinessSummary": {
"type": "object",
"properties": {
"critical": {
"type": "object",
"properties": {
"ok": {
"type": "integer",
"minimum": 0
},
"failing": {
"type": "integer",
"minimum": 0
}
},
"required": [
"ok",
"failing"
]
},
"nonCritical": {
"type": "object",
"properties": {
"ok": {
"type": "integer",
"minimum": 0
},
"degraded": {
"type": "integer",
"minimum": 0
},
"failing": {
"type": "integer",
"minimum": 0
}
},
"required": [
"ok",
"degraded",
"failing"
]
}
},
"required": [
"critical",
"nonCritical"
]
},
"HealthCheck_ReadinessPayload": {
"allOf": [
{
"$ref": "#/components/schemas/HealthCheck_Status"
},
{
"type": "object",
"properties": {
"summary": {
"$ref": "#/components/schemas/HealthCheck_ReadinessSummary"
},
"dependencies": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/HealthCheck_DependencyCheck"
}
}
},
"required": [
"summary"
]
}
]
},
"HealthCheck_HealthSummary": {
"allOf": [
{
"$ref": "#/components/schemas/HealthCheck_Liveness"
},
{
"type": "object",
"properties": {
"summary": {
"$ref": "#/components/schemas/HealthCheck_ReadinessSummary"
}
},
"required": [
"summary"
]
}
]
},
"HealthCheck_Status_Entity": {
"type": "object",
"description": "Envelope for the status (ping) resource.",
"properties": {
"data": {
"$ref": "#/components/schemas/HealthCheck_Status"
},
"links": {
"type": "object",
"properties": {
"self": {
"$ref": "#/components/schemas/Link"
},
"parent": {
"$ref": "#/components/schemas/Link"
}
},
"required": [
"self",
"parent"
]
}
},
"required": [
"data",
"links"
],
"example": {
"data": {
"status": "ok"
},
"links": {
"self": {
"href": "/health/ping",
"method": "GET"
},
"parent": {
"href": "/health",
"method": "GET"
}
}
}
},
"HealthCheck_Liveness_Entity": {
"type": "object",
"description": "Envelope for the liveness resource.",
"properties": {
"data": {
"$ref": "#/components/schemas/HealthCheck_Liveness"
},
"links": {
"type": "object",
"properties": {
"self": {
"$ref": "#/components/schemas/Link"
},
"parent": {
"$ref": "#/components/schemas/Link"
}
},
"required": [
"self",
"parent"
]
}
},
"required": [
"data",
"links"
],
"example": {
"data": {
"status": "ok",
"timestamp": "2026-02-24T12:00:00Z"
},
"links": {
"self": {
"href": "/health/live",
"method": "GET"
},
"parent": {
"href": "/health",
"method": "GET"
}
}
}
},
"HealthCheck_Readiness_Entity": {
"type": "object",
"description": "Envelope for the readiness resource.",
"properties": {
"data": {
"$ref": "#/components/schemas/HealthCheck_ReadinessPayload"
},
"links": {
"type": "object",
"properties": {
"self": {
"$ref": "#/components/schemas/Link"
},
"parent": {
"$ref": "#/components/schemas/Link"
}
},
"required": [
"self",
"parent"
]
}
},
"required": [
"data",
"links"
],
"example": {
"links": {
"self": {
"href": "/health/ready",
"method": "GET"
},
"parent": {
"href": "/health",
"method": "GET"
}
}
}
},
"HealthCheck_HealthSummary_Entity": {
"type": "object",
"description": "Envelope for the root health summary resource. Links to all children.",
"properties": {
"data": {
"$ref": "#/components/schemas/HealthCheck_HealthSummary"
},
"links": {
"type": "object",
"properties": {
"self": {
"$ref": "#/components/schemas/Link"
},
"status": {
"$ref": "#/components/schemas/Link"
},
"liveness": {
"$ref": "#/components/schemas/Link"
},
"readiness": {
"$ref": "#/components/schemas/Link"
}
},
"required": [
"self",
"status",
"liveness",
"readiness"
]
}
},
"required": [
"data",
"links"
],
"example": {
"links": {
"self": {
"href": "/health",
"method": "GET"
},
"status": {
"href": "/health/ping",
"method": "GET"
},
"liveness": {
"href": "/health/live",
"method": "GET"
},
"readiness": {
"href": "/health/ready",
"method": "GET"
}
}
}
}
}
}
}YAML
tags:
- name: health
description: Operational endpoints.
paths:
/health:
get:
tags: [health]
summary: Comprehensive health summary
description: Combined view of status, system/process metrics, and readiness summary. Includes links to all child endpoints.
security: []
responses:
"200":
description: Health summary envelope.
content:
application/json:
schema:
$ref: '#/components/schemas/HealthCheck_HealthSummary_Entity'
/health/ping:
get:
tags: [health]
summary: Status ping
description: Basic health status. Links back to parent /health.
security: []
responses:
"200":
description: Status entity.
content:
application/json:
schema:
$ref: '#/components/schemas/HealthCheck_Status_Entity'
/health/live:
get:
tags: [health]
summary: Liveness
description: Liveness signal with system and process metrics. Links back to parent /health.
security: []
responses:
"200":
description: Liveness entity.
content:
application/json:
schema:
$ref: '#/components/schemas/HealthCheck_Liveness_Entity'
/health/ready:
get:
tags: [health]
summary: Readiness
description: Readiness including dependency checks and summary. Links back to parent /health.
security: []
responses:
"200":
description: Readiness entity.
content:
application/json:
schema:
$ref: '#/components/schemas/HealthCheck_Readiness_Entity'
components:
schemas:
# ─── Shared link primitives ───────────────────────────────────────────────
Verb:
type: string
enum: [GET, POST, PUT, PATCH, DELETE]
description: HTTP method for the link.
Link:
type: object
description: A hypermedia link.
properties:
href:
type: string
format: uri-reference
description: Target URL.
method:
$ref: '#/components/schemas/Verb'
required: [href, method]
# ─── Domain schemas ───────────────────────────────────────────────────────
HealthCheck_StatusValue:
type: string
enum: [ok, degraded, error]
description: Health status value.
HealthCheck_Impact:
type: string
enum: [critical, non_critical]
description: Operational impact if the dependency fails.
HealthCheck_Mode:
type: string
enum: [inline, polled, async]
description: How the dependency is checked.
HealthCheck_Status:
type: object
properties:
status:
$ref: '#/components/schemas/HealthCheck_StatusValue'
required: [status]
HealthCheck_System:
type: object
properties:
hostname:
type: string
platform:
type: string
description: NodeJS.Platform
enum: [aix, android, darwin, freebsd, linux, openbsd, sunos, win32]
release:
type: string
arch:
type: string
description: e.g., x64, arm64
uptime:
type: number
description: Seconds.
loadavg:
type: array
items:
type: number
minItems: 3
maxItems: 3
description: Load averages for 1, 5, 15 minutes.
totalmem:
type: number
freemem:
type: number
memUsedRatio:
type: number
minimum: 0
maximum: 1
cpus:
type: object
properties:
count:
type: integer
minimum: 1
model:
type: string
speedMHz:
type: number
required: [count]
required:
- hostname
- platform
- release
- arch
- uptime
- loadavg
- totalmem
- freemem
- memUsedRatio
- cpus
HealthCheck_MemoryUsage:
type: object
description: Process memory usage (NodeJS.MemoryUsage).
properties:
rss:
type: number
heapTotal:
type: number
heapUsed:
type: number
external:
type: number
arrayBuffers:
type: number
additionalProperties:
type: number
HealthCheck_Process:
type: object
properties:
pid:
type: integer
node:
type: string
description: Node.js version string.
uptime:
type: number
description: Seconds.
memory:
$ref: '#/components/schemas/HealthCheck_MemoryUsage'
required: [pid, node, uptime, memory]
HealthCheck_Liveness:
allOf:
- $ref: '#/components/schemas/HealthCheck_Status'
- type: object
properties:
timestamp:
type: string
format: date-time
system:
$ref: '#/components/schemas/HealthCheck_System'
process:
$ref: '#/components/schemas/HealthCheck_Process'
required: [timestamp, system, process]
HealthCheck_Freshness:
type: object
properties:
lastChecked:
type: string
format: date-time
lastSuccess:
type: [string, "null"]
format: date-time
required: [lastChecked, lastSuccess]
HealthCheck_Observed:
type: object
properties:
latencyMs:
type: [number, "null"]
additionalProperties: true
HealthCheck_CheckError:
type: object
properties:
code:
type: string
message:
type: string
required: [code, message]
HealthCheck_DependencyCheck:
allOf:
- $ref: '#/components/schemas/HealthCheck_Status'
- type: object
properties:
impact:
$ref: '#/components/schemas/HealthCheck_Impact'
mode:
$ref: '#/components/schemas/HealthCheck_Mode'
freshness:
$ref: '#/components/schemas/HealthCheck_Freshness'
observed:
$ref: '#/components/schemas/HealthCheck_Observed'
details:
type: object
additionalProperties: true
error:
oneOf:
- $ref: '#/components/schemas/HealthCheck_CheckError'
- type: "null"
since:
type: [string, "null"]
format: date-time
required: [impact, mode, freshness]
HealthCheck_ReadinessSummary:
type: object
properties:
critical:
type: object
properties:
ok:
type: integer
minimum: 0
failing:
type: integer
minimum: 0
required: [ok, failing]
nonCritical:
type: object
properties:
ok:
type: integer
minimum: 0
degraded:
type: integer
minimum: 0
failing:
type: integer
minimum: 0
required: [ok, degraded, failing]
required: [critical, nonCritical]
HealthCheck_ReadinessPayload:
allOf:
- $ref: '#/components/schemas/HealthCheck_Status'
- type: object
properties:
summary:
$ref: '#/components/schemas/HealthCheck_ReadinessSummary'
dependencies:
type: object
additionalProperties:
$ref: '#/components/schemas/HealthCheck_DependencyCheck'
required: [summary]
HealthCheck_HealthSummary:
allOf:
- $ref: '#/components/schemas/HealthCheck_Liveness'
- type: object
properties:
summary:
$ref: '#/components/schemas/HealthCheck_ReadinessSummary'
required: [summary]
# ─── Entity wrappers ──────────────────────────────────────────────────────
HealthCheck_Status_Entity:
type: object
description: Envelope for the status (ping) resource.
properties:
data:
$ref: '#/components/schemas/HealthCheck_Status'
links:
type: object
properties:
self:
$ref: '#/components/schemas/Link'
parent:
$ref: '#/components/schemas/Link'
required: [self, parent]
required: [data, links]
example:
data:
status: ok
links:
self:
href: /health/ping
method: GET
parent:
href: /health
method: GET
HealthCheck_Liveness_Entity:
type: object
description: Envelope for the liveness resource.
properties:
data:
$ref: '#/components/schemas/HealthCheck_Liveness'
links:
type: object
properties:
self:
$ref: '#/components/schemas/Link'
parent:
$ref: '#/components/schemas/Link'
required: [self, parent]
required: [data, links]
example:
data:
status: ok
timestamp: "2026-02-24T12:00:00Z"
links:
self:
href: /health/live
method: GET
parent:
href: /health
method: GET
HealthCheck_Readiness_Entity:
type: object
description: Envelope for the readiness resource.
properties:
data:
$ref: '#/components/schemas/HealthCheck_ReadinessPayload'
links:
type: object
properties:
self:
$ref: '#/components/schemas/Link'
parent:
$ref: '#/components/schemas/Link'
required: [self, parent]
required: [data, links]
example:
links:
self:
href: /health/ready
method: GET
parent:
href: /health
method: GET
HealthCheck_HealthSummary_Entity:
type: object
description: Envelope for the root health summary resource. Links to all children.
properties:
data:
$ref: '#/components/schemas/HealthCheck_HealthSummary'
links:
type: object
properties:
self:
$ref: '#/components/schemas/Link'
status:
$ref: '#/components/schemas/Link'
liveness:
$ref: '#/components/schemas/Link'
readiness:
$ref: '#/components/schemas/Link'
required: [self, status, liveness, readiness]
required: [data, links]
example:
links:
self:
href: /health
method: GET
status:
href: /health/ping
method: GET
liveness:
href: /health/live
method: GET
readiness:
href: /health/ready
method: GET