Skip to content

feat: route all logging through a structured pino logger - #402

Open
aliyuHabibu wants to merge 1 commit into
Divinity-Labs:mainfrom
aliyuHabibu:feat/structured-logging
Open

aliyuHabibu wants to merge 1 commit into
Divinity-Labs:mainfrom
aliyuHabibu:feat/structured-logging

Conversation

@aliyuHabibu

Copy link
Copy Markdown

Every module now logs through a component-scoped pino child (ingester:sdex, job:aggregate-refresh, ws:fanout, redis, config, webhook, route:price, startup) instead of console.*, emitted as a structured component field rather than a message prefix. Fastify's request logger is built from the same options so req.log is scrubbed and formatted identically.

The level is configurable via LOG_LEVEL (default info, documented in .env.example): NDJSON when NODE_ENV=production, human-readable otherwise. Values of secret-looking env vars (DATABASE_URL, DIRECT_DATABASE_URL, REDIS_URL, and any name containing KEY/SECRET/TOKEN/PASSWORD) are scrubbed from every serialized line, including the password inside a connection string and driver error messages that echo it, while auth headers are redacted via pino redact.

Adds a test asserting no console.* survives in non-test source and that a connection string or API key value never reaches the output.

Summary

Type of change

  • Bug fix
  • New feature
  • Refactor
  • Docs
  • Tests
  • CI / tooling

Checklist

  • I have read CONTRIBUTING.md
  • npx tsc --noEmit passes
  • npm run build passes
  • I added / updated tests where relevant
  • I updated docs where relevant

Close #332

Every module now logs through a component-scoped pino child
(ingester:sdex, job:aggregate-refresh, ws:fanout, redis, config,
webhook, route:price, startup) instead of console.*, emitted as a
structured `component` field rather than a message prefix. Fastify's
request logger is built from the same options so req.log is scrubbed
and formatted identically.

The level is configurable via LOG_LEVEL (default info, documented in
.env.example): NDJSON when NODE_ENV=production, human-readable
otherwise. Values of secret-looking env vars (DATABASE_URL,
DIRECT_DATABASE_URL, REDIS_URL, and any name containing
KEY/SECRET/TOKEN/PASSWORD) are scrubbed from every serialized line,
including the password inside a connection string and driver error
messages that echo it, while auth headers are redacted via pino redact.

Adds a test asserting no console.* survives in non-test source and that
a connection string or API key value never reaches the output.
@drips-wave

drips-wave Bot commented Oct 17, 2026

Copy link
Copy Markdown

@aliyuHabibu Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Miracle656

Copy link
Copy Markdown
Collaborator

This is the one I want for #278 — pino rather than a hand-rolled wrapper, component children instead of message prefixes, a configurable LOG_LEVEL, scrubbing, and Fastify's request logger built from the same options so req.log and application logs match. That last detail is the one most implementations skip and then wonder why half the output looks different.

It conflicts now — main has moved six times this morning (#379, #380, #382, #392, #401, #310). Please rebase and I will review it properly straight away; it is next in my queue.

Heads-up on sequencing: #397 independently added a src/logging.ts with a logEvent() helper over console.*, and docs/logging.md documenting it. I have asked that author to rebase onto yours and re-express their field set as pino calls, since yours is what the issue asked for. Their fields for ingestion failures — venue, network, pair, attempt, retryMs, durationMs — are genuinely good and worth keeping when they come across, so expect a small follow-up on top of this rather than a competing change.

@Miracle656

Copy link
Copy Markdown
Collaborator

Needs a rebase — main moved six times this morning (#379, #380, #382, #392, #401, #310 all landed) and this now conflicts. Push a rebase and I will pick it up; nothing is queued ahead of it.

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.

Sixty-five console calls and no structured logger

2 participants