Files
bjarneo 90ca8b5d31
Release / build (amd64, darwin, macos-latest) (push) Has been cancelled
Release / build (amd64, linux, ubuntu-latest) (push) Has been cancelled
Release / build (amd64, windows, windows-latest) (push) Has been cancelled
Release / build (arm64, darwin, macos-latest) (push) Has been cancelled
Release / build (arm64, linux, ubuntu-latest) (push) Has been cancelled
Release / release (push) Has been cancelled
Release / update-homebrew (push) Has been cancelled
File-based logging with intent-based applog facade (#192)
* feat: file-based logging with intent-based applog facade

Closes #176.

Adds a slog-backed file logger at ~/.config/cliamp/cliamp.log with a
configurable level (log_level config key, --log-level CLI flag) and
refactors applog into an intent-based facade with three tiers:

- Debug/Info/Warn/Error: file only
- Status: footer only (transient UI feedback)
- UserWarn/UserError: both file and footer

The footer ring buffer is preserved unchanged; the file sink is layered
behind an atomic.Pointer[*slog.Logger] so log calls stay lock-free.

Migrated all 11 spotify call sites: failures saving credentials and the
auth-callback server error to UserError, reconnect/rate-limit warnings
to UserWarn, 're-authenticated successfully' to Info+Status.

Plugin-side logging and log rotation deferred to follow-ups.

* docs(site): add diagnostic logging feature card

Keeps site/index.html in sync with docs/configuration.md after the
log_level config key was added in abfdc37.

* Address CodeRabbit review

- config: silently fall back to default for invalid log_level in TOML,
  matching the loader's behavior for other keys (volume, repeat, etc.)
- spotify: extract duplicate re-auth message literal into a const
- main: return applied level from initLogging so the startup log records
  the level that's actually in effect, not the raw config string

* Drop Enabled gate from UserWarn/UserError

The footer needs the formatted string regardless of file-log level, so
the gate was paying for two fmt.Sprintf sites and a branch in exchange
for skipping a sub-nanosecond slog dispatch. Diagnostic-only methods
(Debug/Info/Warn/Error/logf) keep the gate where it actually avoids the
Sprintf cost.

* applog: use t.Cleanup for test logger close

Resolves three errcheck violations from `defer closeFn()` by switching
to `t.Cleanup(func() { _ = closeFn() })`. The explicit underscore
documents the discard intent and t.Cleanup is the idiomatic place to
register test resource teardown.
2026-04-25 19:40:21 +02:00
..