Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Output and logs

NXD writes to two places at once, with different jobs.

ChannelContainsAudience
TerminalCompact progress milestones and a final summaryYou, watching a deployment
Log file (.log/nxd-<host>.log)Complete untruncated output: raw subprocess stdout and stderr, Disko traces, store transfer listings, activation debugYou, afterwards, working out what happened

Every lifecycle operation uses both, whether it targets one host or twenty. The terminal never becomes the only record, and the log file never becomes the thing you have to read to follow a normal run.

Progress lines name what they did

A progress message states the specific resource, the action, and the parameters that matter. Vague provider phases such as “VMware action completed” are deliberately not allowed — a message that does not say which resource it touched is not useful in a postmortem.

Step formatting depends on duration, to avoid noise:

  • Fast steps emit a single completed line with exact parameters:

    [medo-test] Configured DNS resolvers (1.1.1.1, 8.8.8.8)
    
  • Slow steps emit an active line when they start and a completion line annotated with how long they took:

    [medo-test] Partitioning & formatting disk /dev/vda with Disko...
    [medo-test] Partitioned & formatted disk /dev/vda (ext4) (18s)
    

A fast step never emits both a started and a completed line for the same work.

Secrets are redacted in both channels

Secret values, private keys, tokens, and confidential parameters are redacted from the terminal and from log files. A log file is a durable artifact that often gets pasted into an issue or a chat, so it is held to the same standard as anything else that leaves the machine.

Profiling is separate

--profile reports internal phase timings for diagnosing where a slow run spent its time:

PROFILE phase=inventory-evaluation duration_ms=4120

It covers inventory evaluation, runtime composition, selected-output evaluation, endpoint attestation, secret resolution, observation, planning, apply, and total time.

Profiling output goes to stderr (or structured JSON) so it never disturbs the normal progress stream or any JSON on stdout. Progress reports human durations for milestones you care about; profiling reports machine-readable latency for phases you are investigating. They share the same underlying timers and do not duplicate each other’s lines.

Phase names are stable operator diagnostics. They are not a second lifecycle model, and commands do not invent provider phases by parsing action names.

Build placement is reported

Provider progress reports both the configured and the resolved build placement, so an auto setting never leaves you guessing where the work actually happened:

✓ [medo] build placement configured=auto builder=deploy@utils

For the full invariants, see docs/architecture-design/logging-and-progress.md in the repository.