Skip to content

feat: daemon logging spine — rotated, timestamped, manifest-configurable#226

Merged
ArthurBernard merged 2 commits into
developfrom
feat/daemon-log-setup
Jul 14, 2026
Merged

feat: daemon logging spine — rotated, timestamped, manifest-configurable#226
ArthurBernard merged 2 commits into
developfrom
feat/daemon-log-setup

Conversation

@ArthurBernard

Copy link
Copy Markdown
Owner

Summary

  • Leaf 01/3 of the daemon-logging plan (docs: plan daemon-logging #225): a real logging spine for the daemon path — logs/daemon.log written by a midnight-rotating handler (14-day retention), every line ISO-8601-timestamped with the numeric tz offset, level/dir/retention configurable via the manifest's new optional logging: section.

Why

  • The 2026-07-14 health audit was nearly blind: the log was a bare shell redirect — no timestamps, no rotation, 10 process incarnations interleaved, and the engine's own module loggers emitted into the void (no handler). Tick-error tracebacks were invisible. ADR: root-handler spine with owned/tagged handlers (idempotent), third-party namespaces capped at WARNING, local-time-with-offset timestamps.

Changes

  • trading_bot/application/log_setup.py (new): configure_daemon_logging() — owned TimedRotatingFileHandler (midnight, backupCount=retention_days) + stderr handler, _OffsetIsoFormatter, noisy-namespace caps, idempotent re-call.
  • trading_bot/application/config.py: LoggingConfig (validated level, dir, retention_days ≥ 1) + additive logging: field on AppConfig.
  • trading_bot/interfaces/cli/main.py (daemon path only): wires the setup; daemon started/stopped → log + console, per-tick heartbeat → log only, tick errors → logger.exception (tracebacks captured). Interactive commands untouched.
  • Tests: test_log_setup.py (new, handler wiring/idempotence/format/levels), test_config.py extended.

Changelog

Added under [Unreleased]: daemon logs are real logs — rotated, tz-offset-timestamped, manifest-configurable; tick tracebacks captured.

Test plan

  • python -m pytest — 1495 passed, 1 skipped, cov 96.27%
  • ruff check trading_bot/ + ruff format --check green
  • Real-data verification: scratch daemon (port 8099, copied books, read-only dccd store) wrote daemon.log via the handler — started / 3 tick lines (last two exactly 60 s apart) / stopped, all +02:00-stamped; live daemon (pid 1348485, port 8000) untouched
  • CI green

Wire a real logging setup for the daemon path (start [--serve]):

- LoggingConfig (level/dir/retention_days) as an additive logging: section
  on AppConfig — a manifest without one keeps the defaults (INFO, logs/, 14d).
- configure_daemon_logging(): midnight-rotated TimedRotatingFileHandler
  (daemon.log, backupCount=retention_days) + a stderr StreamHandler on the
  root logger, ISO-8601 local timestamps with numeric UTC offset; noisy
  third-party namespaces (apscheduler/uvicorn/httpx/websockets) capped at
  WARNING; idempotent via owned-handler tagging.
- _run_daemon routes its lifecycle lines through trading_bot.daemon:
  started/stopped log + console, per-tick line log-only, tick errors via
  logger.exception so tracebacks land in the file.

Interactive CLI commands keep their rich-console output unchanged.
@ArthurBernard
ArthurBernard force-pushed the feat/daemon-log-setup branch from c683249 to 6c3f32f Compare July 14, 2026 12:37
@ArthurBernard
ArthurBernard merged commit e493d72 into develop Jul 14, 2026
@ArthurBernard
ArthurBernard deleted the feat/daemon-log-setup branch July 14, 2026 12:38
This was referenced Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant