pkgproxy design: access log
The one log line pkgproxy writes per request. Part of the pkgproxy design, whose index says which file holds each § number.
23. Access log: one line per request, with an outcome
internal/reqlog logs one “handled request” line per request: method,
url, remote address, handler, outcome, status, bytes and duration.
outcome says how the request was served; handlers record it with
reqlog.SetOutcome (the last call wins), as they do handler. The values
are stable words, not translated.
hit— served from the cache without contacting the originrevalidated— the origin was consulted about a cached entry, which was then served (refreshed, or confirmed by a 304)stale— the origin could not be reached, the due-for-revalidation entry was served (also logged as a warning, with the reason)fetched— fetched from the origin, saved to the cache and servedjoined— waited for or followed another request’s fetchpassthrough— relayed from the origin, not cached (uncacheable paths, the hash-mismatch fallback)synthesised— answered by pkgproxy itself from what it recorded, because it was not contacting the origin (§11.7)tunnel— a blind CONNECT tunnelerror— the request failed;Wrapassumes this for any 4xx/5xx response nothing recorded an outcome for
A handler adds attributes of its own with reqlog.SetAttr, after the
ones above. The line is logged when the handler returns, so it covers
work done after the response was sent. A snap refresh answered online
carries assertions_fetched (how many assertions it fetched ahead,
§11.7) and
chains_incomplete (how many of the snaps it recorded still lack some):
the line appearing is how a reader, or a test, knows the fetch ahead is
over.
A response with a 5xx status is logged at error level, with the first 512
bytes of its body as response: the error text of a failed cache lookup,
or what the origin answered when its error was relayed. Only text is
logged (valid UTF-8, trimmed): a compressed body (Content-Encoding set)
or a non-text content type is skipped. A relayed origin body may contain
sensitive data, which is why the capture is limited to server errors and
to 512 bytes.
Every handler records an outcome on every path that serves an answer;
a failure it does not label is error, from Wrap. The TTL-cached
documents of the Go module proxy (list, @latest, .info) and of LXD
(the simplestreams index and product catalogs) get theirs from
revalidate.ServeDoc, which serves both. A HEAD for an uncached blob is
passthrough on the registry, which asks upstream, and synthesised on
LXD, which answers from the product catalog, and for a snap, answered
from the size the store gave. Of the requests that share
one fetch, only those that waited for another’s are joined; the one
that started it is fetched or revalidated. That holds for fills (apt
packages, registry and LXD blobs), Go .mod and .zip files and the
documents ServeDoc serves, whose shared fetches say which request
started them (internal/flight). A registry manifest’s does not yet, so
all the requests that shared one are joined.