Files
CompanySite/.agents/backend-specialist/ERROR_MONITORING.md
T
Clintchiz d402256547
Deploy to Production / Build & Verify (push) Failing after 5m56s
Ping Search Engines / Notify Search Engines (push) Successful in 2s
Deploy to Production / Pre-Deploy Tests (push) Has been skipped
Deploy to Production / Deploy to Railway (push) Has been skipped
Deploy to Production / Deploy to Render (push) Has been skipped
Deploy to Production / Deploy to VPS (PM2) (push) Has been skipped
Deploy to Production / Deploy to Fly.io (push) Has been skipped
Deploy to Production / Post-Deploy Verification (push) Has been skipped
Deploy to Production / Notify on Failure (push) Successful in 2s
E2E Test Suite / Critical User Journeys (push) Has been skipped
E2E Test Suite / API Integration Tests (push) Has been skipped
E2E Test Suite / Smoke Tests (P0) (push) Failing after 11m26s
E2E Test Suite / Form Interaction Tests (push) Failing after 11m42s
E2E Test Suite / Destructive & Chaos Tests (push) Failing after 12m2s
E2E Test Suite / Cross-Browser Regression (chromium) (push) Failing after 16m14s
E2E Test Suite / Cross-Browser Regression (webkit) (push) Failing after 17m45s
E2E Test Suite / Cross-Browser Regression (firefox) (push) Failing after 25m23s
E2E Test Suite / Security Header Tests (push) Failing after 7m55s
E2E Test Suite / Test Report Summary (push) Failing after 20s
E2E Test Suite / Mobile Device Tests (push) Failing after 2h49m9s
Uptime Monitor / Health & Response Time (push) Failing after 2s
Uptime Monitor / SSL Certificate (push) Successful in 2s
Uptime Monitor / Send Alerts (push) Failing after 3s
Uptime Monitor / Record Uptime Success (push) Has been skipped
First Init
2026-03-21 16:46:46 +05:30

5.7 KiB

Error Monitoring & Logging

Overview

The WorkRoot site uses a two-layer monitoring approach:

  1. Structured Logger (src/utils/logger.ts) — always active, zero dependencies
  2. Sentry Integration (src/utils/sentry.ts) — optional, activated via SENTRY_DSN env var

Files Created / Modified

File Change
src/utils/logger.ts New — structured logger
src/utils/sentry.ts New — Sentry HTTP integration
src/middleware.ts Updated — logs all requests + SSR errors
src/pages/api/contact.ts Updated — structured logs + Sentry on email failure
src/pages/api/newsletter.ts Updated — structured logs + Sentry on SMTP failure
.env.example Updated — added SENTRY_DSN, LOG_LEVEL, RELEASE_VERSION

Structured Logger

Usage

import { logger, logApiRequest } from '../../utils/logger';

// General logging
logger.debug('scope', 'message', { key: 'value' });
logger.info('scope', 'message', { key: 'value' });
logger.warn('scope', 'message', { key: 'value' });
logger.error('scope', 'message', { key: 'value' });

// API request logging
logApiRequest({
  scope: 'api.contact',
  method: 'POST',
  path: '/api/contact',
  status: 200,
  ip: clientAddress,
  durationMs: Date.now() - startTime,
  meta: { subject: formData.subject },
});

Output Format

Development — human-readable with color:

[INFO] 2026-03-21T08:00:00.000Z [api.contact] POST /api/contact 200 {"durationMs":42}
[ERROR] 2026-03-21T08:00:01.000Z [api.contact] Email delivery failed {"error":"..."}

Production — JSON for log aggregation:

{"level":"info","scope":"api.contact","message":"POST /api/contact 200","timestamp":"2026-03-21T08:00:00.000Z","durationMs":42}

Log Levels

Level When
debug Verbose request tracing (dev only by default)
info Successful operations, informational events
warn Rate-limit hits, 4xx errors, degraded operations
error 5xx errors, email failures, unhandled exceptions

Configure minimum log level via LOG_LEVEL env var (debug/info/warn/error).


Sentry Integration

Setup

  1. Create a project at sentry.io (Node.js platform)
  2. Copy the DSN from Settings → Client Keys (DSN)
  3. Add to your environment:
SENTRY_DSN=https://xxx@oXXXXXX.ingest.sentry.io/XXXXXXX
RELEASE_VERSION=1.0.0

No SDK installation required — the integration uses Sentry's HTTP store API directly.

Usage

import { captureException, captureMessage } from '../../utils/sentry';

// Capture an exception (also logs via structured logger)
await captureException(error, {
  scope: 'api.contact',
  user: { ip: clientAddress },
  extra: { email: formData.email },
  tags: { feature: 'contact-form' },
});

// Capture a message
await captureMessage('Rate limit exceeded', 'warning', {
  scope: 'api.contact',
  extra: { ip },
});

What Gets Captured

Event Sentry Level Location
SSR middleware crash error src/middleware.ts
Contact form email failure error src/pages/api/contact.ts
Newsletter SMTP failure error src/pages/api/newsletter.ts

Without SENTRY_DSN

All calls to captureException / captureMessage fall back to structured logger only. No errors are swallowed — monitoring degrades gracefully.


Middleware Request Logging

All HTTP requests pass through src/middleware.ts, which now logs:

  • 5xxerror level (also tries to capture in Sentry)
  • 4xxwarn level
  • All othersdebug level (dev only)

Duration is measured from request start to response completion.


Environment Variables

# Required for Sentry error tracking
SENTRY_DSN=https://xxx@oXXXXXX.ingest.sentry.io/XXXXXXX

# Optional — minimum log level (default: info in prod, debug in dev)
LOG_LEVEL=info

# Optional — used for Sentry release tracking
RELEASE_VERSION=1.0.0

Upgrading to Full Sentry SDK

For richer features (performance monitoring, session replay, source maps):

npm install @sentry/node

Then replace src/utils/sentry.ts with:

import * as Sentry from '@sentry/node';

Sentry.init({
  dsn: import.meta.env.SENTRY_DSN,
  environment: import.meta.env.PROD ? 'production' : 'development',
  release: process.env.RELEASE_VERSION,
  tracesSampleRate: 0.1, // 10% of transactions
});

export const captureException = (err: unknown, ctx?: object) =>
  Sentry.captureException(err, ctx ? { extra: ctx as Record<string, unknown> } : undefined);

export const captureMessage = (msg: string, level = 'info') =>
  Sentry.captureMessage(msg, level as Sentry.SeverityLevel);

Log Aggregation (Production)

Since production output is newline-delimited JSON, it integrates with:

  • Logtail / Better Stack — point log drain at your server stdout
  • Datadog — use their Node.js log agent
  • Render / Railway / Fly.io — all capture stdout automatically; pipe to their log service
  • Self-hosted — any log shipper that reads Docker/PM2 stdout (Filebeat, Promtail, etc.)

Testing

Verify structured logging is working:

# Development — see colored output
npm run dev
# Visit http://localhost:4321/api/health  →  should see DEBUG log

# Production — see JSON output
NODE_ENV=production node server.mjs

Verify Sentry is working:

# Set SENTRY_DSN in .env, then trigger an error:
curl -X POST http://localhost:4321/api/contact \
  -H "Content-Type: application/json" \
  -d '{"name":"Test","email":"bad@","subject":"other","message":"test"}'
# Check your Sentry dashboard for the captured event