- 可观测性
- 后端
【免费下载链接】highlight
highlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.
highlight.io 为基于 Electron 构建的桌面应用提供了专门的 SDK 集成方案。本文以 electron-integration.md 为主线,讲解如何通过configureElectronHighlight监听主进程BrowserWindow的 focus/blur 事件,在应用最小化或失焦时自动停止录制、恢复可见时自动续录,从而降低会话回放对 Electron 用户性能与电池的额外消耗,并同步给出仓库内 highlight.run SDK 的源码级实现佐证。
为什么 Electron 应用需要专门的可见性处理
Electron 是典型的桌面端 JS 框架,主进程管理窗口生命周期,渲染进程运行页面 UI。浏览器中的 Tab 页可以通过document.visibilitychange/Page Visibility API感知前台/后台切换,但 Electron 渲染进程并不总能感知"窗口被最小化到任务栏"这类窗口级事件。如果不做处理,会话录制会在用户完全看不到界面时继续采集屏幕与交互数据,白白消耗 CPU、内存与电量。
highlight.io 的应对方式是:在主进程监听窗口的focus/blur(乃至close)事件,通过 IPC 把可见性状态转发给渲染进程,再由 SDK 内部把它归一化为hidden标志,从而统一驱动录制启停逻辑。这也是 highlight.run@4.3.4 及以上版本 内置configureElectronHighlight能力的由来。
前置条件与最小接入代码
官方文档要求 SDK 版本不低于highlight.run@4.3.4,当前仓库中highlight.run的版本号已经迭代到 9.16.0,configureElectronHighlight自 SDK 入口 以具名导出方式提供。接入只需两步:
- 安装 SDK:
# npm npm install highlight.run # 或 yarn yarn add highlight.run # 或 pnpm pnpm add highlight.run- 在主进程拿到
BrowserWindow实例后,调用configureElectronHighlight完成埋点:
const { app, BrowserWindow } = require('electron'); const mainWindow = new BrowserWindow({ /* ... */ }); // 传入 BrowserWindow 对象即可完成主进程事件监听 configureElectronHighlight(mainWindow);需要注意该函数必须在mainWindow创建之后调用;源码中对入参做了防御性检查,只有满足window.on && window.webContents?.send时才会挂载事件,避免在非法对象上报错(见 electron.ts)。
渲染进程侧仍需像普通 Web 应用一样先完成 SDK 初始化(H.init),Electron 集成只是在此基础上的补充。完整的初始化示例可参考 Electron 快速上手组件:
// hooks.client.ts / 渲染进程入口 import { H } from 'highlight.run'; H.init('<YOUR_PROJECT_ID>', { serviceName: 'frontend-app', environment: 'production', version: 'commit:abcdefg12345', tracingOrigins: true, networkRecording: { enabled: true, recordHeadersAndBody: true, urlBlocklist: [ // 插入你不希望被录制的完整或部分 URL // 开箱即用,Highlight 不会录制以下 URL(可以安全移除) 'https://www.googleapis.com/identitytoolkit', 'https://securetoken.googleapis.com', ], }, });<YOUR_PROJECT_ID>需要替换为你在 highlight.io 控制台创建的 Project ID,它同时用于H.init与后端数据关联。
主进程到渲染进程的事件转发链路
configureElectronHighlight的完整实现只有十余行,位于 sdk/highlight-run/src/environments/electron.ts:
export default function configureElectronHighlight(window: any) { if (window.on && window.webContents?.send) { window.on('focus', () => { window.webContents.send('highlight.run', { visible: true }) }) window.on('blur', () => { window.webContents.send('highlight.run', { visible: false }) }) window.on('close', () => { window.webContents.send('highlight.run', { visible: false }) }) } }可以看到它实际上做了三件事:
- 窗口获得焦点(
focus)→ 向渲染进程发送{ visible: true }; - 窗口失去焦点(
blur,包括被最小化、被其他窗口遮挡、切到别的应用)→ 发送{ visible: false }; - 窗口关闭(
close)→ 也发送{ visible: false },确保会话在关闭前正确收尾,避免产生残缺录制段。
highlight.run既是消息的 channel 名称,与 渲染进程的 IPC 订阅 严格对应。官方文档中给出的手工等价写法如下:
mainWindow.on('focus', () => { mainWindow.webContents.send('highlight.run', { visible: true }); }); mainWindow.on('blur', () => { mainWindow.webContents.send('highlight.run', { visible: false }); });这正是configureElectronHighlight内部替你完成的逻辑,文档中的示例可以视为该函数的行为说明。
渲染进程如何消费可见性消息
渲染进程侧,SDK 在初始化监听器时优先检测是否存在 Electron 的 IPC 通道(window.electron?.ipcRenderer),存在则订阅highlight.run消息,否则退回浏览器原生 Page Visibility 监听,二者二选一只注册一次(见 client/index.tsx):
if (window.electron?.ipcRenderer) { window.electron.ipcRenderer.on( 'highlight.run', ({ visible }: { visible: boolean }) => { this._visibilityHandler(!visible) }, ) this.logger.log('Set up Electron highlight.run events.') } else { PageVisibilityListener((isTabHidden) => this._visibilityHandler(isTabHidden), ) this.logger.log('Set up document visibility listener.') }两条路径最终汇入同一个_visibilityHandler(hidden),它维护了以下状态机:
- 变为不可见(
hidden === true):写入TabHidden自定义事件;若开启了disableBackgroundRecording,则调用stopRecording()停止录制; - 变为可见(
hidden === false):若开启了disableBackgroundRecording,则重新initialize()续录,并写入TabHidden = false事件。
此外,_visibilityHandler内置了 100ms 的防抖(常量定义于 sdk/highlight-run/src/client/constants/sessions.ts),且会跳过manualStopped(手动停止)状态下的可见性事件,避免快速来回切换窗口时反复启停录制造成抖动(见 client/index.tsx)。
关键选项:disableBackgroundRecording
需要强调的是:Electron 集成默认并不会在失焦时停止录制,它只是把可见性事件送达 SDK。是否真正停止录制取决于H.init配置中的disableBackgroundRecording:
H.init('<YOUR_PROJECT_ID>', { // 应用不可见(最小化/失焦)时不录制 disableBackgroundRecording: true, });该选项在 sdk/highlight-run/src/client/types/types.ts 中定义:If set, Highlight will not record when your app is not visible (in the background). By default, Highlight will record in the background.默认值为false,即默认在后台继续录制。
官方文档明确说明,这样做的收益是:当应用不可见时暂停 Highlight 录制、恢复可见时续录,以最小化 Highlight 对 Electron 用户带来的性能与电池影响。桌面应用常驻后台,这一开关对耗电敏感场景(如笔记本、长时间挂机)尤为实用。
完整接入清单(对照仓库快速上手内容)
仓库的 Electron 快速上手组件(highlight.io/components/QuickstartContent/frontend/electron.tsx)给出的标准接入顺序如下,可作为落地清单:
- 安装 npm 包:
highlight.run; - 初始化 SDK:用
H.init('<YOUR_PROJECT_ID>', options)完成渲染进程侧初始化,推荐配置tracingOrigins与networkRecording以打通前后端错误关联; - Instrument Electron events:创建
BrowserWindow后调用configureElectronHighlight(mainWindow),监听窗口 focus/blur/close 事件; - 识别用户(可选但推荐):在登录流程完成后调用
H.identify(identifier, metadata),便于按用户检索会话; - 验证安装:到 highlight.io 控制台的会话列表中确认新会话出现(注意移除
Status is Completed过滤器以查看进行中的会话); - (可选)配置 Sourcemap:使用
@highlight-run/sourcemap-uploader在 CI 中上传 sourcemap,以获得增强的错误堆栈; - (可选)后端埋点:为后端接入 highlight.io,将日志/错误与前端会话关联。
小结
Electron 场景下,highlight.io 用一条"主进程事件 → IPC 消息 → 渲染进程可见性处理"的链路,把桌面窗口的最小化、失焦、关闭与浏览器侧的页面可见性语义对齐。接入成本极低:安装highlight.run并调用一次configureElectronHighlight(mainWindow),配合disableBackgroundRecording: true,即可让会话录制随窗口可见性智能启停,兼顾可观测性与桌面端资源消耗。相关源码可继续查阅 sdk/highlight-run/src/environments/electron.ts、sdk/highlight-run/src/client/index.tsx 与 sdk/highlight-run/src/client/types/types.ts。
- 可观测性
- 后端
【免费下载链接】highlight
highlight.io: The open source, full-stack monitoring platform. Error monitoring, session replay, logging, distributed tracing, and more.
相关推荐
highlight.io Electron 接入指南:桌面应用的会话回放、错误监控与主进程窗口事件追踪
highlight.io Electron 接入指南:桌面应用的会话回放、错误监控与主进程窗口事件追踪 本篇指南基于 highlight.io(开源全栈监控平台
可观测性后端Docker-Selenium视频禁用:按会话控制录制功能开关
Docker Selenium视频禁用:按会话控制录制功能开关 还在为自动化测试视频录制占用大量存储空间而烦恼?本文教你如何精准控制Docker Seleniu
测试后端云原生容器编排可观测性shadPS4模拟器:在PC上体验PS4游戏的终极开源解决方案
shadPS4模拟器:在PC上体验PS4游戏的终极开源解决方案 shadPS4是一款基于C++开发的开源PS4模拟器,支持Windows、Linux和macOS
虚拟化图形学桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考