ctx.log records structured, leveled logs from inside a workflow. Unlike a bare console.log - which
stays on the runner’s stdout, invisible to Duraton - ctx.log lines flow to Duraton, persist
durably with the run, and are readable per run via the API.
Logging a line
ctx.log is callable (info level) and has one method per level:
fields is an optional object of structured context. It is stored as JSON, so prefer structured
fields over interpolating values into the message.
Durable under replay
A handler re-runs from the top on every pass (durable execution), soctx.log is replay-aware:
- A handler-level log (outside any step) re-emits on every pass, but Duraton gives it a stable identity per attempt and records it exactly once.
- A log inside a
step.runonly executes on the pass where that step runs. A step that retries records its logs once per attempt, so you can see what each attempt did:
Redaction
Field values under sensitive key names (password, token, secret, authorization, and similar)
are masked to [redacted] before anything is persisted.
Redaction is keyed on field names, so prefer putting sensitive values in named fields rather than
inlining them into the free-text message.
Reading logs back
Fetch a run’s logs oldest-first:level, message, fields, scope (the step name, or @root for a
handler-level log), and attempt. See the Runs API for pagination and the
full response shape.
Limits
Each pass caps how many lines it ships so a pathologically chatty handler cannot overrun the 1 MiB wire-message limit; beyond the cap, a single line records how many were dropped. Logs are part of a run’s data and are removed with the run.See the logging example running end to end in Examples.