Observability

Vercel's built-in logs capture console.* output and unhandled exceptions; on top of that we emit structured JSON through a small logger wrapper.

What's available now

  • Structured logger at src/lib/log.tslog.info, log.warn, log.error, logError(event, err, context?). All wrap console.* and write {level, event, ts, ...context} JSON so Vercel log search can filter by event.
  • Per-request correlation via X-Request-Id — generated in withApiAuth (src/lib/api/request-id.ts) and echoed back on every /api/v1/* response.
  • /api/health — Postgres + Upstash probes. Used by external uptime monitors; logError("health.check_failed", ...) fires only on failure so polling doesn't spam the log.
  • Vercel Function Logs — stdout / stderr.
  • Upstash Analytics — rate-limit call counts (enabled on @upstash/ratelimit).
  • Stripe Dashboard — subscription and webhook events.
  • AWS CloudWatch — SES + SNS call-level metrics.
  • Webhook delivery logwebhook_deliveries table rows; inspection UI on /overview/webhooks.
  • Audit logaudit_logs table; dashboard at /overview/settings/audit.

What the logger covers today

Surface Event prefix Notes
Cron: scheduled sends cron.scheduled.* usage_increment and fanout failures, plus cron.scheduled.run summary
Cron: webhook retry cron.retry_webhooks.run processed + due counts
Cron: idempotency cleanup cron.cleanup_idempotency.run delete count
Cron: overage report cron.overage.* run summary; per-org Stripe create failures
Webhook: SES webhook.ses.* signature failures, fan-out failures, processed summary
Webhook: SNS SMS webhook.sns_sms.* signature failures, fan-out failures, processed summary
Webhook: inbound email webhook.inbound_email.* signature failures, fan-out failures, processed summary
Template test send template.test_send* success + failure paths
Stripe webhook stripe.webhook.* handler-level failures

Webhook fan-out now runs inside after(() => ...) from next/server, so the handler returns a 200 before provider callbacks happen and errors surface via the logger only.

Still missing

  • No Sentry / OTEL / APM.
  • No latency histograms beyond Vercel defaults.
  • No webhook_deliveries failure surface beyond the dashboard view.

Quick wins next

  1. Sentry@sentry/nextjs picks up both server and client errors with one install + config.
  2. Vercel OTEL — export traces to Honeycomb / Datadog / Jaeger.
  3. Weekly audit log email to owners summarizing notable actions.