Digging Deeper
Logging
Introduction
JCC Express MVC ships with a Laravel-style logging API built on top of winston.
Core capabilities:
- PSR-3 / RFC 5424 levels (
emergency,alert,critical,error,warning,notice,info,debug) - Multiple channels (
single,daily,console,stderr,stack) - Channel stacks — write one message to several channels at once
- Per-logger context (
withContext) attached to every entry - Static facade usage via
Log(exported fromjcc-express-mvc/Core) - A global
logger()helper for quick debug logging
Configuration and bootstrapping
Logging is configured in app/Config/logging.ts and merged in app/Config/index.ts.
At runtime, LogServiceProvider reads app.config.logging and calls Log.configure(...).
If no config is present it falls back to defaults derived from the LOG_CHANNEL, LOG_LEVEL
and LOG_DAILY_DAYS environment variables.
Relevant .env keys:
You can also reconfigure logging at runtime (useful in tests):
Channel drivers
| Driver | Description |
|---|---|
single | Appends every entry to one file (path, default storage/logs/app.log). |
daily | Writes to <name>-YYYY-MM-DD.log next to path and prunes files older than days (default 14). |
console | Writes to stdout. |
stderr | Like console, but all levels go to stderr. |
stack | Forwards to a list of other channels (channels: [...]). |
Each non-stack channel accepts an optional level — entries below that severity are dropped for that channel.
The
dailydriver is a lightweight built-in transport (no extra dependency). If you need rotation by size or compression, installwinston-daily-rotate-fileand configure a custom channel in your logging config.
Writing log messages
Each method accepts an optional context object, which is appended to the line as JSON:
Passing an Error logs its message and stack trace:
Log.log(level, message, context?) (and its alias Log.write) let you pass the level dynamically.
Channels and stacks
Log.channel() with no argument returns the default channel — the same target used by Log.info(...).
Contextual logging
withContext returns a logger that merges the given data into every subsequent entry — handy for
request IDs, user IDs, job names, etc.
You can also bind context on a specific channel:
The logger() helper
A global logger() helper is available everywhere for quick logging:
Log files
By default, file channels write under storage/logs/:
single→storage/logs/app.logdaily→storage/logs/jcc-YYYY-MM-DD.log
The directory is created automatically on first write.
Summary
- Configure channels in
app/Config/logging.ts;LogServiceProviderapplies it viaLog.configure(...). - Use the
Logfacade (jcc-express-mvc/Core) with PSR-3 level methods. - Use
Log.channel(name)/Log.stack([...])to target specific outputs. - Use
Log.withContext({...})to attach structured data to every entry. - Tune
LOG_CHANNEL,LOG_LEVELandLOG_DAILY_DAYSin.env.