Skip to content

feat(telemetry): add centralized Exceptionless dogfooding for SvelteKit frontend#2254

Open
niemyjski wants to merge 3 commits into
mainfrom
niemyjski/svelte-telemetry-dogfooding
Open

feat(telemetry): add centralized Exceptionless dogfooding for SvelteKit frontend#2254
niemyjski wants to merge 3 commits into
mainfrom
niemyjski/svelte-telemetry-dogfooding

Conversation

@niemyjski
Copy link
Copy Markdown
Member

Summary

Implements end-to-end Exceptionless telemetry for the Svelte 5 / SvelteKit frontend, then applies a thorough adversarial code review pass fixing all identified issues.

What changed

New: src/lib/telemetry/

  • exceptionless.client.ts — Central module; page views, session lifecycle, 404s, API failure tracking, big product actions. Gated by isEnabled() so no-ops if API key is absent.
  • Telemetry.svelte — Reactive component; starts/ends sessions, tracks page views on SPA navigation. Mounted outside {#if isAuthenticated} so logout transition fires correctly.
  • sanitize.ts — PII sanitizer; redacts emails, tokens (≥32 chars), phone numbers, IPs, SSNs; recursively sanitizes nested objects; caps string/object sizes.
  • route.ts — Path normalizer; per-segment ObjectId/UUID replacement (no partial-hex false matches), produces ui.page.events format (no leading slash).
  • action.tstrackBigAction() helper + withTelemetryAction() wrapper that tracks both success and failure with errorType.

Updated: hooks + layouts

  • hooks.client.ts — Exceptionless startup() in init; dev-only debug logging; version from env.PUBLIC_APP_VERSION; handleError returns { errorId, message } per SvelteKit spec.
  • +layout.svelte — Module-level guards prevent double useMiddleware registration on re-instantiation; <Telemetry> moved outside {#if isAuthenticated}.
  • +error.svelte — New file; 404 tracking with per-path dedup.

Updated: feature API files (big product actions)

Auth, organizations, projects, stacks, saved-views, webhooks, tokens — all major mutations instrumented with trackBigAction().

Fixes applied (staff-engineer review)

# Issue Fix
1 @@log:* debug in production Dev-only guard
2 Hardcoded version = '8.0.0' Reads env.PUBLIC_APP_VERSION
3 handleError didn't return { errorId, message } Fixed; typed as HandleClientError
4 <Telemetry> inside {#if isAuthenticated} Moved outside; passes userId prop
5 useMiddleware double-registration Module-level boolean guards
6 OBJECTID_REGEX partial-match bug Per-segment exact match /^[0-9a-f]{24}$/i
7 toPageEventName leading slash Strip and replace; fallback root
8 404 fires on every re-render lastTrackedNotFoundPath dedup
9 No sessionStorage guard for HMR ex_session_active key guards startSession()
10 Nested objects pass PII unsanitized Recursive shallow sanitization
11 Failure tracking missed errorType Captures error.name as errorType
12 No isEnabled() guard All exports no-op when API key absent
13 Floating .submit() Promises void added throughout

Dogfood verification ✅

Tested against live app with real API key. Events confirmed in Exceptionless:

  • ui.page.issues — page view on navigate
  • ui.page.events — page view
  • ui.page.sessions — page view
  • ui.page.project.:id.configure — dynamic segment normalized correctly
  • session events — start/end via Telemetry.svelte
  • ui.action.project.create — project created
  • ui.action.stack.mark-fixed — stack marked fixed
  • 404 type event with source /this-page-does-not-exist — not-found tracking

Test coverage

298 tests pass (287 before → +11 new tests).

npm run check    # 0 errors
npm run lint     # 0 errors  
npm run test:unit # 298 passed (18 suites)

niemyjski and others added 3 commits May 25, 2026 15:58
…it app

Instruments framework boundaries (not individual components) to track:
- Page views with normalized routes (IDs replaced with :id)
- Session lifecycle tied to auth state changes
- API failures (5xx/429) with 30s deduplication
- 404 not-found events via +error.svelte
- Product action helpers (withTelemetryAction/trackBigAction)

All telemetry is fail-safe (never throws), sanitizes PII aggressively,
and uses low-cardinality event names for efficient aggregation.
Add trackBigAction calls to onSuccess callbacks for:
- Auth: login, logout, signup, forgot-password
- Organizations: create, delete, invite-user
- Stacks: mark-fixed, snooze, delete, add-reference
- Projects: create, delete
- Saved Views: create, update, delete
- Webhooks: create, delete
- Tokens: create, delete

Also mock @exceptionless/browser in server test setup to prevent
transitive import failures from stacktrace-js in Node.js.
- Remove production debug logging (@@log:* debug → dev-only)
- Replace hardcoded version '8.0.0' with env.PUBLIC_APP_VERSION
- handleError now returns { errorId, message } per SvelteKit spec
- Fix OBJECTID/UUID regex: use per-segment matching to prevent partial
  hex string replacement (507f...extra no longer becomes :idextra)
- Fix toPageEventName: produce 'ui.page.events' not 'ui.page./events'
- Fix session end on logout: move <Telemetry> outside {#if isAuthenticated}
  so the userId→undefined transition fires endSession() correctly
- Add sessionStorage guard in Telemetry.svelte to prevent duplicate
  startSession() calls on HMR reloads and component remounts
- Add module-level guard for useMiddleware registrations in layout
  to prevent double middleware execution on re-instantiation
- Fix +error.svelte: deduplicate 404 tracking per path on re-renders
- Add nested object sanitization in sanitizeProperties()
- Omit null/undefined values from sanitized properties
- Capture errorType (not message) in withTelemetryAction failure
- Add no-op isEnabled() guard gating all telemetry on API key presence
- Use void on all .submit() Promise returns
- Fix all lint errors: import order, curly braces, sort-objects,
  sort-modules, unnecessary regex escapes
- Update tests: 298 passing (was 287)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
Exceptionless.Web 71% 61% 3733
Exceptionless.AppHost 18% 9% 82
Exceptionless.Insulation 25% 23% 203
Exceptionless.Core 68% 62% 7738
Summary 67% (13074 / 19439) 61% (6866 / 11304) 11756

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant