diff --git a/CHANGELOG.md b/CHANGELOG.md index 24ed5524..88c964c4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The Docker Hub repository description is published from `README.md` on each stable release. +- The support documentation describes the log format, the level abbreviations + and how to read the logs. + +### Changed + +- The container prints six lines when it starts, instead of twenty-three. + +- Nginx request errors now appear in `docker logs`, and Nginx no longer writes + an access log to a file inside the container that nothing rotated. + +- A misconfigured `TRUST_PROXY` produces one short warning instead of two long + ones. + ### Fixed - The Books, Now Playing and Backup widgets now show why they failed, such as a @@ -20,12 +33,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The last visible row in a Settings group no longer draws a separator under itself, which showed under Password Protection whenever protection was off. +- The startup banner no longer prints a Web UI address that pointed at the + internal API port and worked for nobody. + ### Security - A Connections tile that cannot reach a service now says so in plain words instead of printing the address it tried, which put an internal host and port on the dashboard. +- A failed connection test no longer writes the request path to the log, where + a service that carries its API key in the path would have left it. + ## [1.5.2] - 2026-08-09 ### Changed diff --git a/docker-compose.yml b/docker-compose.yml index eb28ee63..6fe48ac1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -53,8 +53,9 @@ services: # - PASSWORD_HASH_MEMORY=64mib # Set to true to allow widget URLs using private/LAN IP addresses # - ALLOW_PRIVATE_IPS=true - # Log verbosity: debug, info, warn or error. Settings, General sets this - # too, and that wins once the config has loaded. + # Log verbosity: debug, info, warn or error, where warn and error behave + # the same. Settings, General sets this too, and that wins once the config + # has loaded. # - LOG_LEVEL=info # Where the widget folders are read from. Only if you have moved them. # - WIDGETS_PATH=/usr/share/nginx/html/widgets diff --git a/docs/architecture.md b/docs/architecture.md index d2ae8619..38cb8489 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -36,7 +36,7 @@ Everything is optional; the defaults are what the container ships with. | `ICONS_PATH` | `/icons` | Where uploaded icons are written. | | `WIDGETS_PATH` | `/usr/share/nginx/html/widgets` | Where the widget folders are read from. Point it elsewhere only if you have moved them; a wrong path loads an empty registry, and every widget then reports as unknown. | | `PORT` | `3000` | The port the API listens on. nginx proxies to it, so changing it means changing `nginx/dashboard.conf` too. | -| `LOG_LEVEL` | `info` | `debug`, `info`, `warn` or `error`. Settings, General also sets this, and that setting wins from the moment the config loads; the variable is what applies during boot and if no setting is stored. | +| `LOG_LEVEL` | `info` | `debug`, `info`, `warn` or `error`, where `warn` and `error` behave the same: both show warnings and errors. Settings, General also sets this, and that setting wins from the moment the config loads; the variable is what applies during boot and if no setting is stored. | | `APP_VERSION` | the version in `package.json` | What the update check compares against. The release build stamps it, so leave it alone outside a build. | | `TRUST_PROXY` | unset | Believe `X-Forwarded-Proto`, so a request through a TLS-terminating proxy gets a `Secure` cookie. Only behind a proxy you control. See [security.md](./security.md#https-and-the-session-cookie). | | `TRUSTED_PROXY` | unset | Where a front proxy sits, so nginx can resolve the real client for rate limiting. See [security.md](./security.md#authentication). | diff --git a/docs/support.md b/docs/support.md index d867b911..f188d513 100644 --- a/docs/support.md +++ b/docs/support.md @@ -17,7 +17,8 @@ Redact secrets before pasting logs or config. ## Reading the logs -Both Nginx and the API log to the container's stdout: +The API logs to the container's stdout. Nginx logs request errors to stderr and +keeps no access log, so both reach the same place: ``` docker logs @@ -31,7 +32,33 @@ docker compose logs -f In Portainer, open the container and use the **Logs** view. -The API logs `key=value` pairs; errors carry an `error=` field. +### What a log line looks like + +Every API record is one line: + +``` + msg= key=value +``` + +`LVL` is one of `DBG`, `INF`, `WRN`, `ERR` or `AUD`. `AUD` marks a +security-relevant event and is never filtered by the level setting. + +A few things worth knowing when reading them: + +- Warnings are emitted at both `warn` and `error`, so choosing Errors in + Settings still shows them. +- The startup banner is not a record. It has no timestamp and no level, and it + always prints. +- Secrets are never logged. Values that could carry one, such as the address of + a service that failed a connection test, are reduced to the host. +- Lines from supervisord and Nginx have their own shapes and are not Stackyard + records. + +The format is logfmt, so anything shipping to Loki or Grafana parses it with +`| logfmt` and no custom rules. + +To change how much is logged, see the `LOG_LEVEL` row in +[architecture.md](architecture.md#environment). ## Common problems