Operate and launch

Observability and Structured Logging

Correlate redacted logs, OpenTelemetry traces, queue readiness, and actionable alerts across web and workers.

Synced with starter commit 2a1a04a.

Use this page to make support and incident work possible before you have your first incident. Sushi SaaS emits JSON to stdout; it deliberately does not choose a log-storage vendor, retention period, dashboard, or alerting product for you.

OpenTelemetry is optional and vendor-neutral. Set OTEL_ENABLED=true, a distinct OTEL_SERVICE_NAME per process, and the standard OTEL_EXPORTER_OTLP_ENDPOINT/OTEL_EXPORTER_OTLP_HEADERS values. Next.js request/fetch spans and custom job enqueue/execution spans are exported; logs written inside a span include trace_id and span_id. Telemetry is a no-op until enabled.

/api/ready reports payload-free queue counts, failed/stale jobs, and oldest due age. Failed work or a due job older than ten minutes degrades the queue without taking customer traffic out of service; dependency failures still return 503.

Make three operating choices

  • Send stdout to the collector already provided by your host, or forward it to a service such as Datadog, Better Stack, or Grafana. The application contract stays the same.
  • Use info in production unless you are diagnosing a specific issue. debug increases volume and may shorten useful retention.
  • Decide which identifiers support staff may search. Request, organization, job, order, and Stripe event IDs are useful; email addresses and raw payloads usually are not.

Ready to launch means: one browser request can be followed into its service/provider work with an ID, a test secret is redacted, an application error returns safe translated copy to the user, and alerts link to the log query an operator needs.

The Node runtime uses Pino and edge code emits the same JSON-shaped contract. Logs go to stdout for the hosting platform to collect; the application does not manage log files. Set LOG_LEVEL to debug, info, warn, or error.

Pass the request ID through routes, services, jobs, Stripe orders/events, and provider calls. Log structured fields such as event name, org_uuid, safe resource UUID, job/order number, duration, and result—not a prose-only message.

The logger redacts authorization headers, cookies, passwords, tokens, API keys, and other catalogued secrets. Never log raw request bodies, presigned URLs, or exported account data. Route boundaries pass failures to respError, which records internal context while returning a translated safe error_code; never expose error.message to the browser.

Monitor readiness, cron runs, retry exhaustion, webhook action-required state, latency, and unexpected 5xx rates. Correlate Slack alerts back to logs by identifiers; Slack is not the log store.

Next: Route only actionable failures through Slack Operations Notifications, keeping structured logs as the source of evidence.

Observability and Structured Logging · Sushi SaaS