feat(desktop): report panel freezes and time task open
Merged
CH
4d ago+897+897+012345678901234567890123456789-23-23-01234567890123456789
PR 1 of the performance rollout: make freezes and slow task opens visible in Sentry so the later fixes are measured. No loading behaviour changes.
What it does
- Panel freeze detection. The panel window's renderer SDK adds
eventLoopBlockIntegration({ threshold: 1000 }); the voice and call windows don't (mountWindow(surface, { reportsFreezes: true })fromindex.tsxonly). Main needs no change:@sentry/electron8.2.0's main defaults already includerendererEventLoopBlockIntegration, and main'sintegrations: [startupTracingIntegration()]is merged with those defaults. - Unresponsive panel. New
apps/desktop/src/main/window/renderer-health.tsfollows each panel BrowserWindow'sunresponsive/responsive/closedas an Effect stream and reports one Sentry event per episode: when the page answers again, or when the window closes while still frozen (recovered: false). The event carries the duration and the page'sapp.getAppMetrics()working set read as it froze. Repeatedunresponsivewithin an episode counts once. Wired via a newfollowResponsivenessoption onPanelManager. Unlike the voice window, the panel isn't replaced. - Memory.
sampleWindowMemoryreads every window's working set every 60 s onSchedule.spaced, run from the telemetry service's own scope (closed at stop). It leaves a breadcrumb only when a window crosses 1.5 GB: not on every sample while it stays above, and again only after it drops below and crosses back. - Spans (sampled at
SENTRY_TRACES_SAMPLE_RATE, each started as its own trace):task.open: from the press inopenTaskuntil the document region is READY for that task. A refused or replaced ask, a leave, or reopening the task already open records nothing. Taggedtask.plan_chars.transcript.first_paint: from opening the follow to the commit after its first page. Taggedtranscript.message_countandtranscript.page_bytes.transcript.caught_up: from opening the follow to the page with nothing more. Same tags.- The panel reaches Sentry through a new door,
@luke/panel/panel-spans. If no recorder is installed (tests, web), it records nothing. Attributes are typed as numbers only, so no message text or credential can get in. They are also read lazily, only for a span the sampler keeps, so an unsampled span never serializes a page.
- Slow frames.
enableLongAnimationFrame: trueis set explicitly onbrowserTracingIntegrationfor desktop and web. INP is already reported by the 11.7.0 SDK's default web vitals. Its oldenableInpswitch is deprecated, so it isn't set.
Tests
renderer-health.test.ts(fake window,TestClock): one report per unresponsive episode with its duration and working set, a second episode is reported separately, a close while frozen is reported as not recovered, and the listeners are removed. The memory sampler leaves nothing under the bound, nothing between samples, one breadcrumb on crossing, none while it stays over, and another after dropping below and crossing again.desktop-sentry.test.ts(real SDK, IPC as the boundary): only the panel registers with main's freeze watchdog, at 1000 ms. A span recorded before the SDK loads is sent with its attributes. An unsampled span never reads its attributes.use-agent-transcript.test.ts/use-tasks-tab.test.ts: the three spans, their durations and attributes. A follow released before its first page, and a refused open, record nothing.
Not in this PR
Spans on the web tab (the door supports it, but web installs no recorder yet), PostHog, the server.
Made with Luke