-
Notifications
You must be signed in to change notification settings - Fork 12.9k
feat(container-runner): persist agent container stdout+stderr to disk#2727
Open
manojp99 wants to merge 1 commit into
Open
feat(container-runner): persist agent container stdout+stderr to disk #2727manojp99 wants to merge 1 commit into
manojp99 wants to merge 1 commit into
Conversation
Agent containers' stdout and stderr were discarded — stdout dropped on the floor, stderr folded into log.debug which is invisible unless LOG_LEVEL=debug. Once a container was removed, all evidence was gone. This adds per-instance log file persistence via inherited file descriptor: the container writes directly to the file at the kernel level, so the host process is uninvolved after spawn(). Files accumulate at logs/containers/<group>/<containerName>.log and can be inspected with tail/less/grep or pruned with rm/find/cron. - New env var: NANOCLAW_CONTAINER_LOGS — default is DISABLED (no on-disk container logs). Set NANOCLAW_CONTAINER_LOGS=enabled in .env or the environment to turn persistence on. - When disabled, spawns with stdio=[ignore,ignore,ignore] — exactly the same effective behavior as before this change. - When enabled, file open failures fall through to stdio=ignore — persistence is best-effort and never blocks container spawn. - Removed the old container.stderr → log.debug handler (gated behind LOG_LEVEL=debug anyway) and the stdout no-op handler. - No rotation built in by design — operators manage retention manually via rm/find/cron. If manual pruning becomes tedious, that's the signal to add a sweep in host-sweep.ts. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
@manojp99
manojp99
requested review from
gabi-simons and
gavrielc
as code owners
June 10, 2026 20:19
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This is a sibling PR to microsoft/amplifier-app-nanoclaw#7 — the same container log persistence feature, now proposed for the original nanoclaw repo.
Problem
Agent containers' stdout and stderr are currently discarded:
log.debug()which only displays ifLOG_LEVEL=debug, and even then only goes to the host process' stdout/stderr (transient, not persisted)Once a container is removed (via
docker rm), all evidence is gone. This makes post-incident debugging impossible.Solution
Per-instance log file persistence via inherited file descriptor: the container writes directly to the file at the kernel level after
spawn()returns, so the host process is uninvolved. Files accumulate at:containerNamealready includesDate.now(), so files are unique per spawn.Configuration
New env var:
NANOCLAW_CONTAINER_LOGS— default is DISABLED (no on-disk container logs). Opt in:When disabled: spawns with
stdio=['ignore','ignore','ignore']— exactly the same behavior as before this change. Zero surprise for upgraders.When enabled but file open fails: falls back to
stdio=['ignore','ignore','ignore']— persistence is best-effort and never blocks container spawn.What changed
src/config.ts
NANOCLAW_CONTAINER_LOGSto the envConfig arrayCONTAINER_LOGS_ENABLED(true only if var is exactly"enabled")src/container-runner.ts
CONTAINER_LOGS_ENABLEDstdio: ['ignore', logFd, logFd](or all'ignore'when disabled)container.stderr → log.debughandler and thestdoutno-op handlerInspection & cleanup
What's NOT included (and why)
host-sweep.ts.tail -f.Verification
no-catch-allwarning at the log file open matches the pattern already used ×ばつ elsewhere in the file (intentional best-effort design).This is a minimal, isolated change to the container spawning path. No new dependencies, no retention logic, no complexity.