Document two Sentry paths for Web Vitals; enable browserTracing in test page

- logr README: restructure the Vitals + Sentry section into two clearly
  separated delivery paths. Path A (via the logger → sentryTransport)
  reaches Issues/breadcrumbs; Path B (via Sentry's browserTracingIntegration)
  reaches the Performance/Insights product. Add a decision table covering
  the five common use cases (aggregate dashboards, triage breadcrumbs,
  alerts on poor ratings, non-Sentry backends, dev validation) with the
  recommended path for each, and document the production combo of Path B
  for analytics plus Path A at `breadcrumbLevel: TRACE` for error-context
  breadcrumbs.
- Test page: enable Sentry.browserTracingIntegration() with
  tracesSampleRate=1.0 so the page load emits a real transaction visible
  under Insights → Browser → Web Vitals, in addition to the logger-based
  vitals that already land as Issues. Promote every vital rating to ERROR
  in the test page override so good/needs-improvement samples also surface
  in the Issues feed — useful to validate end-to-end.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
master
dev 6 months ago
parent 4c074e196e
commit 342e189244

@ -464,6 +464,92 @@ query directly in your observability backend:
- **Sentry discover:** group events by `tag.category = vitals` and `tag.tag:lcp`, plot p75 per release
- **Datadog logs:** facet on `metric` and `route`, dashboard p95/p99 per route
### Vitals + Sentry: two delivery paths
Vitals can reach Sentry through **two independent pipelines**, each feeding
a different Sentry product. Knowing which is which avoids noise and gives
you the right dashboard for the question you're asking.
#### Path A — through the logger (what `registerWebVitals` does)
Vitals flow as regular `LogEntry` objects through every transport, including
`sentryTransport`. They end up as **Sentry Issues** (if promoted to ERROR)
or **breadcrumbs** (at INFO/WARN), alongside your normal logs.
| Rating | Default level | Reaches Sentry as … |
| ------------------ | ------------- | ------------------------------------------------------------------ |
| `good` | DEBUG | Dropped (below `breadcrumbLevel: INFO`) |
| `needs-improvement`| INFO | Breadcrumb (attached to the next captured event, not a new Issue) |
| `poor` | WARN | Breadcrumb (still below `eventLevel: ERROR`) |
With the defaults, vitals rarely appear as Sentry **Issues** — **this is by
design**. In production you do not want every page load producing an Issue.
**Best production use of Path A:** lower `breadcrumbLevel` so vitals become
rich context on the next captured error, without flooding the Issues feed:
```ts
logger.addTransport(sentryTransport(Sentry, {
eventLevel: LogLevel.ERROR,
breadcrumbLevel: LogLevel.TRACE // every sample becomes a breadcrumb
}));
```
**Validation trick for dev pages** — temporarily promote every sample to
ERROR so they show up as Issues and you can confirm the pipeline:
```ts
registerWebVitals(logger, webVitals, {
levels: {
good: LogLevel.ERROR,
'needs-improvement': LogLevel.ERROR,
poor: LogLevel.ERROR
}
});
```
#### Path B — through Sentry's native Browser Tracing (recommended for production)
Sentry's own `browserTracingIntegration` auto-captures Web Vitals and emits
them as **Performance transactions**. These land in a dedicated product and
do not pollute the Issues feed.
Where to find them in the Sentry dashboard:
- **Insights → Browser → Web Vitals** — aggregate p75/p95 per route, browser,
device, release
- **Performance → Transactions** — per-pageload detail with full vitals,
resource timing and long tasks
Setup (this is a one-time thing at app init, nothing to do in `logr`):
```ts
import * as Sentry from '@sentry/browser';
Sentry.init({
dsn: '<your-dsn>',
integrations: [Sentry.browserTracingIntegration()],
tracesSampleRate: 0.1 // 10% of page loads send a transaction
});
```
Vitals now flow automatically — no call to `registerWebVitals` needed for
this path.
#### When to use which
| Use case | Path |
| ----------------------------------------------------------- | ---- |
| Aggregate dashboards (p75 LCP by route, regressions by release) | **B** (Sentry Performance) |
| Correlate vitals with a specific error (debugging triage) | **A** at `breadcrumbLevel: TRACE` (breadcrumbs on error events) |
| Alerts on poor ratings (`poor` LCP → PagerDuty) | **A** with `poor: LogLevel.ERROR` + Sentry Alert rule on the tag |
| Ship vitals to **non-Sentry** backends (Loki, Datadog, OTel) | **A** — the logger fans out to every transport |
| Validate the pipeline during development | **A** with all ratings at ERROR (noisy but visible in Issues) |
The two paths are complementary and can run in parallel. In production the
common setup is **Path B for analytics + Path A as breadcrumbs** — you get
the aggregate view under Performance and contextual vitals on every error,
without a single extra Issue.
---
## Patterns

@ -196,8 +196,16 @@
registerWebVitals(logger, webVitals, {
// Custom tag so we can filter this page's vitals easily in dashboards.
tags: ['test-page'],
// Promote 'poor' to ERROR to stand out visually in the table.
levels: { poor: LogLevel.ERROR }
// In this test page we promote every rating to ERROR so Sentry shows
// them as Issues — useful to validate the pipeline reaches the
// dashboard. In production you would keep the defaults (good=DEBUG,
// needs-improvement=INFO, poor=WARN) and route vitals through
// breadcrumbs or a metrics sink, not as individual Issues.
levels: {
good: LogLevel.ERROR,
'needs-improvement': LogLevel.ERROR,
poor: LogLevel.ERROR
}
});
vitalsEnabled = true;
}
@ -231,7 +239,12 @@
environment: 'logr-test',
release: 'logr-test@1.0.0',
sampleRate: 1.0,
tracesSampleRate: 0
// Browser tracing captures native Web Vitals (LCP/INP/CLS/FCP/TTFB)
// and sends them as Performance data — visible under
// "Insights → Browser → Web Vitals" in the Sentry dashboard.
integrations: [Sentry.browserTracingIntegration()],
// 1.0 = every page load sends a transaction; lower it in production.
tracesSampleRate: 1.0
});
persistDsn();
sentryStatus = 'ready';

Loading…
Cancel
Save

Powered by TurnKey Linux.