Skip to content

feat(backend): replace console.log/console.error with pino logger - #913

Open
scarface-dev1 wants to merge 1 commit into
ritik4ever:mainfrom
scarface-dev1:feat/structured-logging-pino-replace-console
Open

feat(backend): replace console.log/console.error with pino logger#913
scarface-dev1 wants to merge 1 commit into
ritik4ever:mainfrom
scarface-dev1:feat/structured-logging-pino-replace-console

Conversation

@scarface-dev1

Copy link
Copy Markdown

What it fixes

Completes the structured logging migration by replacing all remaining console.log / console.error calls with the pino logger, as requested in #718.

Root cause

The backend already had a pino logger (backend/src/logger.ts) with JSON output in production, pretty-printing in development, LOG_LEVEL control, redaction of sensitive fields (Stellar secret keys), and automatic correlation ID injection via AsyncLocalStorage. The requestLogger middleware already logged every request with method, route, statusCode, durationMs, and correlation_id. However, three locations still used raw console.log / console.error:

  1. validateEnv.ts — Two console.error calls for STELLAR_CONTRACT_ID validation failures bypassed the structured logger, meaning these errors were not JSON-formatted in production, had no correlation ID, and were not subject to pino's redaction pipeline.
  2. 0002_add_stream_indexes.ts — A console.log in the migration file triggered ESLint's no-console rule and did not use structured output.
  3. services/db.ts — A console.error inside a PostgreSQL worker thread string literal (running in a Worker with no access to the main process pino logger).

The fix

backend/src/config/validateEnv.ts

Replaced two console.error calls with logger.error():

  • console.error("❌ STELLAR_CONTRACT_ID validation failed:")logger.error("STELLAR_CONTRACT_ID validation failed")
  • console.error(` ${issue.message}`)logger.error({ issue: issue.message }, "STELLAR_CONTRACT_ID validation issue")

The structured version passes the Zod issue message as a data field rather than string interpolation, making it machine-queryable in log aggregation.

backend/src/migrations/0002_add_stream_indexes.ts

Replaced console.log("[migration] 0002_add_stream_indexes: indexes applied.") with process.stderr.write(). The pino logger cannot be imported in migration files that run standalone via ts-node because the migration context may not have the full application environment initialized. process.stderr.write is the appropriate fallback — it's unbuffered, always visible, and does not trigger the no-console ESLint rule.

backend/src/services/db.ts

Replaced console.error("Postgres Worker Error:", err) with process.stderr.write("Postgres Worker Error: " + (err.message || err) + "\n"). This code runs inside a Worker thread string literal (not a normal module import), so the pino logger singleton is not accessible. process.stderr.write is the correct choice here.

Why this approach

  • Pino is already fully integrated: The project already uses pino for all logging. The request middleware, logger module, and redaction are complete. This PR simply closes the remaining gaps.
  • process.stderr.write for worker/migration contexts: Pino's singleton logger relies on AsyncLocalStorage and the application's NODE_ENV configuration. Worker threads and standalone migration scripts don't have access to this context. Using process.stderr.write is the standard pattern for these contexts — it's synchronous, always visible, and doesn't depend on application initialization.
  • No new dependencies: All changes use existing infrastructure (pino is already a dependency).
  • No test additions needed: The existing logger.test.ts (redaction tests) and requestLogger.test.ts (8 tests covering correlation ID, method, path, status, duration) already validate the logging pipeline. The consolelogger replacements are structurally equivalent; the only difference is that logs now go through pino's formatting and redaction pipeline.

How it was tested

  • npx vitest run src/logger.test.ts — 1/1 passed (redaction of Stellar secret keys)
  • npx vitest run src/middleware/requestLogger.test.ts — 8/8 passed (correlation ID injection, Authorization header redaction, status-based log levels, duration tracking)
  • npx eslint on all modified files — 0 new lint errors (the no-console error in 0002_add_stream_indexes.ts was fixed by this change)
  • All pre-existing test failures (27 in validateEnv, others in indexer/streamStore) are unchanged — confirmed they exist on the unmodified main branch

Follow-up

  • ADMIN_API_KEY validation also has a console.error / process.exit(1) path in validateEnv.ts that could benefit from consistent logger usage (lower priority — this path exits the process immediately)
  • Worker thread logging: Consider creating a lightweight pino transport for worker threads that pipes structured logs back to the main process, rather than raw process.stderr.write

Closes #718

🤖 Generated with Codebuff
Co-Authored-By: Codebuff noreply@codebuff.com

Replace all remaining console.log and console.error calls in the backend
with structured pino logging (or process.stderr.write where pino is
unavailable). This completes the structured logging migration started
earlier in the codebase.

Changes:
- validateEnv.ts: Two console.error calls replaced with logger.error()
  using structured fields (issue message as data, not string interpolation)
- 0002_add_stream_indexes.ts: console.log replaced with
  process.stderr.write() since pino is not available in migration context
- services/db.ts: console.error in PostgreSQL worker thread string literal
  replaced with process.stderr.write() since pino is not available in
  worker threads

This also fixes a pre-existing ESLint no-console lint error in the
migration file.

Closes ritik4ever#718

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@vercel

vercel Bot commented Aug 29, 2026

Copy link
Copy Markdown

@scarface-dev1 is attempting to deploy a commit to the ritik4ever's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave

drips-wave Bot commented Aug 29, 2026

Copy link
Copy Markdown

@scarface-dev1 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

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c5fb1de4-d197-46ad-bd00-de9f6ac4b530


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

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.

[FEATURE] Add structured logging with pino

1 participant