The log was text, so the Grafana dashboard picked lines apart with regular expressions, and a change of wording would have blanked its panels. With IPX_LOG_FORMAT=json each line is one JSON object: the access log carries method, path, route, status and ms as fields (the route passed from the routing layer in the response's extensions), and each wire event its ev, feed, new, downloaded, failed, bytes, msg and the rest (log_wire), beside the old message. The two startup lines that were println! are logged, so no line breaks the JSON. Text stays the default, for a terminal. The dashboard reads the fields with Loki's json parser, and groups requests by route rather than path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
34 lines
1.2 KiB
YAML
34 lines
1.2 KiB
YAML
services:
|
|
ipx:
|
|
image: 192.168.1.130:5000/ipx:latest
|
|
container_name: iPX
|
|
restart: unless-stopped
|
|
environment:
|
|
PUID: "99"
|
|
PGID: "100"
|
|
TZ: "America/Toronto"
|
|
IPX_LOG: "ipx=info"
|
|
# One JSON object a line, which Loki (through Alloy) and the Grafana dashboard read.
|
|
IPX_LOG_FORMAT: "json"
|
|
# Traces to Tempo, in the monitoring project; ipx sends none without it.
|
|
OTEL_EXPORTER_OTLP_ENDPOINT: "http://192.168.1.130:4318"
|
|
# What the dashboard filters on, so a daemon run by hand for testing stays out of it.
|
|
OTEL_RESOURCE_ATTRIBUTES: "deployment.environment.name=production"
|
|
# IPX_DATABASE_URL=postgres://... to use Postgres; without it, /data/state.db (SQLite).
|
|
env_file:
|
|
- ipx.env # relative: Arcane resolves it inside its own container
|
|
ports:
|
|
- "8099:8099" # web UI
|
|
- "6881:6881/tcp" # BitTorrent peers
|
|
- "6881:6881/udp" # DHT
|
|
volumes:
|
|
- /mnt/fast/appdata/ipx:/config # config.toml, and the web token
|
|
- /mnt/user/ipx/:/data # state.db
|
|
- /mnt/user/ipx/downloads:/downloads
|
|
healthcheck:
|
|
test: ["CMD", "ipx", "status"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
start_period: 10s
|