log: gate stderr handler behind PALLAS_LOG_STDERR so fast-agent TUI is usable
The stderr StreamHandler, even using sys.__stderr__ captured before Rich installed its Live display, still corrupts the fast-agent TUI in interactive 'fast-agent go' sessions — Rich redraws on top of our JSON log lines but leaks through every repaint, making the interface effectively unusable. Keep the RotatingFileHandler as the always-on durable capture (that's what survives fast-agent's progress_display takeover and what we rely on for diagnostics). Gate the stderr sink behind PALLAS_LOG_STDERR=1 for operators who explicitly want journal/terminal capture on a systemd-managed deployment.
This commit is contained in:
@@ -171,10 +171,15 @@ def setup_logging() -> None:
|
||||
stdout and swallows plain ``print`` / stderr writes mid-render, so a
|
||||
file sink is the only guaranteed way to see DEBUG diagnostics and
|
||||
tracebacks.
|
||||
* ``StreamHandler`` → ``sys.__stderr__``. Uses the *original* stderr
|
||||
file descriptor captured before Rich installed its Live display, so
|
||||
records bypass the progress renderer and land in the terminal or
|
||||
journal verbatim. Fine for production where Rich is off.
|
||||
* ``StreamHandler`` → ``sys.__stderr__`` (opt-in). Uses the *original*
|
||||
stderr FD captured before Rich installed its Live display, so records
|
||||
would bypass the progress renderer and land in the terminal or journal
|
||||
verbatim. In interactive ``fast-agent go`` sessions this still
|
||||
smashes the Rich UI (Rich redraws on top but our JSON lines leak
|
||||
through every repaint), so we only attach it when ``PALLAS_LOG_STDERR``
|
||||
is set to a truthy value — production systemd deployments that want
|
||||
journal capture should set ``PALLAS_LOG_STDERR=1``; interactive users
|
||||
get a clean TUI and rely on the rotating file sink.
|
||||
|
||||
- ``httpx`` / ``httpcore``: WARNING (prevent request-level debug flooding)
|
||||
- ``uvicorn.access``: health path filter applied
|
||||
@@ -209,12 +214,17 @@ def setup_logging() -> None:
|
||||
"could not attach file log handler: %s", exc
|
||||
)
|
||||
|
||||
# Stderr sink — writes to the *original* FD Rich captured at import
|
||||
# time, so our records skip the progress display and hit the TTY
|
||||
# (or systemd journal) directly.
|
||||
stream_handler = logging.StreamHandler(stream=sys.__stderr__)
|
||||
stream_handler.setFormatter(formatter)
|
||||
handlers.append(stream_handler)
|
||||
# Stderr sink — *opt-in* only. Interactive ``fast-agent go`` sessions
|
||||
# install Rich's Live display which owns the terminal; emitting JSON
|
||||
# log records to stderr during that session corrupts the TUI on every
|
||||
# redraw and made Pallas effectively unusable in dev. Operators who
|
||||
# want systemd/journal capture can re-enable by exporting
|
||||
# ``PALLAS_LOG_STDERR=1`` before launching. The rotating file sink
|
||||
# above is the always-on durable capture.
|
||||
if os.environ.get("PALLAS_LOG_STDERR", "").lower() in ("1", "true", "yes"):
|
||||
stream_handler = logging.StreamHandler(stream=sys.__stderr__)
|
||||
stream_handler.setFormatter(formatter)
|
||||
handlers.append(stream_handler)
|
||||
|
||||
# Root logger carries everything from libraries we do NOT own.
|
||||
# We set the level low enough to accept our configured level; each
|
||||
|
||||
Reference in New Issue
Block a user