Skip to content

Commit 8836546

Browse files
adeebshihadehclaude
andcommitted
revert to sentry, log all sessions with serial
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 8193ff2 commit 8836546

File tree

6 files changed

+256
-91
lines changed

6 files changed

+256
-91
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
VITE_SENTRY_DSN=https://acb8cfad1992fafc3dc90ab1bfa3d07f@o33823.ingest.us.sentry.io/4510604761825280

package-lock.json

Lines changed: 0 additions & 59 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
"@commaai/qdl": "git+https://github.com/commaai/qdl.js.git#21d7be79fa5178f253d32a0879bd8bdd4fa37e30",
1717
"@fontsource-variable/inter": "^5.2.5",
1818
"@fontsource-variable/jetbrains-mono": "^5.2.5",
19-
"@openreplay/tracker": "^17.1.0",
2019
"react": "^18.3.1",
2120
"react-dom": "^18.3.1",
2221
"xz-decompress": "^0.2.2"

src/app/Flash.jsx

Lines changed: 101 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useEffect, useRef, useState } from 'react'
2-
import { tracker } from '../main'
2+
import { addBreadcrumb, setTags, setTag, setContext, captureSessionSummary } from '../utils/telemetry'
33

44
import { FlashManager, StepCode, ErrorCode, DeviceType } from '../utils/manager'
55
import { useImageManager } from '../utils/image'
@@ -51,6 +51,41 @@ const originalConsole = { log: console.log, warn: console.warn, error: console.e
5151
}
5252
})
5353

54+
// Unique per-page session id for correlating events
55+
const SESSION_ID = (crypto && 'randomUUID' in crypto) ? crypto.randomUUID() : String(Math.random()).slice(2)
56+
57+
// Helper for building environment metadata
58+
function buildEnvMeta() {
59+
const ua = navigator.userAgent
60+
let os = 'Unknown'
61+
if (ua.includes('Windows NT 10.0')) os = 'Windows 10/11'
62+
else if (ua.includes('Windows NT 6.3')) os = 'Windows 8.1'
63+
else if (ua.includes('Windows NT 6.2')) os = 'Windows 8'
64+
else if (ua.includes('Windows NT 6.1')) os = 'Windows 7'
65+
else if (ua.includes('Mac OS X')) {
66+
const match = ua.match(/Mac OS X (\d+[._]\d+[._]?\d*)/)
67+
os = match ? `macOS ${match[1].replace(/_/g, '.')}` : 'macOS'
68+
} else if (ua.includes('Linux')) {
69+
os = 'Linux'
70+
if (ua.includes('Ubuntu')) os += ' (Ubuntu)'
71+
else if (ua.includes('Fedora')) os += ' (Fedora)'
72+
else if (ua.includes('Debian')) os += ' (Debian)'
73+
} else if (ua.includes('CrOS')) os = 'ChromeOS'
74+
75+
const sandboxHints = []
76+
if (ua.includes('snap')) sandboxHints.push('Snap')
77+
if (ua.includes('Flatpak')) sandboxHints.push('Flatpak')
78+
if (navigator.userAgentData?.brands?.some(b => b.brand.includes('snap'))) sandboxHints.push('Snap')
79+
80+
return {
81+
os,
82+
sandbox: sandboxHints.length ? sandboxHints.join(', ') : 'None detected',
83+
browser: navigator.userAgent,
84+
url: window.location.href,
85+
version: import.meta.env.VITE_PUBLIC_GIT_SHA || 'dev',
86+
}
87+
}
88+
5489
// Debug info component for error reporting
5590
function DebugInfo({ error, step, selectedDevice, serial, message, onClose }) {
5691
const [copied, setCopied] = useState(false)
@@ -640,12 +675,33 @@ export default function Flash() {
640675
.then((programmer) => {
641676
// Create QDL manager with callbacks that update React state
642677
qdlManager.current = new FlashManager(programmer, {
643-
onStepChange: setStep,
644-
onMessageChange: setMessage,
645-
onProgressChange: setProgress,
646-
onErrorChange: setError,
647-
onConnectionChange: setConnected,
648-
onSerialChange: setSerial,
678+
onStepChange: (s) => {
679+
setStep(s)
680+
addBreadcrumb({ category: 'flash', message: `step:${s}`, level: 'info', data: { step: s } })
681+
setTag('last_step', String(s))
682+
},
683+
onMessageChange: (m) => {
684+
setMessage(m)
685+
if (m) addBreadcrumb({ category: 'flash', message: m, level: 'info' })
686+
},
687+
onProgressChange: (p) => {
688+
setProgress(p)
689+
},
690+
onErrorChange: (e) => {
691+
setError(e)
692+
if (e !== ErrorCode.NONE) {
693+
addBreadcrumb({ category: 'flash', message: 'error', level: 'error', data: { errorCode: e } })
694+
setTag('error_code', String(e))
695+
}
696+
},
697+
onConnectionChange: (c) => {
698+
setConnected(c)
699+
addBreadcrumb({ category: 'flash', message: c ? 'connected' : 'disconnected', level: c ? 'info' : 'warning' })
700+
},
701+
onSerialChange: (sn) => {
702+
setSerial(sn)
703+
setTag('serial', sn)
704+
}
649705
})
650706

651707
// Initialize the manager
@@ -657,34 +713,59 @@ export default function Flash() {
657713
})
658714
}, [config, imageManager.current])
659715

660-
// OpenReplay: set metadata when device is selected
716+
// Telemetry: set static tags/context once
717+
useEffect(() => {
718+
setTags({ session_id: SESSION_ID })
719+
setContext('env', buildEnvMeta())
720+
}, [])
721+
722+
// Telemetry: tag device selection
661723
useEffect(() => {
662724
if (selectedDevice) {
663-
tracker.setMetadata('deviceType', selectedDevice)
725+
setTag('device_type', selectedDevice)
726+
addBreadcrumb({ category: 'flash', message: `device:${selectedDevice}`, level: 'info' })
664727
}
665728
}, [selectedDevice])
666729

667-
// OpenReplay: set serial as user ID and metadata
730+
// Telemetry: wizard screen transitions
668731
useEffect(() => {
669-
if (serial) {
670-
tracker.setUserID(serial)
671-
tracker.setMetadata('serial', serial)
732+
if (wizardScreen) addBreadcrumb({ category: 'wizard', message: wizardScreen, level: 'info' })
733+
}, [wizardScreen])
734+
735+
// Helper to send a single pass/fail summary
736+
function sendSessionSummary(result) {
737+
if (reportSentRef.current) return
738+
reportSentRef.current = true
739+
const meta = {
740+
...buildEnvMeta(),
741+
selectedDevice,
742+
connected,
743+
serial,
744+
step,
745+
message,
672746
}
673-
}, [serial])
747+
const tail = consoleLogs.slice(-200)
748+
captureSessionSummary({
749+
sessionId: SESSION_ID,
750+
result,
751+
errorCode: error,
752+
step,
753+
meta,
754+
consoleTail: tail,
755+
})
756+
}
674757

