systemd Notify
sd_notify protocol surface for daemons running under Type=notify systemd units. Composes the standard lifecycle messages — READY=1 on boot, WATCHDOG=1 on heartbeat, STOPPING=1 on shutdown, RELOADING=1 on hot-reload — against the $NOTIFY_SOCKET env var systemd populates for the child process.
Transport: Node has no unix-DGRAM socket support in its dgram module, so the v1 path shells out to systemd-notify(1) via execFile (NOT exec — no shell-string parsing on the message bytes). Operators running under systemd already have systemd-tools installed by definition, so the dependency is no expansion of the trust surface.
Compose with b.appShutdown for the STOPPING signal: register a priority-0 phase that calls b.sdNotify.stopping() so systemd sees the shutdown intent before the framework tears anything down. Compose with a periodic WATCHDOG=1 against the unit's WatchdogSec= interval so systemd auto-restarts the daemon if the event loop wedges.
When $NOTIFY_SOCKET is unset (process running outside systemd — bare invocation, foreground dev, container without --notify-ready), every call is a no-op that surfaces a single boot-time audit entry. Operators get observability of the degraded state without per-call log noise.
b.sdNotify.send(opts) #
{
state: string, // e.g. "READY=1" / "STOPPING=1"
status: string, // free-form status text → `STATUS=`
mainpid: number, // PID override → `MAINPID=`
audit: boolean, // default true
}
Generic sd_notify dispatch. Sends one or more KEY=VALUE payload lines to systemd via systemd-notify(1). No-op when $NOTIFY_SOCKET is unset (foreground / container without --notify-ready / non-systemd init). Returns a Promise resolving on dispatch success.
await b.sdNotify.send({ state: "READY=1", status: "Listening on :8080" });
b.sdNotify.ready(opts?) #
{
status: string, // free-form status text → STATUS=
audit: boolean, // default true
}
Send READY=1 to systemd, signaling boot complete. Use once the listener is bound and the daemon is accepting work.
await b.sdNotify.ready({ status: "Listening on :8080" });
b.sdNotify.stopping(opts?) #
{
status: string, // free-form status text → STATUS=
audit: boolean, // default true
}
Send STOPPING=1. Operators wire this into b.appShutdown as the earliest shutdown phase (priority 0) so systemd sees the shutdown intent before any teardown begins.
b.appShutdown.create({ name: "sd-notify-stopping", priority: 0,
run: function () { return b.sdNotify.stopping(); } });
b.sdNotify.reloading(opts?) #
{
status: string, // free-form status text → STATUS=
audit: boolean, // default true
}
Send RELOADING=1 then (after the reload completes) READY=1. Use during hot-config-reload paths; systemd treats the unit as "reloading" until the next READY=1.
await b.sdNotify.reloading();
await reloadConfig();
await b.sdNotify.ready();
b.sdNotify.watchdog(opts?) #
{
audit: boolean, // default true
}
Send WATCHDOG=1. Operators with WatchdogSec= configured on their unit call this periodically (e.g. every WatchdogSec/2) so systemd auto-restarts the daemon when the event loop wedges.
setInterval(function () { b.sdNotify.watchdog(); }, 15000);
Last updated 2026-08-08T16:39:49.652Z by seeder.