You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CLAUDE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -130,7 +130,7 @@ the existing viewset/serializer pattern and keep `v1` fields additive-only
130
130
-**Prod/test `config.ini` has only a `[Django]` section — no `[Postgres]` section.** Per `settings.py`, a missing `[Postgres]` section means Django uses the fallback `DATABASES` default (`HOST='db'`) — i.e. the dockerized `db` service of the active compose file. A `[Postgres]` section, if added, would override it. So the DB is the in-stack `db` container in **every** environment (no external Postgres); on the servers that's the `db` service in `docker-compose.yml`.
-`TIME_ZONE = 'America/Los_Angeles'`. `ML_WEBSITE_VERSION` in settings is shown in the admin header and used in release tagging.
133
-
-**Logging (#1283):**`debug.log` lives at `LOG_DIR/debug.log`, where `LOG_DIR` is `$ML_LOG_DIR` or `<BASE_DIR>/media` (`/code/media` in the container). Keep it inside `MEDIA_ROOT` — that's the tree bind-mounted to the shared CSE filesystem, so it's what makes the log readable over SSH at all. `ML_LOG_DIR` is unset everywhere today; it exists for non-`/code` hosts. `MEDIA_ROOT` is web-served, so never log anything sensitive. If the dir isn't writable the file handler degrades to a `NullHandler` rather than crashing `django.setup()`, and since there's no console on the servers that state surfaces via `/version.json` (`log_to_file`) and a superuser-only callout on the admin dashboard.
133
+
- **Logging (#1283):** `debug.log` lives at `LOG_DIR/debug.log`, where `LOG_DIR` is `$ML_LOG_DIR` or `<BASE_DIR>/media` (`/code/media` in the container). Keep it inside `MEDIA_ROOT` — that's the tree bind-mounted to the shared CSE filesystem, so it's what makes the log readable over SSH at all. `ML_LOG_DIR` is unset everywhere today; it exists for non-`/code` hosts. `MEDIA_ROOT` is web-served, so never log anything sensitive. If the dir isn't writable the file handler degrades to a `NullHandler` rather than crashing `django.setup()`, and since there's no console on the servers that state surfaces via `/version.json` (`log_to_file`) and a superuser-only callout on the admin dashboard. Rotation uses `concurrent-log-handler` (#1439) because Gunicorn's 3 workers share one file — the stdlib `RotatingFileHandler` races on rollover across processes. Its lock file goes in a per-uid temp dir (`/tmp/makelab-log-locks-<uid>`), never the web-served media root and never shared across users. If the package isn't importable (the bind-mounted checkout can be ahead of the image's site-packages) or no lock dir is usable, the handler degrades to the stdlib `RotatingFileHandler` instead of crashing `django.setup()`; `/version.json` reports which one is live as `log_rotation`. `django.db.backends` is pinned to INFO so per-query SQL doesn't dominate the log (or the lock).
134
134
135
135
### Container startup side effects (`docker-entrypoint.sh`)
# Makeability Lab Global Variables, including Makeability Lab version
89
-
ML_WEBSITE_VERSION="2.32.0"# Keep this updated with each release and also change the short description below
90
-
ML_WEBSITE_VERSION_DESCRIPTION="Positions can now be titled \"Research Software Engineer\", and the affiliation fields are relabeled \"Institution or organization\"and \"Department or unit\" — collaborators come from nonprofits and companies, not just universities (#1437). This release also carries the 2.31.1 log-path fix (#1283)."
90
+
ML_WEBSITE_VERSION="2.32.1"# Keep this updated with each release and also change the short description below
91
+
ML_WEBSITE_VERSION_DESCRIPTION="debug.log rotation is now multiprocess-safe (concurrent-log-handler): Gunicorn's three workers previously raced on rollover and silently lost log records (#1439)."
91
92
DATE_MAKEABILITYLAB_FORMED=datetime.date(2012, 1, 1) # Date Makeability Lab was formed
92
93
MAX_BANNERS=7# Maximum number of banners on a page
93
94
@@ -122,6 +123,21 @@
122
123
# degraded state is surfaced two web-reachable ways instead: the 'log_to_file' field
123
124
# on /version.json (website/views/version.py) and a warning callout on the admin
124
125
# dashboard (website/templates/admin/index.html).
126
+
# Probed once, at import, so a missing package degrades the handler instead of
127
+
# killing startup (see _file_log_handler). This matters because the container
128
+
# bind-mounts the repo over /code while site-packages come from whenever the
129
+
# image was last built: a branch switch or the window between the deploy
130
+
# webhook's `git pull` and `docker compose build` can leave new settings.py
131
+
# running against an older image. dictConfig raises ValueError ("Unable to
132
+
# configure handler 'file'") on an unimportable class, and that aborts
133
+
# django.setup() — no NullHandler degrade, no /version.json, no admin callout.
134
+
try:
135
+
importconcurrent_log_handler# noqa: F401 (imported only to probe availability)
136
+
_HAS_CONCURRENT_LOG_HANDLER=True
137
+
exceptImportError:
138
+
_HAS_CONCURRENT_LOG_HANDLER=False
139
+
140
+
125
141
def_ensure_log_dir_writable(log_dir):
126
142
"""Create ``log_dir`` if needed and return True if it looks writable.
0 commit comments