12. Logging and diagnostics
Source 12-logging-and-diagnostics.md
Commands are short-lived, so this spec does not copy the twelve-factor “logs as an event stream” idea. The twelve-factor app is written for long-running services whose platform captures stdout and routes it. A command that runs for a moment has no such platform, and in this spec stdout carries data only (section 4). So a CLI does not write structured (JSON) log events to stdout or stderr.
Verbose mode
-verboseis a boolean parameter on every CLI. It is off by default. There is no single-letter alias (3a).- With
-verbose, the CLI writes extra human-readable diagnostic lines to stderr. They explain what it is doing. Examples of useful content:- which config files and folders it read or used, and the resolved scope values (
env, tenant, organization, project, namespace, see 3a), - waiting for a lock, and who holds it (section 7),
- calls made to a remote system: the method and address, the status, and the time taken,
- the debug detail of a failure: a stack, or a raw response from a remote system.
- which config files and folders it read or used, and the resolved scope values (
- There is one level, on or off. No
-verbose 3, no level names. - stdout is unchanged. The
resultis the same with or without-verbose. - Diagnostic lines follow the colour and styling rules of section 4, per stream. They are plain text, not JSON.
- Diagnostic lines are not a contract. Their wording and order can change at any time, with no notice. Programs read
resultanderror, never the diagnostics. - Never print secrets, even in verbose mode. No credential, token, or password. Print names, not values. This includes values from a credential CLI (section 9) and sensitive parameters (3a). A remote call is shown without its authorization header or any secret in the address.
Errors and verbose mode
- Without
-verbose, an error carries only what section 5 defines. Debug detail (a stack, a raw remote response) is not printed. - With
-verbose, that debug detail is printed as diagnostic lines on stderr. internalerrors (section 5) tell the caller to repeat the command with-verboseand to include therequestIdwhen reporting a bug.- Output with
-output jsonoryamland-verbosetogether: the diagnostic lines come first, and the error object is the last line of stderr, on its own line. A program that needs exactly one object on stderr does not pass-verbose. - No diagnostic log file by default. A failure is investigated by repeating the command with
-verbose. A CLI may keep a log file, in which case the convention of section 9 applies.
Out of scope: tracing and metrics
- This spec gives no guidance on tracing or metrics. How a CLI or a team measures or follows commands is up to the implementer.
- Boundary: anything an implementer adds must not change the specified behaviour. It must not write to stdout, change an exit code or an output shape, put a secret anywhere, or alter the files and folders of section 9.