One-line lightweight observability for Node.js. Wires together three small, independent packages so you get health, info, metrics, request timelines, and event-loop watchdog without OpenTelemetry, agents, collectors, or vendor tooling.
node-actuator-lite— Spring Boot-style/actuator/health,/info,/metrics,/env,/threaddump,/heapdump, and/prometheusendpoints.node-eventloop-watchdog— Detects event-loop stalls, captures stack traces and hotspots, and triggers recovery.node-request-trace— Per-request timelines, browser dashboard, and CLI without OpenTelemetry.
When all three are wired together by this package:
- The watchdog auto-registers
/actuator/eventloop,/actuator/eventloop/history,/actuator/eventloop/hotspots, and/actuator/eventloop/metrics. - Block events include the active request id, route, and method captured by
node-request-trace. - A custom
eventLoophealth indicator marks the processDOWNwhen blocks pile up. - An
info.contributors.ecosystemblock surfaces the bundled package versions.
npm install node-observability-liteRequires Node.js >= 18. Express is an optional peer dependency.
const express = require('express');
const observability = require('node-observability-lite');
const app = express();
observability.express(app, {
preset: 'production',
auth: (req) => req.get('authorization') === `Bearer ${process.env.OPS_TOKEN}`,
});
app.get('/', (_req, res) => res.json({ ok: true }));
app.listen(3000);const Fastify = require('fastify');
const observability = require('node-observability-lite');
const app = Fastify();
await observability.fastify(app, {
preset: 'production',
auth: (request) => request.headers.authorization === `Bearer ${process.env.OPS_TOKEN}`,
});
app.get('/', async () => ({ ok: true }));
await app.listen({ port: 3000 });const Koa = require('koa');
const observability = require('node-observability-lite');
const app = new Koa();
observability.koa(app, {
preset: 'production',
auth: (ctx) => ctx.headers.authorization === `Bearer ${process.env.OPS_TOKEN}`,
});
app.use(async (ctx) => {
if (ctx.path === '/') ctx.body = { ok: true };
});
app.listen(3000);Runnable versions of all three live under examples/.
Each gives you, behind the bearer token:
GET /actuator
GET /actuator/health
GET /actuator/info
GET /actuator/metrics
GET /actuator/prometheus
GET /actuator/eventloop
GET /actuator/eventloop/history
GET /actuator/eventloop/hotspots
GET /actuator/eventloop/metrics
GET /trace/recent
GET /trace/slow
GET /trace/stats
GET /trace/ui
| Preset | Sensitive endpoints | Watchdog | Trace | Auth required |
|---|---|---|---|---|
production (default) |
env / heapdump / threaddump disabled | observe mode | enabled | yes |
development |
all enabled | observe mode | enabled | no |
minimal |
env / heapdump / threaddump disabled | disabled | disabled | no |
Override anything per-package:
observability.express(app, {
preset: 'production',
auth: req => true,
basePath: '/management',
actuator: {
health: { groups: { liveness: ['process'] } },
},
watchdog: {
warningThreshold: 200,
criticalThreshold: 1000,
},
trace: {
slowThreshold: 500,
},
});Mounts the trace middleware, optional auth guard, the actuator middleware, and the trace dashboard router on an Express app, and starts the event-loop watchdog. Returns the underlying actuator instance plus references to the watchdog and trace singletons (or null when those are disabled by the resolved preset).
Registers the trace plugin, an optional preHandler auth hook, the actuator plugin, and a /trace/* JSON/UI route on a Fastify instance, and starts the event-loop watchdog. Async because Fastify plugin registration is async.
Mounts the Koa trace middleware (after instrumenting the app), an optional auth middleware, the actuator middleware (Express-compatible, wrapped via an internal adapter), and the /trace/* route on a Koa app, and starts the event-loop watchdog.
Resolves a user options object against the chosen preset. Useful for inspection or for plugging the result into a custom integration.
Returns the names of built-in presets.
| Option | Type | Default | Description |
|---|---|---|---|
preset |
'production' | 'development' | 'minimal' |
'production' |
Built-in baseline. |
basePath |
string |
'/actuator' |
Actuator base path; also used by the auth guard. |
auth |
(req) => boolean | Promise<boolean> |
none | Required when the preset enforces auth. Receives the Express request. |
requireAuth |
boolean |
preset value | Force-enable or disable the auth guard. |
includeEventLoopHealthIndicator |
boolean |
true |
Add the auto-generated eventLoop health indicator. |
actuator |
object | preset values | Deep-merged onto the preset actuator options. See node-actuator-lite. |
watchdog |
object | preset values | Deep-merged onto the preset watchdog options. See node-eventloop-watchdog. |
trace |
object | preset values | Deep-merged onto the preset trace options. See node-request-trace. |
productionpreset disablesenv,threaddump, andheapdumpendpoints.productionpreset requires anauthfunction before any actuator or trace path is served.- The auth guard runs before any actuator/trace middleware.
Releases are published with npm provenance so you can verify the origin of every published version:
npm view node-observability-lite --json | jq '.dist'The release workflow runs on tagged commits in this repository, executes lint/typecheck/coverage gate, and only then publishes to npm with --provenance --access public.
See SECURITY.md for how to report vulnerabilities.
See CONTRIBUTING.md and CODE_OF_CONDUCT.md. Issues and PRs are welcome.
For deeper documentation on the option shape, custom dependency injection, and shutdown handling, see USAGE.md.
MIT