Commit Graph
4 Commits
Author SHA1 Message Date
jason5ng32andClaude Fable 5 9bfbf21a60 Feat(monitoring): integrate Sentry across frontend and backend, env-gated end to end
Frontend (@sentry/vue, loaded via build-time-gated dynamic import — no
VITE_SENTRY_DSN_FRONTEND, no Sentry in the bundle; init joins the mount
gate so instrumentation precedes the first render):
- uncaught errors, route-change tracing / Web Vitals, error-only masked
  Session Replay, console.error capture fingerprinted per message prefix
  so each fallback source stays a distinct issue
- explicit ip-source:exhausted signal via the app-events bus
- hidden source maps uploaded (then deleted) by @sentry/vite-plugin,
  gated on SENTRY_AUTH_TOKEN

Backend (@sentry/node, bootstrapped by sentry-instrument.js via
node --import so ESM loader hooks land before express; never loaded
without SENTRY_DSN_BACKEND):
- Express error capture + per-route tracing
- logger hook mirrors warn+ lines to Sentry Logs and elevates error+
  to grouped, alertable Issues
- Sentry Crons check-ins for the MaxMind / CAIDA / service-status jobs
  via the no-op-without-DSN wrapper common/sentry-cron.js

Delivery & ops:
- first-party tunnel /api/monitoring relays envelopes past ad blockers;
  DSN-allowlisted (never an open relay), exempt from the shared rate
  limiter with its own generous ceiling
- rate-limit ledger file becomes opt-in now that the warn line reaches
  Sentry Logs; ecosystem.config.cjs carries the --import flag for pm2

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-12 11:16:17 +08:00
jason5ng32andClaude Opus 4.7 833f66cc42 Feat(backend): introduce pino logger + pino-http request logs
Replace all backend console.* with a shared pino singleton at
common/logger.js. Startup-style lines get emoji prefixes (🚀 listening,
📦 maxmind ready, 📥 downloading, 🗓️ schedule, ⚠️ warning, ❌ failure);
per-handler / per-request logs stay plain.

Three .env-driven knobs, all without NODE_ENV:
  - LOG_LEVEL (default info) — pino level filter
  - LOG_FORMAT (default pretty) — "json" for log shippers
  - LOG_HTTP (default off) — pino-http on /api/* gated behind this flag
    so pm2 logs don't bloat with 2xx/3xx request lines on every deploy;
    when enabled, 4xx log as warn and 5xx as error

logger.js calls dotenv.config({ quiet: true }) itself because ES module
imports are hoisted above backend-server.js's dotenv call — without that
LOG_LEVEL from .env was silently ignored.

Fixes in common/rdap.js:
  - err: res.status → status: res.status (pino's err serializer expects
    an Error object, not a number)
  - broken single-quoted template literal in "No RDAP endpoint" message
  - demote "No RDAP endpoint" and "Domain not found" from error to warn
    (they're expected outcomes for user input, not server failures)

README (en/zh/fr/tr) + .env.example + AGENTS.md (root and api/) all
updated to document the three new vars and the "no console.* in backend"
convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 01:29:52 +08:00
jason5ng32andClaude Opus 4.7 08e20bed7a Feat(backend): bootstrap MaxMind databases on startup if missing
Previously reloadMaxMindDatabases ran fire-and-forget at the top level
and only logged an error when the .mmdb files were missing — the server
would start but MaxMind API returned 503 forever until someone noticed.

Now backend-server.js runs an explicit bootBackend() that:
  1. bootstrapMaxMindIfMissing — if files are absent, check for
     MAXMIND_ACCOUNT_ID / MAXMIND_LICENSE_KEY and either print a clear
     "how to fix" warning or run a synchronous download cycle capped at
     5 minutes (AbortController threaded through fetch + pipeline so the
     abort actually stops in-flight I/O).
  2. reloadMaxMindDatabases — load readers.
  3. startMaxMindFileWatcher + startMaxMindAutoUpdate — unchanged.
  4. app.listen — only after the steps above.

The 5-minute cap is a total timeout only; we deliberately skipped the
"no-bytes-for-N-seconds stall detector" to keep the path simple. On any
failure (bad credentials, blocked outbound, timeout) the server still
starts — just with MaxMind returning 503 and a clear operator warning.

MAXMIND_AUTO_UPDATE is intentionally NOT consulted by bootstrap; that
flag only gates the periodic scheduler. Credentials alone are enough
signal that the operator wants MaxMind working.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 23:58:22 +08:00
jason5ng32 31c0f2105c feat: add MaxMind database auto update 2026-04-14 13:18:13 +08:00