mirror of
https://github.com/Routstr/routstrd.git
synced 2026-10-30 07:37:40 +00:00
A scheduled refresh runs every 21 minutes and most of what it printed was
identical every pass. On a real daemon (20,746 log lines/day) the refresh block
was ~10% of the file: four INFO phase lines per pass plus one WARN per
unreachable provider, with the same 26-provider failure set repeated across
consecutive passes.
Three changes, one per source of noise:
1. `ROUTSTRD_LOG_LEVEL` (default `info`) makes the level meaningful. `writeLog`
wrote every level unconditionally, so the SDK's `debug` channel was not
actually filterable — which is what blocked moving recurring detail down a
level. `ROUTSTRD_LOG_LEVEL=debug` restores everything; an unparseable value
falls back to the default instead of muting the log. `error` is never
suppressed. The Cashu wallet-engine sink keeps `debug` under its own
`ROUTSTRD_COCO_LOG_LEVEL`, because it is ~87% debug by design and an explicit
`ROUTSTRD_LOG_LEVEL=info` must not silently drop wallet detail.
2. The refresh pass collapses into one line:
[INFO] Scheduled refresh: 214 models, 3 client integration(s) in 33.4s
The phase markers ("Running scheduled Nostr event refresh...", "Running
scheduled model refresh...", "Refreshing 3 client integration(s)...", "Client
integrations refreshed.") move to `debug`. The caller owns the line and
measures the whole pass (Nostr events + models + integrations), so
`refreshModelsAndIntegrations` now returns a result instead of logging.
Integration failures are counted into the line, and `runIntegrationsForClients`
reports them via `logger.error` instead of `console.error` so they land in the
dated log with a level.
3. `Using existing API key for <client>` moves to `debug`. That is the steady
state for an already-configured client, and the `*/5 * * * * routstrd clients
add --pi-agent` cron printed it 290 times/day. `Created new API key` stays at
`info`.
The provider warnings themselves still come from @routstr/sdk 0.4.9 one per
provider; Routstr/routstr-sdk#89 replaces them with a transition-based summary,
and this level filter is what lets that detail stay available at `debug`.
Nothing parsed these strings: `routstrd logs` only tails and filters lines by
request id.
Tests: src/utils/logger.test.ts (level parsing, filtering, argument passthrough,
error never suppressed) and src/integrations/index.test.ts (summary formatting).
Verified end-to-end against a temp ROUTSTRD_DIR that each level writes exactly
the expected lines.
67 lines
2.8 KiB
Markdown
67 lines
2.8 KiB
Markdown
# Logging
|
|
|
|
The daemon appends to dated files under `~/.routstrd/logs/<YYYY-MM-DD>.log`
|
|
(one per local day) and to `~/.routstrd/coco-logs/` for Cashu wallet-engine
|
|
diagnostics. Writes are synchronous on purpose: the daemon calls
|
|
`process.exit()` right after `logger.error(...)` on fatal paths, and async
|
|
writes were silently dropped, making startup failures invisible.
|
|
|
|
## Levels
|
|
|
|
`ROUTSTRD_LOG_LEVEL` sets the **minimum** level written to disk:
|
|
|
|
| Value | Written |
|
|
| --- | --- |
|
|
| `debug` | everything, including per-provider and per-pass diagnostics |
|
|
| `info` *(default)* | `info`, `warn`, `error` |
|
|
| `warn` | `warn`, `error` |
|
|
| `error` | `error` |
|
|
|
|
An unparseable value falls back to `info` rather than muting the log.
|
|
|
|
The daemon repeats work on timers, so anything that would otherwise print once
|
|
per pass is emitted at `debug` and summarized into a single `info` line. A
|
|
scheduled refresh therefore costs **one line** by default:
|
|
|
|
```
|
|
[2026-10-05T15:42:27.044Z] [INFO] Scheduled refresh: 214 models, 3 client integration(s) in 33.4s
|
|
```
|
|
|
|
Set `ROUTSTRD_LOG_LEVEL=debug` to see the phases (`Running scheduled model
|
|
refresh...`), the per-provider detail behind a failure summary, and the
|
|
Nostr-discovery markers. The daemon inherits the variable from whatever starts
|
|
it (`routstrd start`, pm2, systemd), so set it there, not per request.
|
|
|
|
`coco-logs` is the Cashu wallet-engine sink and writes `debug` regardless of
|
|
`ROUTSTRD_LOG_LEVEL`, because those diagnostics are verbose by design (roughly
|
|
87% of those lines are `debug`) and live in their own directory precisely so
|
|
they stay out of the main log. `ROUTSTRD_COCO_LOG_LEVEL` is its own knob, using
|
|
the same values, if you do want it quieter (it is ~19k lines/day on a busy
|
|
daemon).
|
|
|
|
## What a healthy pass looks like
|
|
|
|
```
|
|
$ ROUTSTRD_LOG_LEVEL=info
|
|
[INFO] Routstr daemon listening on http://127.0.0.1:8008/v1
|
|
[INFO] Initial refresh: 214 models, 3 client integration(s) in 41.2s
|
|
[INFO] Model refresh: 32/58 providers ok, 26 unavailable (0 new, 26 unchanged) in 9.8s — maebarai.xyz(530), api.voltai.top(connect), +20 more
|
|
[INFO] Scheduled refresh: 214 models, 3 client integration(s) in 33.4s
|
|
```
|
|
|
|
The `Model refresh:` line comes from the SDK (`@routstr/sdk`): it reports
|
|
reachability as state *transitions* plus one bounded summary, so a provider that
|
|
has been down for days is a count, not a repeated warning. A provider that newly
|
|
fails — or starts failing differently — still gets its own `[WARN] Provider
|
|
<url> unreachable: ...` line, so anything worth alerting on stays greppable.
|
|
|
|
## Inspecting
|
|
|
|
```sh
|
|
routstrd logs -n 50 # last 50 lines
|
|
routstrd logs -f # follow (from debug.log, the daemon's stdout)
|
|
routstrd logs -c # Cashu wallet-engine log instead
|
|
ROUTSTRD_LOG_LEVEL=debug routstrd start
|
|
ROUTSTRD_COCO_LOG_LEVEL=info routstrd start
|
|
```
|