Skip to content

docs: backend logging convention#100

Merged
AquiGorka merged 1 commit into
mainfrom
backend-logging-convention
May 31, 2026
Merged

docs: backend logging convention#100
AquiGorka merged 1 commit into
mainfrom
backend-logging-convention

Conversation

@AquiGorka
Copy link
Copy Markdown
Contributor

Summary

Adds logging.md — the convention every backend platform follows once the per-repo migration PRs land. Loosely ports AquiGorka/go-logger to TypeScript.

Key points the doc pins down:

  • Five-method Logger interface: info(msg), event(msg), debug(key, value), error(err, msg), scope(name). No warn / fatal / trace.
  • Levels: Debug < Info < Event < Disabled. error always emits regardless of level.
  • Scopes nest via . (log.scope("a").scope("b")main.a.b).
  • Service injection, no singletons. Constructors take { log: Logger; ... }.
  • HTTP routes are factory functions: handle<Operation>(deps): (ctx) => .... No ctx.state.log.
  • Two outputs: stdout in terse human format (colored TTY / plain otherwise), opt-in file in JSON-per-line with a stable schema.
  • Logger and OTEL stay independent. Side-by-side calls, never merged. OTEL coverage is a separate follow-up thread.
  • Migration rule: LOG.info("X", { a, b }) collapses to log.info(funcName) + log.debug("a", a) + log.debug("b", b) + log.event("X"). Existing LOG.warn splits between error and event by intent.

README's "Debugging test failures with traces" section gets a one-sentence pointer to the new doc.

Test plan

  • PM reads logging.md end-to-end and confirms the convention matches intent
  • PM merges this PR before any per-repo migration PR opens
  • Each backend's migration PR references this doc as the spec

No code in this PR — convention only. deno.json has no version field in this repo, so no patch bump.

Adds local-dev/logging.md describing the five-method Logger
(info/event/debug/error/scope), service-injection model, handle<X>(deps)
route factory pattern, and dual stdout-human / file-JSON output.

Loosely ported from github.com/AquiGorka/go-logger so behavior parallels
the Go reference. Logger and OTEL stay independent — OTEL coverage is a
follow-up thread.

README links to the new doc from the existing debugging section.
@AquiGorka AquiGorka merged commit 475d5e6 into main May 31, 2026
7 checks passed
@AquiGorka AquiGorka deleted the backend-logging-convention branch May 31, 2026 16:54
AquiGorka added a commit to Moonlight-Protocol/network-dashboard-platform that referenced this pull request May 31, 2026
## Summary

