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
|
stdout and swallows plain ``print`` / stderr writes mid-render, so a
|
||||||
file sink is the only guaranteed way to see DEBUG diagnostics and
|
file sink is the only guaranteed way to see DEBUG diagnostics and
|
||||||
tracebacks.
|
tracebacks.
|
||||||
* ``StreamHandler`` → ``sys.__stderr__``. Uses the *original* stderr
|
* ``StreamHandler`` → ``sys.__stderr__`` (opt-in). Uses the *original*
|
||||||
file descriptor captured before Rich installed its Live display, so
|
stderr FD captured before Rich installed its Live display, so records
|
||||||
records bypass the progress renderer and land in the terminal or
|
would bypass the progress renderer and land in the terminal or journal
|
||||||
journal verbatim. Fine for production where Rich is off.
|
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)
|
- ``httpx`` / ``httpcore``: WARNING (prevent request-level debug flooding)
|
||||||
- ``uvicorn.access``: health path filter applied
|
- ``uvicorn.access``: health path filter applied
|
||||||
@@ -209,12 +214,17 @@ def setup_logging() -> None:
|
|||||||
"could not attach file log handler: %s", exc
|
"could not attach file log handler: %s", exc
|
||||||
)
|
)
|
||||||
|
|
||||||
# Stderr sink — writes to the *original* FD Rich captured at import
|
# Stderr sink — *opt-in* only. Interactive ``fast-agent go`` sessions
|
||||||
# time, so our records skip the progress display and hit the TTY
|
# install Rich's Live display which owns the terminal; emitting JSON
|
||||||
# (or systemd journal) directly.
|
# log records to stderr during that session corrupts the TUI on every
|
||||||
stream_handler = logging.StreamHandler(stream=sys.__stderr__)
|
# redraw and made Pallas effectively unusable in dev. Operators who
|
||||||
stream_handler.setFormatter(formatter)
|
# want systemd/journal capture can re-enable by exporting
|
||||||
handlers.append(stream_handler)
|
# ``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.
|
# Root logger carries everything from libraries we do NOT own.
|
||||||
# We set the level low enough to accept our configured level; each
|
# We set the level low enough to accept our configured level; each
|
||||||
|
|||||||
Reference in New Issue
Block a user