Document the periodic log review, in both directions - #47
Merged
Conversation
Real traffic is the only source that finds what every check here is blind to. The URL contract proves the 328 URLs someone thought to list and the 917 redirects derived from the export, and it cannot know about a URL nobody recorded, because the crawl that produced the lists is the crawl the lists are checked against. A visitor following a sixteen-year-old link is the one reader who tests that. This was discussed when the migration was designed and had survived only as a one-line first-week task, which is not a periodic process. Both directions are recorded, because they are the same two the media checks read and they are blind to each other for the same reason. Outward finds a non-200 and names content that may be missing, which is the one with an action: add the URL to the golden list and add a redirect. Inward subtracts every URL that has ever answered 200 from the set the site builds, and names content no reader has reached. That one is deliberately slow, since a post can go a year without a visit and still be worth keeping, and its first concrete use is the 97 carried media files the old platform never published: if nothing requests them across a year, that settles whether carrying them is preservation or clutter, which no reasoning from this repo can settle. The three tiers are named, because a request crosses the proxy before it reaches the site and no single log answers both questions. Traefik, and Pangolin's Traefik on the VPS, see every request reaching the host including the ones aimed at names this site does not serve. Pangolin sees what the auth gate rejected. Caddy sees only what arrived. So a 404 count taken from Caddy alone is a floor rather than a total, since a request the edge refused is a reader who found nothing just as surely and appears in no Caddy log. Two parsing properties are stated because both silently produce nothing. The Caddy access log is `format console`, so a line is a timestamp, a level, and a logger name followed by a JSON object rather than being JSON, and a parser assuming one object per line reads zero records. And `trusted_proxies` is what makes `client_ip` the reader rather than the proxy, without which every request appears to come from one internal address. Retention is recorded as the unconfigured prerequisite it is. The containers use Docker's `json-file` driver with no rotation and no size limit, so the log grows without bound and is discarded when the container is recreated. The first is a disk risk and the second silently resets the window the inward pass depends on being long. It belongs to the host rather than to this repo, the same split Retention and Who Owns What already describe for release pruning, so it is recorded and dated to the cutover rather than changed here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR documents the periodic log review process (both “outward” and “inward” directions) as an operational procedure, capturing post-migration practices and constraints that aren’t enforceable via the repository’s automated URL checks.
Changes:
- Adds an
OPERATIONS.md“Log Review” section describing the two-direction review, the three logging tiers, parsing pitfalls, and why Caddy-only counts underreport. - Updates
TODO.mdto record the log-retention prerequisite and to point readers to the new operational procedure for ongoing review cadence and interpretation.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| TODO.md | Records the retention prerequisite and references the documented periodic log review procedure. |
| OPERATIONS.md | Introduces a “Log Review” section defining process, tiers, pitfalls, and retention constraints. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Captures a design decision from the migration that had survived only as a one-line first-week task, which is not a periodic process.
Why
Real traffic is the only source that finds what every check here is blind to. The URL contract proves the 328 URLs someone thought to list and the 917 redirects derived from the export. It cannot know about a URL nobody recorded, because the crawl that produced the lists is the crawl the lists are checked against. A visitor following a sixteen-year-old link is the one reader who tests that.
Both directions, because they are blind to each other
The same two the media checks read, for the same reason:
Outward is the one with an action — add the URL to
checks/golden-urls.txt, add a redirect. Expect the raw counts to be dominated by scanners probingwp-login.phpand.env, which is noise from a site that used to run WordPress.Inward answers a question nothing else can, and it has an immediate concrete use: the 97 carried media files the old platform never published. If nothing requests them across a year, that settles whether carrying them is preservation or clutter — and no reasoning from this repository can settle it.
Three tiers, each blind to something
A request crosses the proxy before it reaches the site, so no single log answers both questions:
X-Blog-Releasethat answeredA 404 count from Caddy alone is a floor, not a total. A request the edge refused is a reader who found nothing just as surely, and it appears in no Caddy log.
Two parsing traps, both of which silently yield nothing
format console— a line is a timestamp, level, and logger name followed by a JSON object rather than being JSON. A parser assuming one object per line reads zero records.trusted_proxiesis what makesclient_ipthe reader rather than the proxy. Without it every request appears to come from one internal address and the inward pass cannot tell a reader from a health check.Retention is the prerequisite, and it is not configured
The containers use Docker's
json-filedriver with no rotation and no size limit —/etc/docker/daemon.jsonsets only a storage driver, so built-in defaults apply. The log grows without bound, and is discarded entirely when the container is recreated. The first is a disk risk on a VPS; the second silently resets the window the inward pass depends on being long.Nothing here fixes it, because the log driver belongs to the host rather than to this repository — the same split
RetentionandWho Owns Whatalready describe for release pruning. It is recorded inTODO.mdand dated to the cutover, since a review reads whatever survived and reports confidently on it either way.Verification
Documentation only. markdownlint and editorconfig-checker clean; no code, config, workflow, or content change, so the build and URL contract are untouched.
The claims about the running system were checked rather than assumed: the
logdirective andformat consoleindeploy/Caddyfile, the containers' actual access-log output, thejson-filedriver with empty options, and/etc/docker/daemon.jsoncarrying onlystorage-driver. The VPS tiers are described fromOPERATIONS.md's existing environment table rather than from access I do not have, and the text says which is which.🤖 Generated with Claude Code