Skip to content

Output timestamps

Prefix every line rite emits — cmd stdout/stderr and rite's own rite: log lines — with a timestamp. The motivation is scrollback archaeology: when a long task takes too long, you should be able to read straight off the log where the time went, without first splitting rite's lines from the cmd's.

go-task has never shipped this (go-task/task#1065). rite owns its entire output pipeline so the prefix lands uniformly on every byte that leaves the process.

Three ways to turn it on

Precedence, highest-wins first: CLI / env > task > top-level.

1. CLI flag or env var

Highest precedence. Useful when debugging a single run without touching the Ritefile.

sh
rite --timestamps build                   # default ISO-8601 UTC ms layout
rite --timestamps="[%H:%M:%S]" build      # custom strftime format
RITE_TIMESTAMPS=1 rite build              # env var, same grammar
RITE_TIMESTAMPS=false rite build          # explicit override OFF (escape hatch)

2. Top-level (project-wide default)

Sibling of set: / output: at the entrypoint — opts every task in:

yaml
version: '3'
timestamps: true
tasks:
  build:
    cmds:
      - go build ./...

3. Task-level (per-task override)

Turn one task off (common) or give it a different format:

yaml
version: '3'
timestamps: true
tasks:
  build:
    cmds:
      - go build ./...
  repl:
    timestamps: false        # opt this interactive task out
    cmds:
      - node --interactive

The default format

Bare true (at any scope) renders a fixed-width bracketed ISO 8601 prefix:

[2026-04-15T14:23:01.123Z] go: downloading ...
  • Always UTC. rite calls .UTC() on the underlying time.Time so the host $TZ never leaks in.
  • Milliseconds are zero-padded to exactly three digits (.000, not .9) — column-oriented log tools assume fixed width.
  • Square brackets keep the prefix visually separable from the cmd content.

The default layout is anchored in code as ast.DefaultTimestampLayout so tooling and docs agree on the exact shape.

Custom strftime formats

Pass any string containing one or more of the supported strftime tokens:

tokenrenders asnotes
%Y2026four-digit year
%m04zero-padded month
%d15zero-padded day of month
%H14zero-padded hour (24h)
%M23zero-padded minute
%S01zero-padded second
%L.123three-digit millisecond, dot-prefixed (matches ts -s %.S)
%z-0700timezone offset
%%%literal percent

Anything else between % markers passes through as a literal. An unsupported token (%Q, etc.) is a hard error at Ritefile parse time — rite does not silently ignore unknown strftime codes.

Examples:

yaml
timestamps: "[%H:%M:%S]"           # [14:23:01]
timestamps: "%Y-%m-%dT%H:%M:%S%L"  # 2026-04-15T14:23:01.123

Custom formats render in local time unless they include %z or a literal UTC marker. The true default is the only UTC-forced form.

Interactive tasks opt out

When a task needs an interactive TTY (spinners, REPLs, Xcode's -showBuildSettings cursor dance), timestamp prefixes fight the cmd's redraws. The pattern is project-wide-on plus task-level-off:

yaml
version: '3'
timestamps: true      # every task logs with timestamps...
tasks:
  deploy:
    cmds:
      - kubectl apply -f manifests/
  debug-pod:
    timestamps: false # ...except this one, which wants a raw TTY
    cmds:
      - kubectl exec -it {{.POD}} -- /bin/bash

A CLI --timestamps preempts the task's false — if you explicitly ask for timestamps on the command line, you get them, even on a task that tried to opt out. Pragmatic: debugging an interactive flow sometimes needs timestamps even at the cost of visual noise.

Scope note

Task-level timestamps: controls the task's cmd output (the bytes the shell writes). rite's own rite: [task] cmd preamble line — which prints before the cmd runs — uses the global (CLI / top-level) setting. The preamble happens before any interactive TTY handoff, so stamping it is harmless and keeps rite's log voice consistent across tasks.

Interaction with other features

  • silent: tasks emit nothing to prefix, so timestamps are a no-op there.
  • output: group banners (begin: / end:) are rite's own output inside the output pipeline and are themselves timestamped.
  • output: prefixed labels come after the timestamp: [2026-04-15T14:23:01.123Z] [task:foo] some line.
  • ANSI color escapes are preserved — the timestamp lands before the first byte of the line, so color sequences aren't split.
  • Partial lines (a printf '%s' without a trailing newline) are buffered until newline arrives or the cmd exits. On exit rite flushes them with a final timestamp and a synthesized \n so log consumers never see half-stamped output.

Env var grammar

RITE_TIMESTAMPS accepts the same values as the flag, plus common variants:

valuemeaning
1, true, onon, default layout
0, false, offoff (escape hatch)
<strftime>on, custom format
unset or emptyno CLI-level override (falls through to Ritefile)

MIT licensed · hard fork of go-task