v1.4 - Access Logging & Chunked Transfer Encoding (2026-04-12)
π New Features
- JSON Access Log: Per-request access log written as NDJSON (one JSON object per line) via the
ACCESS_LOG_FILE_JSONenvironment variable. Captures timestamp, method, path, client IP, HTTP status, duration, service, parsed parameters, upstream target URL, response bytes, and cache status (HIT/MISS/DISABLED). Ideal for feeding into log aggregators or graphing tools. - Plain-Text Access Log: Human-readable single-line access log via the
ACCESS_LOG_FILE_TEXTenvironment variable. Format:[TIMESTAMP] STATUS METHOD PATH IP BYTESb DURATIONms cache=CACHE service=SERVICE target=URL. Ideal for quickgrep/tailinspection. - Dual Access Logging: Both log formats are fully independent and can be enabled simultaneously.
- Chunked Transfer Encoding: Stream large files in configurable chunks using
|chunked_size:BYTESin URL patterns. Reduces memory pressure and improves performance for large file downloads. Works with both cached and freshly fetched responses.
π οΈ Improvements
- Richer Cache Metadata: Cache
.metafiles now store the original proxied URL (proxiedUrl), the client request URL (requestUrl), and the full set of upstream response headers (originalHeaders) for improved debugging and cache introspection. - Automatic Log Directory Creation: Access log directories are created automatically on startup if they do not exist.
X-Forwarded-ForSupport: Client IP in access logs correctly uses theX-Forwarded-Forheader when the proxy is behind a load balancer or reverse proxy.
π Examples
JSON access log line:
{"timestamp":"2026-04-12T16:48:11.710Z","method":"GET","path":"/service/github/1.14/Bruce-CYD-2432S028.bin","ip":"192.168.1.10","status":200,"durationMs":234,"service":"github","params":{"1":"1.14","2":"Bruce-CYD-2432S028.bin"},"targetUrl":"https://github.com/owner/repo/releases/download/1.14/Bruce-CYD-2432S028.bin","bytes":123456,"cache":"MISS"}Plain-text access log line:
[2026-04-12T16:48:11.710Z] 200 GET /service/github/1.14/Bruce-CYD-2432S028.bin 192.168.1.10 123456B 234ms cache=MISS service=github target=https://github.com/owner/repo/releases/download/1.14/Bruce-CYD-2432S028.bin
Chunked transfer encoding:
URL_PATTERNS="downloads=https://cdn.example.com/{1}|cache:3600|chunked_size:32768"Docker Compose with both access logs:
environment:
ACCESS_LOG_FILE_JSON: /logs/access.log
ACCESS_LOG_FILE_TEXT: /logs/access.txt
volumes:
- ./logs:/logsUseful jq queries on the JSON log:
# Download count per filename
jq -r '.params["2"]' access.log | sort | uniq -c | sort -rn
# Total bytes served
jq -r '.bytes' access.log | awk '{s+=$1} END {print s}'
# Cache hit rate
jq -r '.cache' access.log | sort | uniq -cπ Technical Notes
- Access log streams are opened in append mode (
a) at startup; any missing parent directories are created automatically - Stream write errors are reported to the application log without crashing the server
- Chunked responses use
setImmediatebetween chunks to avoid blocking the event loop - The
chunked_sizeflag is stripped from the URL pattern before upstream URL construction (alongside the existingcacheflag) - Cache metadata schema extended: existing
.metafiles written by v1.3.0 remain readable; new fields (proxiedUrl,requestUrl,originalHeaders) default gracefully when absent
Full Changelog: 1.3...1.4