Adopts the convention defined in
[`local-dev/logging.md`](Moonlight-Protocol/local-dev#100).
First of four backend migrations (provider/council/pay are pending).

- **New Logger** at `src/utils/logger/index.ts` — TS port of
[AquiGorka/go-logger](https://github.com/AquiGorka/go-logger). Five
methods (`info`, `event`, `debug`, `error`, `scope`), four levels
(`Debug`, `Info`, `Event`, `Disabled`), nested scopes, dual stdout-human
/ file-JSON output.
- **No module-level singleton.** `src/config/logger.ts` now exports
`createLogger()`; `main.ts` is the only construction site and threads `{
log, bus }` through to every service and free function.
- **`NetworkEventBus`** becomes a DI'd class — takes `{ log }` in its
constructor, no longer exported as a singleton. The stray `console.warn`
in its `publish()` catch is now `log.error`.
- **HTTP routes** use the `handle<X>(deps)` factory pattern.
`handleNetworkWs(deps)` returns the request handler;
`buildNetworkWsRouter(deps)` and `buildApiRouter(deps)` wire it up.
- **Sync free functions** (`refreshWasmRegistry`,
`fetchCouncilTopology`, `refreshTopology`, `coldStartScan`,
`evaluateUnknownContract`, `drainPendingAdoptions`,
`startSorobanWatcher`, `startScheduler`) all take `{ log, bus }` deps
and scope internally via `log.scope("funcName")`.
- **Removed** the local `describeErr()` helper — the new Logger handles
error stringification for both human and JSON sinks via `instanceof
Error` / `safeJsonValue`.
- **Migrated all 42 LOG calls** + the one stray `console.warn` per the
convention's mapping rules.

No OTEL changes (this repo has no OTEL today).

## Logging coverage

| Subsystem | Levels emitted |
|---|---|
| HTTP routes (`handleNetworkWs`) | info, event, debug, error |
| Background services (soroban-watcher, scheduler) | info, event, debug,
error |
| External API calls (council-platform, GitHub releases, Stellar RPC) |
info, event, debug, error |
| Error paths | error |
| Bootstrap (`main.ts`) | info, event, debug, error |

## Verified locally (pre-push)

- `deno fmt --check`: clean
- `deno lint`: clean (22 files)
- `deno task test`: 17 passed, 0 failed
- `deno task check`: clean
- `grep -rn 'LOG\.(...)' src/`: 0 hits
- `grep -rn 'console\.(...)' src/`: 0 hits
- `grep -rn 'describeErr' src/`: 0 hits

## Test plan

- [ ] CI green on this branch
- [ ] PM merges PR #100 (logging convention doc) first, then this
- [ ] Smoke test locally with `LOG_LEVEL=info` via `local-dev/up.sh` to
confirm output format matches the spec

Last commit (`chore: bump version to 0.1.4`) is the patch-bump-alone
commit per the open-pr-checklist.
AquiGorka added a commit to Moonlight-Protocol/provider-platform that referenced this pull request May 31, 2026
## Summary

Adopts the convention defined in
[`local-dev/logging.md`](Moonlight-Protocol/local-dev#100).
Final repo of the 4-repo backend logging migration.

- **New Logger** at `src/utils/logger/index.ts` — TS port of
[AquiGorka/go-logger](https://github.com/AquiGorka/go-logger). Five
methods, four levels.
- **`src/config/logger.ts`** exports `createLogger()`. No singleton.
- **Service classes** (`Mempool`, `Executor`, `Verifier`,
`MetricsCollector`, `EventWatcher`, `ChannelRegistry`, `EventBus`,
`InMemorySessionManager`) take `{ log }` via constructor or
`setLogger()`.
- **HTTP handler factories**: every handler in `stellar/auth/*`,
`bundle/*`, `dashboard/*` (auth, utxos, treasury, audit-export,
transactions, pp, council, bundle-admin), `pay/*` (kyc, transactions,
self/balance, custodial/*, demo/*, escrow/*, report) becomes
`handle<X>(deps)`. Sub-routers become `build<X>Router(deps)`.
- **`appendRequestIdMiddleware`** becomes a factory.
- **`log-and-throw` helper retired** — all 10 `logAndThrow(...)` call
sites replaced with bare `throw`.
- **Free service functions** (`createDashboardChallenge`,
`verifyDashboardChallenge`, `queryBalances`, `createEscrow`,
`claimEscrowForAddress`, `getEscrowSummary`, `emit-helpers`) take deps.
- **All 163 LOG calls + 2 stray console.warn migrated.** `LOG.trace`
dropped.
- **`PLG_ProcessErrorResponse`** takes optional deps to keep pipeline
factories caller-compatible.
- **No OTEL changes** — `withSpan`, `span.addEvent`, `tracer.startSpan`
all preserved.

## Logging coverage

| Subsystem | Levels emitted |
|---|---|
| HTTP routes (stellar/auth, bundle, dashboard, pay, events, waitlist) |
info, event, debug, error |
| Background services (Mempool, Executor, Verifier, EventWatcher,
MetricsCollector) | info, event, debug, error |
| DB layer (event-driven status updates) | event, error |
| External APIs (Stellar RPC, Horizon, council-platform) | info, event,
debug, error |
| Error paths | error |

## Verified locally (pre-push)

- `deno fmt --check`: clean
- `deno lint`: clean
- `deno task test:unit`: 60 passed, 0 failed
- `deno task test:pay`: 136 passed, 0 failed
- `grep -rn 'LOG\.(...)' src/`: 0 hits
- `grep -rn 'console\.(...)' src/` (excl logger module + node_modules):
0 hits

## Test plan

- [ ] CI green
- [ ] Merge after local-dev PR #100 lands
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant