Repository navigation
feat(telemetry): export reliability by browser and device - #1829
Merged
Merged
Conversation
- claude-manager.yml (claude-pr-review): skip draft PRs (`github.event.pull_request.draft == false`), keep the event and author restrictions, rename the step, and replace "squash-merge the PR" with a comment that the PR is ready for a maintainer. The prompt now forbids merging, approving, enabling auto-merge, pushing and marking drafts ready. Permissions unchanged (contents: read). - CLAUDE.md: PR Automation no longer merges; automatic conflict resolution (git merge + push to the PR branch) becomes guidance in a comment; General Rules no longer list "merge PRs". - scripts/ci/check-pr-automation.mjs: fails on merge commands/APIs in any workflow, contents: write / write-all in a Claude job, a PR-writing Claude job without a draft guard, and affirmative merge/push instructions in prompts or CLAUDE.md. Run in lint.yml; unit-tested with passing and failing fixtures (it flags all six items on main today). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The previous commit rewrote the file with LF; the net change against main is now only the two added lines. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t-config-next #1823 bumped next to 16.4.1 in package.json only, and react-dom had stayed at 19.2.8 while react is 19.3.0, so bun.lock no longer matched package.json: - `bun install --frozen-lockfile` failed; - the lockfile still pinned next 16.3.4 (critical advisories), while plain installs got 16.4.1; - a plain install paired react 19.3.0 with react-dom 19.2.8, so 5 test files failed to load with "Incompatible React versions". react-dom 19.2.8 → 19.3.0 and eslint-config-next 16.3.4 → 16.4.1 (matching next); bun.lock regenerated (42 entries, Next.js packages and the sharp patch Next requires; no majors). Verified: frozen install, 20/20 test files and 241 tests (was 5 files failing), typecheck, lint, production build. bun audit: next now has 0 advisories; the remaining critical is Storybook's dev server (dev-only), handled in the security pipeline work. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Report one outcome per export attempt (export_started, then exactly one of export_succeeded / export_failed / export_cancelled) with bucketed context: format, resolution, input size, clip length, overlays, engine, stage, failure category and retry state. Browser, OS and device type come from RUM itself. - exportTelemetry.ts: ExportAttempt and per-worker engine-load events - telemetry.ts: fail-closed env resolution (local hosts and automated browsers never report; production needs the deploy context), scrubbing of file names, captions and paths in beforeSend, handled-error prefix - next.config.ts: bake the host's deploy context into NEXT_PUBLIC_DEPLOY_CONTEXT so production keeps reporting - docs/DATADOG.md and an importable dashboard definition (untested import; no Datadog API access). Queries use @action.target.name. Session replay stays disabled. User-facing error messages are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
👋 Thanks for your PR, @magic-peach!Welcome to Reframe — a browser-based video editor built for everyone 🎬 What happens next
Quick checklist
Useful links
Happy coding! 🎉 |
Contributor
|
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
✅ Deploy Preview for reframe-os ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
magic-peach
marked this pull request as ready for review
November 3, 2026 06:55
Contributor
|
Claude encountered an error —— View job I'll analyze this and get back to you. |
This was referenced Nov 3, 2026
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.
Targets
mainand includes #1827 and #1828 (they are ancestors of this branch, so a merge commit closes them too).What this adds
Export reliability by browser and device, from Datadog RUM.
Each export sends
export_started, then exactly one ofexport_succeeded,export_failedorexport_cancelled. The events carry bucketed context: format, resolution, input size, clip length, whether there's text, music or an image overlay, engine (multi-/single-threaded), stage (engine start / encoding), failure category and retry state. Browser, OS and device type come from RUM itself. Engine loads reportffmpeg_load_success/ffmpeg_load_failureonce per worker.src/lib/exportTelemetry.ts:ExportAttempt(one outcome per attempt; a cancel followed by a late rejection counts once) andstartEngineLoad.src/lib/telemetry.ts:productionrequires the host's deploy context.beforeSendscrubs file names, captions, local paths andblob:URLs.[reframe:handled]prefix so RUM doesn't count them twice.next.config.ts: bakes Netlify'sCONTEXT/ Vercel'sVERCEL_ENVintoNEXT_PUBLIC_DEPLOY_CONTEXT. Without this, production would stop reporting.src/lib/ffmpeg.ts,ffmpeg.worker.ts: the worker reports which engine loaded;getEngineMode()is added.src/hooks/useVideoEditor.ts: wires the attempt into export, cancel and retry. Messages users see are unchanged.docs/DATADOG.md: event schema, privacy rules, query syntax (custom actions are@action.target.name, not@action.name), facet setup and import steps.docs/datadog/export-reliability.dashboard.json: an importable dashboard (17 widgets) with success rate overall and by browser, device, OS, format, resolution and engine, each next to its sample size; GIF exports on mobile; failure categories by browser and device; retry recovery.Privacy
No file names, contents, captions, paths or exact values are sent; a test fails if any property outside the allowed list appears. Session replay stays disabled.
Verified on the deploy preview (2026-11-03)
env: preview, andNEXT_PUBLIC_DEPLOY_CONTEXTis baked in asdeploy-preview.export_started(format, resolution, buckets),ffmpeg_load_success(engine: multi, first load) and oneexport_cancelled(stage: encode), all visible through the Datadog RUM API with the expected@context.*paths, browser, OS and device.export_succeeded/export_failedfrom a real browser. See the note below on the clips I could generate.In Datadog now
2tw-pge-qkk, created fromdocs/datadog/export-reliability.dashboard.json.env:production: failed exports, engine load failures, missing isolation, frontend error spike. IDs are indocs/DATADOG.md.Existing bug found while testing (not caused by this PR)
Browser-recorded clips (MediaRecorder WebM/MP4, e.g. screen recordings) have no duration in their metadata.
getVideoDurationinsrc/lib/ffmpeg.tsreturnsInfinity, the args get-t Infinity, and the export hangs at 100% indefinitely. The same file hangs on production (main). The stall detector doesn't catch it. To be fixed separately.Checks run locally
exportTelemetry.hook.test.ts(failure → retry, cancel, engine-load failure) and DatadogInit on local, production and preview hosts.NEXT_PUBLIC_DATADOG_ENV=off) pass.