Skip to content

feat(logging): add rotating file logging with AppSettings-backed level override - #155

Closed
geourjoa wants to merge 3 commits into
feat-1/app-settings-modelfrom
feat-3/configurable-logging-app
Closed

feat(logging): add rotating file logging with AppSettings-backed level override#155
geourjoa wants to merge 3 commits into
feat-1/app-settings-modelfrom
feat-3/configurable-logging-app

Conversation

@geourjoa

@geourjoa geourjoa commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Recreated from #150 under a renamed branch — the original branch's pull_request webhook never fired (verified: neither a fresh push nor a close/reopen triggered CI, while workflow_dispatch runs against it passed fully). Same commits, same content; #150 will be closed pointing here.

Summary

Stacked on #148 (feat-1) — merge/rebase after that lands.

  • Added a RotatingFileHandler (10MB × 5 backups) to LOGGING in config/settings.py alongside the existing console handler, driven by new env var LOG_FILE_PATH (default /var/log/app/app.log); added app_logs volume to compose.yaml mounted on the api service only (deliberately not shared with celery, to avoid multi-process log-rotation corruption).
  • LOG_LEVEL is seeded into AppSettings (default ERROR, per spec) and applied at runtime via CommonConfig.ready(), since Django settings load before the DB/migrations are guaranteed ready.
  • CI fix: the original os.makedirs(dirname(LOG_FILE_PATH)) ran unguarded at settings.py import time — /var/log/app is only writable inside the deployed container (compose-provisioned volume), so any other environment (local dev, CI, an unprivileged host) hit a PermissionError before Django even finished loading settings. Now degrades to console-only logging when the directory can't be created, and config/test.env points LOG_FILE_PATH at /tmp so CI actually exercises the file handler instead of always falling back.

Test plan

  • ruff check / ruff format / mypy / architecture-boundaries clean
  • pytest apps/common passing
  • CI green (see linked runs on the renamed branch)

No new dependencies.

…l override

Adds a RotatingFileHandler alongside the existing console handler, wired
into both the `django` and `apps` loggers, with the target path/dir
configurable via a new LOG_FILE_PATH env var (settings.py creates the
directory on boot since Django won't). Persists across container restarts
via a new `app_logs` volume mounted on the `api` service in compose.yaml.

The static APP_LOG_LEVEL fallback default changes from INFO to ERROR per
the issue. A runtime hook in CommonConfig.ready() looks up an active
AppSettings(key="LOG_LEVEL") row and, if valid, overrides the `apps`/
`django` logger levels at process start — this can't live directly in the
LOGGING dict because settings.py loads before migrations are guaranteed to
run (or the DB is even reachable), so it's guarded with try/except.

Seeds the LOG_LEVEL AppSettings row (value "ERROR") via a standard
RunPython data migration.

Depends on feat-1/app-settings-model (AppSettings model), not yet merged.
…t writable

os.makedirs(dirname(LOG_FILE_PATH)) ran unguarded at settings.py import
time. The default /var/log/app is only writable inside the deployed
container (where compose.yaml provisions the app_logs volume) — any other
environment (local dev, CI, an unprivileged host) raised PermissionError
before Django finished loading settings, which is how this branch ended up
with zero CI runs at all rather than a failing one.

Wraps the makedirs call and degrades to console-only logging when the
directory can't be created, instead of taking down the whole app over an
optional feature. Also points config/test.env's LOG_FILE_PATH at /tmp so
CI/local test runs exercise the RotatingFileHandler path rather than always
hitting the fallback.
@geourjoa

geourjoa commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Closing — recreating the PR didn't fix the missing pull_request-triggered checks either, so this was a platform/webhook issue, not branch-specific. Consolidating back on #150, which has identical content and has been manually verified green via workflow_dispatch (see PR description).

@geourjoa geourjoa closed this Aug 5, 2026
@geourjoa
geourjoa deleted the feat-3/configurable-logging-app branch August 5, 2026 09:13
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