docs(monitor): record phase 1 as deployed + prod verification results
Phase 1 is live on cochi. The deploy exercised the rotation path on its own — monitor came up against the pre-restart latest.log, Minecraft created a new one, tailer reported rotations:1 and kept streaming — which was the single failure this design was most likely to hit. Also records the one known cosmetic gap: a delete-then-recreate rotation takes the "file was gone" branch, so the rotations counter does not tick. Streaming is unaffected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
fca6747bcc
commit
53604a6127
1 file changed
+37
-8
+37
-8
@@ -247,16 +247,17 @@ tail-across-rotation. None of it is in the tiles. Once a password-gated page
|
|||||||
shows raw log lines, everything after is a small additive commit with a rolling
|
shows raw log lines, everything after is a small additive commit with a rolling
|
||||||
one-container restart.
|
one-container restart.
|
||||||
|
|
||||||
### Phase 1 — thin slice: logs only
|
### Phase 1 — thin slice: logs only — **DONE, live on cochi 2026-08-01**
|
||||||
|
|
||||||
- [ ] DNS A record for `monitor.${BASE_DOMAIN}`; add to `LE_SUBDOMAINS`; issue cert.
|
- [x] DNS A record for `monitor.${BASE_DOMAIN}`; add to `LE_SUBDOMAINS`; issue cert.
|
||||||
- [ ] `docker/monitor/` — Go service: ring buffer, tailer (inode/shrink reopen),
|
(DNS already resolved — the zone has a wildcard, so no record was needed.)
|
||||||
|
- [x] `docker/monitor/` — Go service: ring buffer, tailer (inode/shrink reopen),
|
||||||
cold-start backfill, `GET /api/log?since=`, `GET /healthz`, embedded UI.
|
cold-start backfill, `GET /api/log?since=`, `GET /healthz`, embedded UI.
|
||||||
- [ ] `ui/index.html` — log pane, sticky autoscroll, filter, level chips.
|
- [x] `ui/index.html` — log pane, sticky autoscroll, filter, level chips.
|
||||||
- [ ] compose service (no `ports:`, `mc_data:/data:ro`).
|
- [x] compose service (no `ports:`, `mc_data:/data:ro`).
|
||||||
- [ ] `caddy/conf.d/80-monitor.caddy` + `MONITOR_USER`/`MONITOR_PASSWORD_HASH`.
|
- [x] `caddy/conf.d/80-monitor.caddy` + `MONITOR_USER`/`MONITOR_PASSWORD_HASH`.
|
||||||
- [ ] nginx vhost + `MONITOR_ENABLED` gate; render + reload.
|
- [x] nginx vhost + `MONITOR_ENABLED` gate; render + reload.
|
||||||
- [ ] Deploy with `--hard` (world downtime). Verify below.
|
- [x] Deploy with `--hard` (world downtime, 0 players online). Verified below.
|
||||||
|
|
||||||
### Phase 2 — tiles
|
### Phase 2 — tiles
|
||||||
|
|
||||||
@@ -301,3 +302,31 @@ Then the one that actually matters, because it is the failure this design is
|
|||||||
most likely to hit: **restart the Minecraft server and confirm the stream keeps
|
most likely to hit: **restart the Minecraft server and confirm the stream keeps
|
||||||
moving.** That is the rotation path, it fires on every deploy, and a broken
|
moving.** That is the rotation path, it fires on every deploy, and a broken
|
||||||
tailer stays HTTP-200 while going silent.
|
tailer stays HTTP-200 while going silent.
|
||||||
|
|
||||||
|
### Phase 1 results (cochi, 2026-08-01)
|
||||||
|
|
||||||
|
The deploy itself exercised the rotation path: monitor came up while the old
|
||||||
|
`latest.log` still existed, Minecraft then created a new one, and the tailer
|
||||||
|
reported `rotations: 1` and kept streaming. Verified in prod:
|
||||||
|
|
||||||
|
| Check | Result |
|
||||||
|
|---|---|
|
||||||
|
| `GET /` no creds / wrong creds / right creds | 401 / 401 / 200 |
|
||||||
|
| TLS | `CN=monitor.ulicraft.net`, Let's Encrypt |
|
||||||
|
| Buffer after boot | 908 lines, `tail.ok: true` |
|
||||||
|
| Stream advancing | +109 lines in 12s, `dropped: 0`, `reset: false` |
|
||||||
|
| Rotation across the MC restart | `rotations: 1`, stream uninterrupted |
|
||||||
|
| Port 8080 from the internet | connection refused |
|
||||||
|
| `docker compose port monitor 8080` | `:0` (nothing published) |
|
||||||
|
| Host listeners on :8080 | none |
|
||||||
|
|
||||||
|
Also exercised locally before deploy, against a synthetic log: backfill capped
|
||||||
|
to buffer size, partial (unterminated) lines withheld until their newline lands,
|
||||||
|
`mv`-style rotation, in-place truncation, delete-and-recreate, ring overflow
|
||||||
|
(`dropped: 15, reset: true`), a cursor from the future, malformed `since` (400),
|
||||||
|
unknown path (404).
|
||||||
|
|
||||||
|
**Known cosmetic gap:** a rotation done as delete-then-recreate (rather than
|
||||||
|
`mv`) does not increment the `rotations` counter — the tailer takes the
|
||||||
|
"file was gone, reopen" branch instead of the rotation branch. Streaming is
|
||||||
|
unaffected; only the displayed count is.
|
||||||
Reference in new issue
Block a user