Interpolate log fields instead of passing an object #107

Merged
padreug merged 1 commit from fix/renderer-log-object-args into dev 2026-09-24 07:31:55 +00:00
3 changed files with 7 additions and 3 deletions

View file

@ -219,6 +219,7 @@ UP Board enumerates its eMMC controller via ACPI, not PCI. `upboard.nix` force-l
## Useful invariants when debugging ## Useful invariants when debugging
- The renderer logs prefix every line with a tag: `[Lightning]`, `[ATM]`, `[ATM Service]`, `[LNURL Session]`, `[CLINK]`, `[StateStore]`. `journalctl -u bitspire | grep '\['` is your friend. - The renderer logs prefix every line with a tag: `[Lightning]`, `[ATM]`, `[ATM Service]`, `[LNURL Session]`, `[CLINK]`, `[StateStore]`. `journalctl -u bitspire | grep '\['` is your friend.
- **Never pass an object as a console argument in the renderer.** Electron's console bridge stringifies each argument, so `console.log('msg:', { a, b })` reaches the journal as `msg: [object Object]` and every field is lost. Interpolate instead. Cost a debugging session on 2026-09-23, when a cassette publish that had worked looked like it had done nothing.
- `bitspire.service` runs as the `lamassu` user; `/var/lib/bitspire` is its `dataDir` (ReadWritePaths). DB lives at `/var/lib/bitspire/state.db` (we previously had `/var/lib/lamassu-atm` — that path is gone on dev, see commit `9c455d6`). - `bitspire.service` runs as the `lamassu` user; `/var/lib/bitspire` is its `dataDir` (ReadWritePaths). DB lives at `/var/lib/bitspire/state.db` (we previously had `/var/lib/lamassu-atm` — that path is gone on dev, see commit `9c455d6`).
- The `lightning.lightningPub` field on `LightningServices` is a `LightningBackend` *adapter*, not a `LightningPubClient`. Don't try to call LP-only methods on it. - The `lightning.lightningPub` field on `LightningServices` is a `LightningBackend` *adapter*, not a `LightningPubClient`. Don't try to call LP-only methods on it.

View file

@ -147,7 +147,7 @@ export async function startOperatorConfigService(
}, },
} }
) )
console.log('[OperatorConfig] Subscribed:', { dTag, subscriptionId }) console.log(`[OperatorConfig] Subscribed: d=${dTag} sub=${subscriptionId}`)
const heartbeat = setInterval(() => { const heartbeat = setInterval(() => {
publishCassettesState(cfg, api, machineId).catch((err) => publishCassettesState(cfg, api, machineId).catch((err) =>
@ -342,6 +342,9 @@ async function publishCassettesState(
await cfg.nostrClient.publish(event) await cfg.nostrClient.publish(event)
await api.markStatePublished(createdAt) await api.markStatePublished(createdAt)
console.log('[OperatorConfig] cassettes-state published:', { dTag, eventId: event.id, createdAt }) console.log(
`[OperatorConfig] cassettes-state published: id=${event.id.slice(0, 12)}… ` +
`created_at=${createdAt} seq=${seq} applied_ops=${appliedOps.length} d=${dTag}`
)
return true return true
} }

View file

@ -132,7 +132,7 @@ export async function startOperatorFeesService(
}, },
} }
) )
console.log('[Fees] Subscribed:', { dTag, subscriptionId }) console.log(`[Fees] Subscribed: d=${dTag} sub=${subscriptionId}`)
return { return {
stop: () => cfg.nostrClient.unsubscribe(subscriptionId), stop: () => cfg.nostrClient.unsubscribe(subscriptionId),