Continuous Integration / config (pull_request) Successful in 9s
Continuous Integration / prepare (pull_request) Successful in 1m12s
Continuous Integration / build (pull_request) Successful in 1m53s
Continuous Integration / test (pull_request) Successful in 1m49s
Continuous Integration / deploy-test (pull_request) Skipped
Co-authored-by: Junie <junie@jetbrains.com>
7.2 KiB
7.2 KiB
Monitoring Setup Instructions
Concrete setup steps for the approaches chosen in monitoring-plan.md: Logging and Dashboards (no Alerting).
Logging
What to log
- Uncaught JavaScript errors / exceptions (the app already has an
ErrorBoundarycomponent from Code Generation — this is the natural hook point). - Broken/failed navigation (e.g. an unexpected router error).
- No user PII, form input, or sensitive data should ever be logged — this is a public marketing site, but keep this discipline regardless.
Destination — decided: Sentry free tier + console
Both the console and Sentry are now active (original Question 3 resolved as a combination):
Console (always on)
- Errors already surface via
console.errorinsideErrorBoundary.componentDidCatch— unchanged, zero cost, useful for local/manual debugging.
Sentry free tier (implemented)
@sentry/reactis a dependency;src/main.tsxcallsSentry.init({ ... })at startup, but only when a DSN is present — if not configured, Sentry is silently skipped and only console-logging remains active (safe default, no crash on missing config).ErrorBoundary.componentDidCatchcallsSentry.captureException(error, { extra: { componentStack: info.componentStack } })in addition toconsole.error.- Tracing/performance is also enabled (Sentry's recommended default alongside error monitoring, per the official React SDK setup guide):
tanstackRouterBrowserTracingIntegration(router)is wired up so route navigations are captured as transactions, withtracesSampleRate: 1.0(capture all — appropriate for a low-traffic marketing site; lower this if traffic grows significantly). - Environment/release tagging:
environmentis set toimport.meta.env.MODE(e.g.production) andreleaseis set to the app version frompackage.json(injected at build time viavite.config.ts'sdefine: { __APP_VERSION__ }), so events in Sentry can be filtered/grouped per environment and per shipped version. - The DSN is injected at build time via Vite's
import.meta.env.VITE_SENTRY_DSN(typed insrc/vite-env.d.ts). It is not a secret (Sentry DSNs are safe to expose client-side), so it is passed as a Gitea Actions repository variable (vars.VITE_SENTRY_DSN, not a secret) to theBuildstep incontinuous_integration.yaml. - Manual follow-up required: create a free Sentry project (https://sentry.io) for this app, copy its DSN, and set it as the
VITE_SENTRY_DSNrepository variable in Gitea (Repository Settings → Actions → Variables). Until that variable is set, the build still succeeds and the site still works — Sentry reporting simply stays inactive. - Free tier limits (error volume, retention) are typically sufficient for a low-traffic marketing site.
- Not (yet) implemented, by explicit choice: automatic source map upload (via
@sentry/vite-plugin), which the official Sentry setup guide also recommends so stack traces show real source code instead of minified code. This requires a Sentry auth token/org/project as a new Gitea secret; deliberately left out of scope for now — revisit if readable production stack traces become a priority.
Log level strategy: only errors are logged (no verbose/info-level client logging) — this is a static site with no meaningful "business events" beyond page views, which are covered by analytics (see Dashboards below), not logging.
Temporary manual test tool: SentryTestButton
src/components/SentryTestButton.tsxrenders a "Break the world" button, mounted globally viaRootLayout.tsx, used to manually verify that errors, logs (Sentry.logger.info), and metrics (Sentry.metrics.count) actually arrive in Sentry end-to-end.- Visibility: only shown during local development (
pnpm dev, via Vite'simport.meta.env.DEV) and in the test environment (via the new build-timeVITE_APP_ENVvariable, set totestbycontinuous_integration.yaml'sBuildstep). It is hidden by default (including in any future production build) unless one of those conditions is explicitly true. - Visual feedback: clicking the button immediately shows a green confirmation toast ("Test error verzonden naar Sentry ✅",
role="status") that auto-hides after 4 seconds, so the user gets clear confirmation that the test action fired — without this, the resulting uncaught error/blank state gave no indication anything happened. The actual log/metric/throw (handleSentryTestErrorClick) is fired on the next tick (setTimeout(..., 0)) so the toast has a chance to render/paint first. Sentry.logger.*requiresenableLogs: trueinSentry.init()(src/main.tsx) — added specifically to support this test button (and any future structured logging).- The thrown error is intentionally uncaught: React error boundaries do not catch errors thrown from event handlers (only render/lifecycle errors), so this relies on Sentry's own global
window.onerrorhandler, exactly like the official Sentry test snippet. - This is a temporary verification tool, not a permanent feature — remove
SentryTestButton(and its usage inRootLayout.tsx) once Sentry has been confirmed to receive test errors/logs/metrics end-to-end.
Dashboards
Website analytics
Pick one (all have generous free tiers suitable for a small marketing site):
| Option | Notes |
|---|---|
| Plausible / Umami | Privacy-friendly, lightweight, no cookie banner typically required; self-hosted or low-cost hosted tier |
| Google Analytics (GA4) / Search Console | Free, widely known, but heavier script and involves third-party data sharing (cookie/consent implications) |
Setup (once a tool is picked):
- Create an account/site entry with the chosen provider and obtain the tracking snippet or
<script>tag. - Add the snippet to
index.html(or load it conditionally insrc/main.tsx) — this is a documentation/config task, not something the current codebase needs restructuring for. - Key metrics to surface: unique visitors, page views per route (Home, Packages, etc. — see
frontend-components.md), and referral sources.
Uptime dashboard
Pick one:
| Option | Notes |
|---|---|
| UptimeRobot | Free tier: up to 50 monitors, 5-minute check interval, optional e-mail notification on downtime (opportunistic, not a designed alerting feature per monitoring-plan.md) |
| Better Uptime | Free tier available; similar capability, nicer public status page option |
Setup (once a tool is picked):
- Register the production URL (once hosting is finalized — see
operations/deployment/deployment-plan.md"Open Item") as an HTTP(S) monitor, checking for a200response. - Optional: publish a public status page if desired for transparency to visitors.
- Key metric to surface: uptime percentage / current status.
Summary Table
| Concern | Approach | Status |
|---|---|---|
| Client-side errors | Logging (console + Sentry free tier) | Implemented; VITE_SENTRY_DSN Gitea variable still needs to be created by the user |
| Visitor/usage insight | Analytics dashboard (Plausible/Umami/GA4) | Tool selection open item |
| Site reachability | Uptime dashboard (UptimeRobot/Better Uptime) | Tool selection + production URL open item |
| Alerting | Out of scope | Not configured |
| Shared infrastructure reuse | Out of scope | None exists yet |