Add observability: health checks, request IDs, and structured logging - #38
Merged
Merged
Conversation
…i/health Build metadata. next.config.ts computes the version (package.json), the short commit (VERCEL_GIT_COMMIT_SHA, else git) and the build time once, and inlines them through Next's `env` option, so the server, proxy and browser read the same values via lib/build.ts. Every response carries X-App-Version and X-Commit-SHA; window.appVersion holds the same in the browser. Request ids. proxy.ts gives every request an X-Request-ID, keeping a caller's X-Request-ID or X-Correlation-ID when it is a plain token of up to 128 characters. It forwards the id to route handlers and echoes it on the response. Structured logs. pino replaces console.error/info in every route handler and in the proxy. Each line is JSON with the build, and with requestId when it is written during a request. Messages are unchanged, so existing log searches still match. LOG_LEVEL sets the level, defaulting to info in production and debug elsewhere; it is read directly rather than through env(), so the log works when the environment does not. Errors. Both Sentry inits now carry a release and environment, plus app_version and commit tags. Unhandled server errors are logged with their request id and route template, and that id is tagged on the Sentry event. Browser source maps ship with the deployment; the source is public AGPL, so they reveal nothing new. Health. GET /api/health returns status, build and per-service checks. The database check is a head-only read of wedding_documents. It answers 503 when a configured database does not respond; a backend-less deployment is healthy. Verified against `next start`: headers on pages and API routes, a log line's requestId matching the X-Request-ID returned, a 503 with a database that does not answer, one build timestamp in both server and client output, and every loaded chunk's source map served. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VLGpqEpvfAjaAmtfcKdS9b
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Copilot review overview
🟢 Approval recommended
The implementation is coherent and tested; only a non-blocking documentation overstatement remains.
Review effort: Balanced
Findings: 1
Open (1)
What changed in this PR
Adds application observability through health monitoring, request correlation, build metadata, structured logging, and Sentry tagging.
Changes:
- Adds
/api/healthwith dependency and build status. - Propagates validated request IDs through middleware, responses, logs, and Sentry.
- Replaces server console logging with Pino structured logs.
| File | Description |
|---|---|
suite/proxy.ts |
Generates and propagates request IDs. |
suite/proxy.test.ts |
Tests request ID behavior. |
suite/package.json |
Adds Pino. |
suite/next.config.ts |
Injects build metadata and response headers. |
suite/lib/server/log.ts |
Defines structured request logging. |
suite/lib/server/log.test.ts |
Tests request-bound log metadata. |
suite/lib/sentry/build.ts |
Defines shared Sentry build metadata. |
suite/lib/headers.test.ts |
Tests build headers and timestamps. |
suite/lib/build.ts |
Exposes inlined build information. |
suite/instrumentation.ts |
Adds server Sentry and unhandled-error correlation. |
suite/instrumentation-client.ts |
Exposes build information and configures browser Sentry. |
suite/app/auth/callback/route.ts |
Adds structured error logging. |
suite/app/api/suppliers/route.ts |
Adds request-aware logging. |
suite/app/api/suppliers/[token]/route.ts |
Adds request-aware logging. |
suite/app/api/share/route.ts |
Adds request-aware logging. |
suite/app/api/share/[token]/route.ts |
Adds request-aware logging. |
suite/app/api/library/route.ts |
Adds request-aware logging. |
suite/app/api/library/[id]/route.ts |
Adds request-aware logging. |
suite/app/api/health/route.ts |
Implements the health endpoint. |
suite/app/api/health/route.test.ts |
Tests health states and metadata. |
suite/app/api/documents/route.ts |
Adds request-aware logging. |
suite/app/api/documents/history/route.ts |
Adds request-aware logging. |
suite/app/api/documents/history/[id]/route.ts |
Adds request-aware logging. |
suite/app/api/documents/export/route.ts |
Adds request-aware logging. |
suite/app/api/cron/sweep/route.ts |
Structures retention sweep logs. |
suite/app/api/accounts/weddings/route.ts |
Adds request-aware logging. |
suite/app/api/accounts/members/route.ts |
Adds request-aware logging. |
suite/app/api/accounts/invite/route.ts |
Adds request-aware logging. |
suite/app/api/accounts/invite/[token]/route.ts |
Adds request-aware logging. |
suite/app/api/accounts/delete/route.ts |
Adds request-aware logging. |
suite/app/api/accounts/delete/route.test.ts |
Updates tests for request parameters. |
suite/.env.example |
Documents LOG_LEVEL. |
package-lock.json |
Locks Pino dependencies. |
docs/SELF-HOSTING.md |
Documents health checks and observability. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+191
to
+192
| Every response carries `X-App-Version`, `X-Commit-SHA` and `X-Request-ID`. In | ||
| a browser console, `window.appVersion` says the same. The server logs one JSON |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

This PR adds comprehensive observability to the application through health checks, request tracing, and structured server-side logging.
Summary
Introduces a health check endpoint, request ID propagation across the entire request lifecycle, structured JSON logging with Pino, and build information tracking. These changes enable better monitoring, debugging, and tracing of requests through the system.
Key Changes
Health Check Endpoint (
/api/health): New endpoint that returns deployment status (200 for healthy, 503 for degraded), build information (version, commit, timestamp, environment), and configuration status of optional services (database, accounts, error reporting)Request ID Propagation: Every request receives a unique ID (generated or from caller's
X-Request-ID/X-Correlation-IDheaders) that is:Structured Logging: Replaced
console.error()calls with Pino-based structured JSON logging viarequestLog(), which automatically includes the request ID and build information on every log lineBuild Information:
buildInfo()innext.config.ts)envoptionX-App-VersionandX-Commit-SHAresponse headerswindow.appVersionSentry Integration: Build information is now included in Sentry initialization for both server and browser, enabling better error tracking and correlation
Middleware Enhancements: Updated
proxy.tsto handle request ID generation, validation, and propagation while maintaining existing sign-in redirect logicImplementation Details
/^[\w.:-]{1,128}$/to prevent log injectionLOG_LEVELenvironment variable with sensible defaults (info in production, debug elsewhere)https://claude.ai/code/session_01VLGpqEpvfAjaAmtfcKdS9b