func/log creates a separate diagnostic log for each CLI invocation. It preserves troubleshooting details without mixing internal output into the command’s normal stdout.
Register and write a log
Register Logger through LogModule.register(), then inject it wherever diagnostics are produced:
import { Command, Handler, Module, createApp } from 'func'
import { Logger, LogModule } from 'func/log'
@Command('deploy')
export class DeployCommand {
constructor(private readonly logger: Logger) {}
@Handler()
run() {
this.logger.push('deploy started')
this.logger.push({ target: 'production' })
}
}
@Module({
commands: [DeployCommand],
imports: [LogModule.register()],
})
export class AppModule {}
const app = createApp(AppModule, { appName: 'ship' })
void app.bootstrap()This application writes under ~/.ship/logs. The application name comes from createApp({ appName }); func forwards it to Log, which validates it when the Logger Provider initializes. Every invocation uses a different filename containing a timestamp, process ID, and random identifier.
Logger.push(...data) combines its arguments with Node.js console-formatting semantics and writes a timestamped line. ANSI control sequences are removed so the file always contains plain text.
Understand the file lifecycle
Constructing Logger does not immediately create a directory or file. The file is opened only after the first successful push, and it closes during invocation disposal.
Successful calls do not print the log location. If a call fails after writing at least one record, disposal reports the path on stderr:
Logs were written to "/Users/ada/.ship/logs/func-....log".Logger.path exposes the resolved path for the current invocation even before the first push creates the file.
Limit size and retention
By default, one invocation may write up to 10 MiB and the directory retains the 10 most recent func log files. Both limits are configurable:
LogModule.register({
maxBytes: 2 * 1024 * 1024,
maxFiles: 20,
})| Setting | Behavior |
|---|---|
maxBytes | Maximum bytes written by one invocation; must be positive. |
maxFiles | Number of func log files retained; must be non-negative. |
maxFiles: 0 | Disable file logging entirely. |
After the size limit is reached, later records from that invocation are ignored and at most one warning is emitted. Failures while creating, writing, closing, or pruning log files never replace the original command result.
Retention cleanup only touches files matching the func log naming scheme; unrelated files in the same directory are left alone.
API reference
| API | Purpose |
|---|---|
LogModule.register(options?) | Register the per-invocation Logger Provider. |
Logger.push(...data) | Append a timestamped diagnostic record. |
Logger.path | Read the resolved log path for this invocation. |
LogModuleOptions | Configure maxBytes and maxFiles. |
LOG_SYSTEM / LOG_RUNTIME | Stable error-code enums for the logging feature. |