Skip to content

Logging

Nid uses a structured logging system based on Pino on the backend and a lightweight console logger on the frontend.

Backend

Centralized Logger

All backend modules use the centralized logger defined in backend/src/logger.ts:

typescript
import { createLogger } from '../logger'

const logger = createLogger('mon-module')

logger.info({ accountId, messageId }, 'archiving mail')
logger.error({ err }, 'operation failed')
logger.debug({ data }, 'debug info')
logger.warn('something unusual happened')

createLogger(name) creates a Pino child logger that:

  • Inherits the log level defined by LOG_LEVEL
  • Uses pino-pretty in development (colorized and readable output)
  • Produces structured JSON in production (for integration with tools like Loki, ELK, Datadog)
  • Automatically includes the module name in every log line

Configuration

VariableDefaultDescription
LOG_LEVELinfoMinimum level: debug, info, warn, error, silent
NODE_ENVdevelopmentIn development, activates pino-pretty

Best Practices

  • Always pass context as an object: logger.info({ accountId, jobId }, 'message') rather than logger.info('message ' + accountId)
  • Log errors with err: logger.error({ err }, 'description') — Pino automatically serializes the stack trace
  • Use debug for details: debug information is only visible with LOG_LEVEL=debug
  • Never log sensitive data: no tokens, passwords, API keys

Logged Modules

ModuleFileLogged Operations
archivearchive/archive.service.tsEmail archiving, attachment extraction
archive-workerjobs/workers/archive.worker.tsBatch archiving progress
bulk-workerjobs/workers/bulk.worker.tsBulk operations (trash, delete, modify)
rule-workerjobs/workers/rule.worker.tsRule execution
rulesrules/rules.service.tsRules CRUD, execution
oauthauth/oauth.service.tsToken exchange, refresh
social-authauth/social.service.tsMulti-provider auth
gmailgmail/gmail.service.tsGmail API calls
gmail-throttlegmail/gmail-throttle.tsRate limiting, retries
workerjobs/workers/unified.worker.tsJob dispatch
schedulerjobs/scheduler.tsRule scheduling
dbdb/index.tsMigrations
analyticsanalytics/analytics.service.tsHeatmap, scores, suggestions
deduparchive/dedup.service.tsAttachment deduplication
exportarchive/export.service.tsZIP export
importarchive/import.service.tsmbox/IMAP import
integrityarchive/integrity.service.tsIntegrity verification
retentionarchive/retention.service.tsRetention policies
sharingarchive/sharing.service.tsTemporary sharing
storagestorage/storage.service.tsStorage backend (local/S3)
quotagmail/quota.service.tsAPI quota tracking
reportsreports/report.service.tsWeekly reports
report-schedulerreports/report.scheduler.tsReport scheduling
notifynotifications/notify.tsMulti-channel notifications
webhookwebhooks/webhook.service.tsWebhook dispatch
auditaudit/audit.service.tsAudit log
expirationexpiration/expiration.service.tsEmail expiration
encryptionprivacy/encryption.service.tsArchive encryption
pii-scannerprivacy/pii.service.tsPII detection
tracking-pixelprivacy/tracking.service.tsTracking pixel detection
unsubscribeunsubscribe/unsubscribe.service.tsNewsletter scan
job-sseroutes/job-sse.tsSSE broadcast
mcpmcp-server.tsMCP server

Fastify Error Handling

The global error handler (plugins/index.ts) automatically logs:

  • Zod validation errors (warn level) with details
  • Client errors (4xx, warn level)
  • Server errors (5xx, error level) with the URL, method, and user ID

Frontend

Logger

The frontend uses a lightweight logger defined in frontend/src/utils/logger.ts:

typescript
import { createLogger } from '../utils/logger'

const logger = createLogger('mon-composant')

logger.info('Action effectuée', { page: 'dashboard' })
logger.error('Erreur API', { url, status })
  • In production: only warn and error are displayed
  • In development: all levels are active

Error Boundary

An ErrorBoundary component (components/ErrorBoundary.tsx) captures unhandled React errors and logs them with the component stack.

API Interception

The Axios client (api/client.ts) automatically logs:

  • 401 errors (warn level)
  • 5xx errors (error level)
  • Network errors (error level)

Global Errors

main.tsx captures and logs:

  • Unhandled errors (window.onerror)
  • Unhandled Promise rejections (unhandledrejection)