Skip to content

Logging And Verbosity

Scott Singleton edited this page May 10, 2026 · 1 revision

Logging & Verbosity

Tamp ships its own minimal logger rather than a third-party dependency. Single sink (a TextWriter), level-filtered, secret-aware via the redaction layer.

Levels

Level Use
Trace Per-step internal trace; chatty.
Debug Plan generation, skip reasons, deeper detail.
Info (default) Target start/end, build summary.
Warn Recoverable issues, deprecations.
Error Things that abort a target or the build.

Info lines have no prefix; everything else carries [TRACE] / [DEBUG] / [WARN] / [ERROR].

CLI control

tamp Compile --verbosity quiet         # errors only
tamp Compile --verbosity minimal       # warnings + errors
tamp Compile --verbosity normal        # default
tamp Compile --verbosity verbose       # + debug
tamp Compile --verbosity diagnostic    # + trace

# Shortcuts
tamp Compile --quiet
tamp Compile --verbose
tamp Compile --diagnostic

Both --verbosity quiet and --verbosity=quiet forms work. Short forms also accepted: --verbosity q | m | n | v | d.

Build summary

Always prints, regardless of verbosity. Quiet mode hides target progress lines but the summary table at the end of the run is always there:

─── Build Summary ───
  Target          Status      Duration
  Restore         ✓ Done      1.2 s
  Compile         ✓ Done      14.5 s
  Test            ✓ Done      8.3 s
  Pack            ✓ Done      4.0 s
                              ─────
  Total                       28.0 s

Status glyphs:

Status
Done
Failed
· Skipped (OnlyWhen / etc.)
NotRun (after a failure aborted the plan)

Writing from a target action

Inside a target's Executes lambda you can reach the executor's logger via TampBuild.CurrentLog(forthcoming — for now, just Console.WriteLines flow through the redaction layer in the executor's normal output path).

The Logger surface, when reachable from build scripts, will be:

Log.Trace("…");
Log.Debug("…");
Log.Info("…");
Log.Warn("…");
Log.Error("…");
Log.WriteRaw("…");      // bypasses level filter (used internally for the build summary)

Secret redaction

Every write through the executor's logger goes through a RedactingTextWriter first. When a Secret is registered (either by being declared on a CommandPlan.Secrets list, or via RedactionTable.Register directly), its value is scrubbed from any subsequent log output:

WARN: Authorization failed: bearer abc123def456
       ↓
WARN: Authorization failed: bearer <Secret:RegistryToken>

The redaction is per-line, including child-process stdout/stderr that flows through the executor. A secret split across two stream callbacks (e.g., the value arrives as two chunks) still redacts correctly because the RedactingTextWriter buffers per line.

What the redaction does NOT cover:

  • Output the build script writes via raw Console.Write (not through the executor's logger). If you bypass the framework's writer, you bypass redaction.
  • Process arguments visible to the OS process table while a child process runs. Use CommandPlan.StandardInput / wrappers like Docker.Login's --password-stdin for sensitive values that need to reach a child.

CI vendor logs

When running under a recognised CI vendor, target actions can emit vendor-specific log commands via the typed CiHost adapter — OpenGroup, LogError, SetVariable, etc. See CI Host Integrations for details.

Future: Tamp.Logging.Serilog

The Logger is deliberately minimal so it has no external deps. A future opt-in package Tamp.Logging.Serilog (not yet shipped) would adapt the Logger calls into a Serilog pipeline for consumers who want structured logging, sinks beyond the console, and cross-build aggregation.

See also

Clone this wiki locally