diff --git a/MANUAL.html b/MANUAL.html index c8386e7..89f1235 100644 --- a/MANUAL.html +++ b/MANUAL.html @@ -505,19 +505,19 @@ old.broadcast.tvrip.tt0066026.mkv

08 — Observability

Logs

-

Three log files are written to the current working directory (not the config paths):

+

All logs are written to a SQLite database, logs.db, in the current working directory (not the config paths). Run the program from where you want it to land — in Docker that's the mounted /data. The logs table has columns id, ts, level, message, file, extra.

- + - - - + + +
FileContents
LevelWhereContents
info_YYYY-MM-DD.logINFO messages, dated
error_YYYY-MM-DD.logERROR messages, dated
structured.jsonOne JSON object per line — every entry, with timestamp, level, message, optional error & file
infodb + stdoutProcessing / metadata hits / completions
errordb + stderrFailures, with the source file recorded
debugdb onlyffprobe output, zscale width, full ffmpeg/opusenc command, OMDb/TVmaze responses (API key redacted) in extra
-

Run the program from the directory where you want the logs to land. A number of DEBUG lines also print to stdout/stderr (ffprobe output, calculated zscale width, the full ffmpeg command) — intentional, but not written to the log files.

-
Known limitation

The date in info_*.log / error_*.log filenames is computed at daemon start and does not roll over at midnight. Left running across days, all writes continue into the start-day's file — restart to rotate. structured.json does not rotate at all.

+

Live encode progress (encoding … · 47% · 3.2fps · …) prints to stdout only and is deliberately not stored, so it can't flood the database.

+
Retention

Rows older than log_retention_days (default 7) are purged on startup and shutdown. Editable live from the settings page (/settings); applies at the next purge. Recent non-debug events are viewable in the dashboard and via GET /status when http_addr is set.

@@ -527,7 +527,7 @@ old.broadcast.tvrip.tt0066026.mkv

The watcher continues with the next file; one bad rip won't stop the daemon.

Collisions

If a finished encode would land on a name that already exists in paths.output, the move is refused (no silent overwrite) and the source is routed to paths.failed. This is the path you hit when two sources sanitize to the same name — two re-rips of the same release, or two episodes that both resolve to SxxExx.

diff --git a/MANUAL.md b/MANUAL.md index 409a2ff..570fc55 100644 --- a/MANUAL.md +++ b/MANUAL.md @@ -225,17 +225,19 @@ A few things worth knowing: ## 8. Logs -Three log files are written to the **current working directory** (not the config paths): +All logs are written to a **SQLite database, `logs.db`**, in the current working directory (not the config paths). Run the program from the directory where you want it to land — in Docker that's the mounted `/data`. -- `info_YYYY-MM-DD.log` — INFO messages, dated. -- `error_YYYY-MM-DD.log` — ERROR messages, dated. -- `structured.json` — one JSON object per line, every entry (info + error), with `timestamp`, `level`, `message`, optional `error` and `file` fields. +The `logs` table has columns `id`, `ts`, `level`, `message`, `file`, `extra`. Three levels are recorded: -Run the program from the directory where you want the logs to land. +- `info` — INFO messages; also printed to stdout. +- `error` — ERROR messages; also printed to stderr, with the source `file` recorded. +- `debug` — verbose diagnostics (ffprobe output, calculated zscale width, the full ffmpeg/opusenc command, OMDb/TVmaze responses with the API key redacted) in the `extra` column. **Database only** — not printed. -Note: a number of `DEBUG` lines are printed to stdout/stderr (ffprobe output, calculated zscale width, the full ffmpeg command, etc.). These are intentional but not written to the log files. +Live encode progress (`encoding … · 47% · 3.2fps · …`) prints to **stdout only** and is deliberately *not* stored, so it can't flood the database. -**Known limitation:** the date in `info_*.log` / `error_*.log` filenames is computed when the daemon starts and does not roll over at midnight. If the daemon is left running across days, all writes continue into the start-day's file. Restart the daemon to rotate. `structured.json` does not rotate at all. +**Retention:** rows older than `log_retention_days` (default `7`) are purged on startup and on shutdown. The value is editable live from the settings page (`/settings`) and applies at the next purge. + +Recent non-debug events are also viewable in the web dashboard and via `GET /status` (when `http_addr` is set). --- @@ -245,7 +247,7 @@ If any step from probing through encoding through renaming fails: - The source `.mkv` is moved to `paths.failed` (the move itself is `os.Stat`-guarded — if the source is already gone, the move is skipped and logged; if the move itself errors, that error is logged too). This guarantees the source leaves `paths.input` on every failure path, so the watcher doesn't retry the same file on the next tick. - The per-job work directory under `paths.work` (containing partial wav/opus/output.mkv) is deleted unconditionally. -- The error is logged to `error_*.log` and `structured.json` with the source file path. +- The error is logged to `logs.db` (level `error`) with the source file path, and printed to stderr. The watcher continues with the next file; one bad rip won't stop the daemon. diff --git a/SPEC.md b/SPEC.md index 753523c..42a5c97 100644 --- a/SPEC.md +++ b/SPEC.md @@ -99,9 +99,10 @@ Regex patterns: ## Logging -- info.log: Human-readable info level -- error.log: Human-readable error level -- structured.json: JSON structured logs +- All logs are stored in a SQLite database `logs.db` in the working directory. +- Levels: `debug`, `info`, `error`. `info`/`error` also print to stdout/stderr; `debug` (ffprobe/ffmpeg/API dumps) is database-only. Live encode progress prints to stdout only (not stored). +- Retention: rows older than `log_retention_days` (default 7) are purged on startup/shutdown; editable from the settings UI. +- Recent non-debug events are viewable in the web dashboard and via `GET /status`. ## Polling - Scan input folder every 10-30 seconds for `.mkv` files