Log to a rotating file in production
You want production logs on disk: one file per day, capped so a single file never grows without bound, and guaranteed to flush the last entries when the container stops. That’s three options on FileLog plus one autoFlushOn.
The setup
Section titled “The setup”import { log, ConsoleLog, FileLog } from "@warlock.js/logger";
const isProduction = process.env.NODE_ENV === "production";
log.configure({ channels: isProduction ? [ new FileLog({ storagePath: process.cwd() + "/storage/logs", chunk: "daily", // one file per calendar day → 15-03-2024.log rotate: true, // roll the file over once it gets too big maxFileSize: 10 * 1024 * 1024, // 10 MB per file before rotation }), ] : [new ConsoleLog()], // Drain the in-memory buffer before the process exits. autoFlushOn: ["SIGINT", "SIGTERM", "beforeExit"],});Import it once, as early as possible:
import "./logger"; // side-effect: configures the singleton
import { log } from "@warlock.js/logger";
log.info("app", "boot", "Server listening on :3000");What each piece does
Section titled “What each piece does”chunk: "daily"names the file by date, so you get15-03-2024.log,16-03-2024.log, … instead of one ever-growingapp.log. Use"hourly"for very high volume,"single"(the default) for a single file.rotate: true(the default) checks the active file’s size before each write and, once it passesmaxFileSize, renames it aside (app-15-03-2024-1710494523000.log) and starts a fresh one.maxFileSizeis in bytes —10 * 1024 * 1024is 10 MB, which is also the default.autoFlushOnis the important one.FileLogbuffers entries in memory (it flushes at 100 entries or every 5 seconds), so a process that exits without draining loses whatever is still buffered. WiringSIGINT/SIGTERM/beforeExitmakes the logger flush onCtrl+C,docker stop, and natural exit. See Shutdown & flushing.
Keeping errors in their own file
Section titled “Keeping errors in their own file”A common refinement: everything goes to the daily file, and errors and warnings get their own dedicated file so on-call doesn’t have to grep the firehose.
log.setChannels([ new FileLog({ storagePath: "./storage/logs", chunk: "daily" }), new FileLog({ storagePath: "./storage/logs/errors", // ← its own directory levels: ["error", "warn"], // only these reach this file chunk: "daily", }),]);The levels whitelist is per channel — the first file still records everything. See Channels Overview for the filtering model.
See also
Section titled “See also”- File Channel — every
FileLogoption in detail - Shutdown & flushing — why the buffer needs draining and how
autoFlushOndoes it - JSON File Channel — swap
FileLogforJSONFileLogwhen a log aggregator reads the files