Electron 监测¶
Windows SDK 通过 Native Bridge 接入 Electron:Renderer 中的 Browser RUM 和 Browser Logs 负责采集页面数据,Electron Main Process 将数据交给 Windows Native Core,由 Native Core 统一管理应用 ID、Session、采样、全局上下文、持久化队列和上传。
根据 Native SDK 的初始化所有者选择一种模式:
| 模式 | 适用场景 | Native Runtime 来源 | SDK 所有者 |
|---|---|---|---|
混合模式(external) |
C++ 桌面应用中嵌入 Electron 页面 | 宿主提供,例如 vcpkg 基础包 | C++ 宿主 |
全量模式(managed) |
应用本身是 Electron | npm 安装时下载,也支持显式指定目录 | Adapter 管理的 Bridge EXE |
两种模式不能同时使用。页面侧共用相同的 Preload、attachWindow() 和 Renderer 初始化方式。
该方式不同于 Web RUM 的 Electron 独立接入。Windows SDK 集成中,Renderer 不直接上传数据,也不配置真实应用 ID、上报地址或 Client Token。
数据流如下:
Electron Renderer
@cloudcare/browser-rum / @cloudcare/browser-logs 采集器
|
| FTWebViewJavascriptBridge.sendEvent(JSON)
v
安全 Preload -> 白名单 IPC -> Electron Main Process
|
v
Windows Native Core(由 C++ 宿主或 Bridge EXE 初始化)
原生 RUM / Log / 会话 / 采样 / 上下文 / 持久化 / 上传
集成 Electron¶
安装依赖¶
在 Electron 项目中安装 Native Adapter 和 Browser SDK:
不采集 Browser Log 时,可以不安装 @cloudcare/browser-logs。
Browser Logs 的 Bridge 接入要求 3.3.6 或更高版本。
已验证的 Electron 基线为 22.3.27 和 43.x,声明的兼容范围为 ^22.3.27 || 43.x,中间主版本尚未验证。Electron 22 是 Windows 7 SP1 的旧版兼容基线,Electron 43 要求 Windows 10 或更高;仍需验证目标操作系统与 Native Runtime 的组合。
npm 安装和运行时安装器要求 Node.js 18+;打包后的应用用户无需另行安装 Node.js。Windows 支持 x64、x86(Electron/Node.js 中为 ia32)和 arm64,需要安装与运行时架构匹配的 Microsoft Visual C++ v14 Redistributable 和 Windows Universal CRT。
发布的 npm 包本身不内置 Native 二进制,但 postinstall 会按平台和架构下载并校验 Native Runtime,无需本地编译。全量模式默认自动定位该运行时,不需要先安装 vcpkg。Adapter 同时支持 macOS;本页介绍 Windows Native Bridge 接入。
重要版本节点
Adapter 0.1.0-alpha.3 增加 Windows x86/arm64 运行时选择、校验与打包支持,并将默认 Native Runtime 固定为 Windows SDK vcpkg_0.1.0-alpha.8、macOS SDK 1.6.8-alpha.6。这些是该版本的默认依赖,不代表后续版本始终使用相同 Native SDK。
Adapter、Windows SDK 和 macOS SDK 分别维护版本。实际默认值以所安装 npm 包的 package.json.nativeRuntime 为准。
仅使用混合模式时,可在安装前设置 PowerShell 环境变量 $env:GUANCE_NATIVE_SKIP_DOWNLOAD = "1",跳过不使用的运行时下载;切换回全量模式安装前需清除此变量。
可选:由 vcpkg 提供 Native Runtime¶
宿主拥有 Native SDK,或需要自行构建运行时时,按照快速开始配置 SDK vcpkg 注册表。JavaScript Adapter 仍由 npm 单独安装。手动提供全量模式运行时时启用 electron-bridge:
{
"dependencies": [
{
"name": "guance-windows-native",
"default-features": false,
"features": ["electron-bridge"]
}
]
}
混合模式只安装基础 Native 包,不启用 Electron Feature:
在 vcpkg.json 所在目录执行:
集成时只使用以下公开入口:
@cloudcare/electron-native-adapter:Main Process 的统一bootstrap()入口;@cloudcare/electron-native-adapter/preload/standalone:应用没有现有 Preload 时直接使用;@cloudcare/electron-native-adapter/preload/install:应用已有 Preload 时,由 bundler 合并到业务 Preload。
不要复制 Adapter 源码,也不要引用 npm 包中未通过 exports 声明的内部文件。
以上 vcpkg 命令以 x64 为例。手动使用 vcpkg 工具目录时,将下面的 sdkDirectory 传入 native.directory;默认 npm 下载流程无需配置此项:
const path = require("node:path");
const { app } = require("electron");
const sdkDirectory = app.isPackaged
? path.join(process.resourcesPath, "guance-windows-native")
: path.resolve(
__dirname,
"../../../vcpkg_installed/x64-windows/tools/guance-windows-native",
);
开发目录的相对层级应按应用结构调整,不要依赖当前工作目录或写死开发机绝对路径。
初始化 Native Bridge¶
混合模式¶
C++ 宿主先初始化 Windows SDK,再将 Bridge Server 绑定到已有的 guance_sdk_handle:
guance_sdk_handle sdk = guance_sdk_init(&config);
guance_electron_bridge_server_options options{};
guance_electron_bridge_server_options_init(&options);
options.pipe_name = "my-app-rum";
options.logging_enabled = 1;
options.session_replay_enabled = 0;
options.replay_privacy_level = "mask";
guance_electron_bridge_server_handle bridge =
guance_electron_bridge_server_start(sdk, &options);
// 应用退出时先停止 Bridge Server,再关闭 SDK。
guance_electron_bridge_server_stop(bridge);
guance_sdk_shutdown(sdk);
Electron Main Process 连接同名 named pipe:
const electron = require("electron");
const { bootstrap } = require("@cloudcare/electron-native-adapter");
const rumBridge = await bootstrap({
electron,
native: {
mode: "external",
pipeName: "my-app-rum",
},
enableAppLaunch: true,
});
混合模式下:
- 不要启动
guance_windows_electron_bridge.exe,否则会创建第二个 SDK Handle; - Electron 不再传入应用 ID、DataKit/Dataway、缓存或上传配置;
- C++ 宿主必须保证 SDK Handle 的生命周期长于 Bridge Server;
- 采集 Browser Log 时,需要同时启用 Native 自定义日志,并将
logging_enabled设为1。
全量模式¶
应用本身是 Electron 时,由 Main Process 启动并管理 Bridge EXE。在 app.whenReady() 完成后、加载 Renderer 页面前执行以下初始化:
const electron = require("electron");
const path = require("node:path");
const { bootstrap } = require("@cloudcare/electron-native-adapter");
const rumBridge = await bootstrap({
electron,
native: {
mode: "managed",
settings: {
applicationId: "<rum-application-id>",
datakitUrl: "http://127.0.0.1:9529",
service: "electron-desktop-client",
environment: "prod",
version: electron.app.getVersion(),
cachePath: path.join(electron.app.getPath("userData"), "native-rum-cache"),
sampleRate: 1,
loggingEnabled: true,
loggingSampleRate: 1,
replayEnabled: false,
replaySampleRate: 1,
replayPrivacy: "mask",
debug: false,
},
},
enableAppLaunch: true,
});
使用 DataWay 上报时,将 datakitUrl 替换为 datawayUrl 和 clientToken。applicationId、service、environment、version 必填,并且必须提供 DataKit 或 DataWay 地址。
Native RUM、Log、Replay 和 Trace 的采样率取值均为 0 到 1,默认均为 1。loggingEnabled、replayEnabled、traceEnabled、debug 默认关闭;示例显式开启了日志。replayPrivacy 支持 allow、mask-user-input、mask,默认 mask。
其他可选配置:
| 位置 | 参数 | 说明 |
|---|---|---|
native.settings |
traceEnabled、traceSampleRate |
配置 Native Trace 开关与采样率 |
native.settings |
traceType |
默认 w3c_traceparent |
native.settings |
traceAllowedUrls |
Native Trace URL 规则字符串 |
native.settings |
httpTimeoutMs |
上传超时,默认 10000 毫秒,范围 1..300000 |
native(managed) |
readyTimeoutMs、stopTimeoutMs |
启动握手与退出等待时间,默认 10000、3000 毫秒 |
native(managed) |
onNativeOutput |
接收 (stream, text),用于诊断 Bridge 标准输出和错误输出 |
native(external) |
timeoutMs、retryDelayMs |
连接超时与重试间隔,默认 10000、100 毫秒 |
bootstrap() |
onError |
接收异步传输和窗口处理错误 |
应用退出前需要等待 rumBridge.stop() 完成,例如:
let stopping = false;
electron.app.on("before-quit", (event) => {
event.preventDefault();
if (stopping) return;
stopping = true;
rumBridge.stop().then(() => electron.app.exit(0), (error) => {
console.error(error);
electron.app.exit(1);
});
});
bootstrap() 返回统一的 Client,提供 capabilities、attachWindow()、detachWindow()、updateWindow()、transportState 和幂等的 stop()。transportState 用于检查可写状态、背压和传输失败。startFullMode() 与 connectMixedMode() 仅作为早期版本兼容入口保留,新接入统一使用 bootstrap()。
Adapter 默认启用 enableAppLaunch,会结合 Electron 应用生命周期、可信窗口首帧和 Browser View 上下文自动生成 launch_cold、launch_hot Action;不需要自动启动 Action 时设置为 false。为保证冷启动关联首个 Browser View,应尽早启动或连接 Bridge,并在创建窗口后立即调用 attachWindow()。
接入 Preload 与窗口¶
每个需要采集的窗口都必须加载 Guance Preload,并通过 attachWindow() 登记为可信窗口。保持以下 Electron 安全配置:
contextIsolation: true;nodeIntegration: false;sandbox: true。
应用没有现有 Preload 时,直接使用 standalone.cjs:
const standalonePreloadPath = require.resolve(
"@cloudcare/electron-native-adapter/preload/standalone",
);
const { BrowserWindow } = require("electron");
const window = new BrowserWindow({
webPreferences: {
preload: standalonePreloadPath,
contextIsolation: true,
nodeIntegration: false,
sandbox: true,
},
});
const detachWindow = rumBridge.attachWindow(window);
window.webContents.once("destroyed", detachWindow);
应用已有 Preload 时,将 @cloudcare/electron-native-adapter/preload/install 作为 webpack、esbuild 等 bundler 的构建依赖,并在业务 Preload 中调用一次:
const {
installElectronRumPreload,
} = require("@cloudcare/electron-native-adapter/preload/install");
installElectronRumPreload();
启用 sandbox: true 时,最终 Preload 产物必须是一个可由 webPreferences.preload 直接加载的自包含 bundle。例如可以使用 esbuild,并将 Electron 保留为运行时外部依赖:
esbuild src/preload.cjs --bundle --platform=node --format=cjs --external:electron --outfile=dist/preload.cjs
不需要采集的页面不要加载 Guance Preload,也不要调用 attachWindow()。对于多窗口应用,每个窗口都要在加载页面前独立登记;Adapter 会在窗口销毁时自动移除登记,返回的移除函数也可用于提前停止采集。
若所有窗口均可信,可在 bootstrap() 中设置 autoAttach: true,自动登记已有和新建窗口;默认值为 false。自动登记不能替代 Preload 安装。
初始化 Renderer¶
每个需要监控的 Renderer 都要初始化 Browser SDK。Bridge 模式不需要 applicationId;datakitOrigin 仅用于通过 Browser SDK 的初始化校验,数据不会上传到该地址。
import { datafluxRum } from "@cloudcare/browser-rum";
import { datafluxLogs } from "@cloudcare/browser-logs";
datafluxLogs.init({
datakitOrigin: "http://127.0.0.1",
forwardErrorsToLogs: true,
forwardConsoleLogs: ["error", "warn"],
});
datafluxRum.init({
datakitOrigin: "http://127.0.0.1",
});
const capabilities = JSON.parse(
window.FTWebViewJavascriptBridge.getCapabilities(),
);
if (capabilities.includes("records")) {
datafluxRum.startSessionReplayRecording();
}
Browser SDK 检测到 FTWebViewJavascriptBridge 后会切换到 Bridge 传输,不启动 Browser HTTP Batch。日志采样建议统一由 Native loggingSampleRate 控制,避免再设置较低的 Browser sessionSampleRate 造成双重采样。
Session Replay 是实验性且默认关闭的能力
仅当 Native SDK 和 Bridge 配置均启用 Replay 时,getCapabilities() 才返回 records。Renderer 必须根据该能力决定是否开始录制,不能单独强制启用。混合模式还需要让 Native Replay 配置、Bridge Server 配置和录制生命周期保持一致。
打包资源¶
全量模式应在应用签名前调用公开的打包辅助函数,把完整运行时复制到 ASAR 之外:
const { stageWindowsRuntime } = require(
"@cloudcare/electron-native-adapter/packaging/windows",
);
stageWindowsRuntime({
resourcesDirectory: "release/MyApp-win32-x64/resources",
arch: "x64",
});
辅助函数默认定位 npm 包内已安装的运行时,复制到 resources/native;目标目录必须为空。打包后的 managed 模式会自动定位该目录,无需设置 native.directory。Native EXE、DLL 和 manifest 等资源应完整保留,不能放入 app.asar。
跨架构打包时,先安装目标运行时,再显式传入目标 arch。Windows 支持 x64、x86 / ia32、arm64。CLI 安装的运行时须通过辅助函数的 nativeDirectory 指定。
手动使用 vcpkg 工具目录时,也可继续通过 electron-builder 的 extraResources 复制,并使用前述 sdkDirectory 指定资源位置:
{
"build": {
"extraResources": [
{
"from": "vcpkg_installed/x64-windows/tools/guance-windows-native",
"to": "guance-windows-native"
}
]
}
}
全量模式必须交付同一 SDK 版本的 guance_windows_electron_bridge.exe 和相邻的 guance_windows_native.dll,同时由应用打包工具携带 @cloudcare/electron-native-adapter。混合模式不需要复制 vcpkg 工具目录;Native DLL 仍由 C++ 宿主原有的部署流程交付,JavaScript Adapter 仍由 npm 依赖提供。不要依赖当前工作目录或开发机绝对路径定位资源。
自定义与离线运行时安装¶
若 npm 安装时使用了 --ignore-scripts,或需要其他目标架构,可在应用根目录运行:
Windows 目标为 win32-x64、win32-x86、win32-arm64;macOS 为 darwin-universal。<sdk-tag> 使用 Native SDK Release 的完整标签,保留 vcpkg_、nuget_ 或 v 等已有前缀;标签下必须存在对应运行时资产。
离线安装需要 SDK .tar.gz 和相邻的 .tar.gz.sha256 校验文件:
npx guance-electron-native --sdk-version <sdk-tag> --target <target> --runtime-archive C:/sdk/runtime.tar.gz
CLI 将运行时安装到应用根目录下。开发时把输出目录传给 native.directory,打包时传给 stageWindowsRuntime() 的 nativeDirectory;打包后移除开发目录配置,使用自动定位的 resources/native。
npm postinstall 可使用以下环境变量(PowerShell 使用 $env:变量名 = "值" 设置):
| 环境变量 | 用途 |
|---|---|
GUANCE_NATIVE_RUNTIME_ARCHIVE |
使用本地 SDK 压缩包及相邻校验文件,替代下载 |
GUANCE_NATIVE_RUNTIME_TARGET |
指定目标平台和架构 |
GUANCE_NATIVE_SDK_VERSION |
覆盖包中固定的 Native SDK 标签 |
GUANCE_NATIVE_RUNTIME_ASSET_NAME |
覆盖下载资产文件名 |
GUANCE_NATIVE_RUNTIME_DOWNLOAD_BASE_URL |
使用 HTTPS 镜像,目录结构为 /<sdk-tag>/<filename> |
GUANCE_NATIVE_SKIP_DOWNLOAD |
设为 1 跳过运行时安装,适用于 external 模式 |
压缩包必须与指定 SDK 版本和架构匹配。仅提供离线 Native Runtime 不代表 npm 完全离线;还需要提前准备 npm 包及其依赖缓存。私有源码 checkout 会跳过自动下载,本地 file: 依赖联调时需自行准备运行时。
集成边界¶
- Main Process 只使用
@cloudcare/electron-native-adapter导出的公开接口,不自行注册 SDK 内部 IPC Channel; - 不要将应用 ID、Client Token、DataKit/Dataway 地址、原生 Session 或完整 Native 配置暴露给 Renderer;
- Main Process 只登记可信的
webContents。远程页面还需要限制导航、弹窗、权限和允许域名; - 全量模式通过
native.settings配置 Native Trace,混合模式由宿主配置。Adapter 不向 Renderer 注入 Trace 配置,也不因此自动为页面请求添加 Trace Header; - Renderer JavaScript Error 和 Long Task 由 Browser RUM 采集;
unresponsive、render-process-gone和 Main Process Crash 不由 Bridge 自动上报,如有需要应单独接入 ElectroncrashReporter或其他 Crashpad 服务。
验证集成¶
- 在 Renderer DevTools Network 中确认没有 RUM 或 Log 直传请求;
- 触发 View、Action、Resource、Error、Long Task 和一条 Browser Log,在控制台确认数据;
- 确认数据使用 Native 配置中的应用 ID、Session ID 和
sdk_name=df_windows_rum_sdk; - 确认 Browser Log 的
warn状态在 Native Log 中显示为warning,且自定义属性被保留; - Replay 关闭时,确认
getCapabilities()不包含records;开启时,确认录制数据正常上报; - 混合模式关闭 Electron 页面后,确认 C++ SDK 仍在运行;全量模式退出应用后,确认 Bridge EXE 正常关闭。
可参考 Windows SDK 仓库中的 Electron Native Adapter Consumer Acceptance 和 Electron Sample 完成验收。本地联调可以使用 npm file: 依赖;正式应用使用发布包,并通过应用的 lockfile 管理实际安装版本。