675-
// OpenReplay: track session result
758+
// Send report on failure
676759
useEffect(() => {
677760
if (error !== ErrorCode.NONE && !reportSentRef.current) {
678-
reportSentRef.current = true
679-
const errorName = Object.keys(ErrorCode).find(k => ErrorCode[k] === error) || 'UNKNOWN'
680-
tracker.event('flash_result', { result: 'fail', errorCode: error, errorName, step, serial })
761+
sendSessionSummary('fail')
681762
}
682763
}, [error])
683764

765+
// Send report on success
684766
useEffect(() => {
685767
if (step === StepCode.DONE && error === ErrorCode.NONE && !reportSentRef.current) {
686-
reportSentRef.current = true
687-
tracker.event('flash_result', { result: 'pass', serial })
768+
sendSessionSummary('pass')
688769
}
689770
}, [step, error])
690771

src/main.jsx

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
import React from 'react'
22
import ReactDOM from 'react-dom/client'
3-
import Tracker from '@openreplay/tracker'
3+
import { initSentry } from './utils/telemetry'
44

55
import '@fontsource-variable/inter'
66
import '@fontsource-variable/jetbrains-mono'
77

88
import './index.css'
99
import App from './app'
1010

11-
// Initialize OpenReplay session tracking
12-
const tracker = new Tracker({
13-
projectKey: 'rN9Ir1HEKHJDs8P5rymv',
14-
__DISABLE_SECURE_MODE: location.hostname === 'localhost',
15-
})
16-
tracker.start()
17-
18-
// Export for use in other components
19-
export { tracker }
20-
2111
// Explicitly load fonts before rendering to prevent FOUT
2212
async function loadFonts() {
2313
await Promise.all([
@@ -26,6 +16,9 @@ async function loadFonts() {
2616
])
2717
}
2818

19+
// Initialize telemetry (no-op if DSN unset)
20+
initSentry()
21+
2922
loadFonts().then(() => {
3023
ReactDOM.createRoot(document.getElementById('root')).render(
3124
<React.StrictMode>

0 commit comments

Comments
 (0)