Review of the logging work from the previous commit turned up a real correctness issue: the uncaughtException/unhandledRejection handlers logged the error but let the process keep running, which silently disabled Node's default crash-on-fatal-error behavior and could leave a zombie process serving broken requests instead of restarting. Both processes now log and then exit(1); restart: unless-stopped is added to both services so Docker actually brings them back up. Also: harden the logger against JSON.stringify throwing on non-serializable meta, log aborted (closed-before-finished) requests in the API access log, and stop the Next.js proxy from logging the Docker healthcheck's request to "/" every few seconds so real navigation events aren't drowned out. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
27 lines
861 B
TypeScript
27 lines
861 B
TypeScript
import { createLogger, toErrorMeta } from "./shared/logging/logger";
|
|
|
|
export function registerNodeInstrumentation() {
|
|
const logger = createLogger("web");
|
|
const heartbeatIntervalMs = 5 * 60 * 1000;
|
|
|
|
logger.info("web server starting", { pid: process.pid });
|
|
|
|
process.on("uncaughtException", (error) => {
|
|
logger.error("uncaught exception, exiting", toErrorMeta(error));
|
|
process.exit(1);
|
|
});
|
|
|
|
process.on("unhandledRejection", (reason) => {
|
|
logger.error("unhandled rejection, exiting", toErrorMeta(reason));
|
|
process.exit(1);
|
|
});
|
|
|
|
setInterval(() => {
|
|
const memory = process.memoryUsage();
|
|
logger.verbose("heartbeat", {
|
|
uptimeSeconds: Math.round(process.uptime()),
|
|
rssMb: Math.round(memory.rss / 1024 / 1024),
|
|
heapUsedMb: Math.round(memory.heapUsed / 1024 / 1024),
|
|
});
|
|
}, heartbeatIntervalMs).unref();
|
|
}
|