Documentation
Site access log
Each site can record an HTTP access log. It's off by default; when you turn it on, every request to the site is captured as a JSONL entry and committed to a dedicated git store. The design keeps commits in the low single digits per day for typical sites, so the log repo doesn't balloon.
Turning it on
/site log enable my-wiki
This:
- creates a new store named
my-wiki-logs(always derived from the site's content store name — there is no separatestore=setting for the log) - starts the writer hot, without a backend restart
- begins capturing requests immediately
Turning it back off keeps the existing log store intact for the record:
/site log disable my-wiki
Tuning
/site log set my-wiki flush_interval=2m
/site log set my-wiki flush_max_bytes=524288
/site log set my-wiki flush_max_entries=2000
Defaults: flush every 5 minutes, or when the buffer reaches 256 KiB / 1000
entries (whichever fires first), or on shutdown. There's also a
buffer_hard_cap safety ceiling (1 MiB by default) — if it's reached, the
writer logs a backpressure warning and forces an emergency flush.
Inspecting
/site log status my-wiki
Shows:
- whether logging is enabled
- the derived log store name
- how many bytes / entries are buffered right now
- the dropped-entry counter (incremented when the channel is full)
- the timestamp of the last successful flush
- the last error, if any
/site log tail my-wiki 100
Prints the last 100 lines from the most recent day file(s). Each line is validated; lines with an unknown schema version are reported with their file path and line number, but the rest of the file is still readable.
What gets captured
One JSON object per line. Field order is fixed:
{"v":1,"ts":"2026-06-04T14:32:11.482Z","site":"my-wiki","host":"wiki.localhost","method":"GET","path":"/posts/hello","status":200,"bytes":4821,"ip":"203.0.113.7","ref":"https://duckduckgo.com/","ua":"Mozilla/5.0 ...","dur_ms":12}
tsis UTC with millisecond precision.pathincludes the query string. Sensitive query params (password,token,code,state,secret) have their values redacted as***.bytesis the response body size in bytes (excluding headers),0forHEAD/204/304.ipis the first entry ofX-Forwarded-Forif present (trusted unconditionally — Everlock assumes a controlled frontend), otherwise the socket peer address. Omitted when neither is available.dur_msis wall-clock time from the body wrapper attaching to response completion.- WebSocket upgrades (status
101) are not logged.
File layout
The log store is a normal git repo:
my-wiki-logs/
2026/
2026-06-04.jsonl
2026-06-03.jsonl
2025/
2025-12-31.jsonl
README.md
One file per UTC day, grouped by year. Each daily file contains only
entries whose ts falls within that day — the first flush after midnight
emits two commits: a final append to yesterday's file for the 23:59
stragglers, then a normal append to today's file.
Reading the log
The files are plain UTF-8 JSONL, so:
jq 'select(.status==404)' 2026-06-04.jsonl
grep '"status":404' 2026-06-04.jsonl
jq -r '[.ts, .ip, .method, .path, .status] | @tsv' 2026-06-04.jsonl
git log on the log store shows the flush history, which is useful for
verifying that retention or pruning policies are working.
Why a separate store
Logs live in <site-store>-logs, never in the content store itself.
Reasons:
- the content repo's
git logkeeps telling the story of edits, not traffic - log retention can differ from content retention (e.g. prune after 90 days)
- the site can be public while the log store stays private
- one fewer name to invent — the log store name is always derived
Failure handling
The request path is never blocked by logging:
- if the in-memory channel is full, entries are dropped (rate-limited
warning, dropped count visible in
/site log status) - if
store.writeto the log store fails (disk full, git lock stuck, etc.), the writer drops the pending buffer with a rate-limited warning and keeps going — no auto-disable, no retry queue, and the site itself keeps serving requests normally
See also
- Site backend reference — the backend description, including the full design rationale and schema-evolution rules
- Admin commands — the full
/site logcommand surface