跳转至

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:

npm install @cloudcare/electron-native-adapter @cloudcare/browser-rum @cloudcare/browser-logs

不采集 Browser Log 时,可以不安装 @cloudcare/browser-logs

Browser Logs 的 Bridge 接入要求 3.3.6 或更高版本。

已验证的 Electron 基线为 22.3.2743.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:

{
  "dependencies": [
    {
      "name": "guance-windows-native",
      "default-features": false
    }
  ]
}

vcpkg.json 所在目录执行:

vcpkg install --triplet x64-windows

集成时只使用以下公开入口:

  • @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 替换为 datawayUrlclientTokenapplicationIdserviceenvironmentversion 必填,并且必须提供 DataKit 或 DataWay 地址。

Native RUM、Log、Replay 和 Trace 的采样率取值均为 01,默认均为 1loggingEnabledreplayEnabledtraceEnableddebug 默认关闭;示例显式开启了日志。replayPrivacy 支持 allowmask-user-inputmask,默认 mask

其他可选配置:

位置 参数 说明
native.settings traceEnabledtraceSampleRate 配置 Native Trace 开关与采样率
native.settings traceType 默认 w3c_traceparent
native.settings traceAllowedUrls Native Trace URL 规则字符串
native.settings httpTimeoutMs 上传超时,默认 10000 毫秒,范围 1..300000
native(managed) readyTimeoutMsstopTimeoutMs 启动握手与退出等待时间,默认 100003000 毫秒
native(managed) onNativeOutput 接收 (stream, text),用于诊断 Bridge 标准输出和错误输出
native(external) timeoutMsretryDelayMs 连接超时与重试间隔,默认 10000100 毫秒
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,提供 capabilitiesattachWindow()detachWindow()updateWindow()transportState 和幂等的 stop()transportState 用于检查可写状态、背压和传输失败。startFullMode()connectMixedMode() 仅作为早期版本兼容入口保留,新接入统一使用 bootstrap()

Adapter 默认启用 enableAppLaunch,会结合 Electron 应用生命周期、可信窗口首帧和 Browser View 上下文自动生成 launch_coldlaunch_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 模式不需要 applicationIddatakitOrigin 仅用于通过 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 支持 x64x86 / ia32arm64。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,或需要其他目标架构,可在应用根目录运行:

npx guance-electron-native --sdk-version <sdk-tag> --target <target>

Windows 目标为 win32-x64win32-x86win32-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 采集;unresponsiverender-process-gone 和 Main Process Crash 不由 Bridge 自动上报,如有需要应单独接入 Electron crashReporter 或其他 Crashpad 服务。

验证集成

  1. 在 Renderer DevTools Network 中确认没有 RUM 或 Log 直传请求;
  2. 触发 View、Action、Resource、Error、Long Task 和一条 Browser Log,在控制台确认数据;
  3. 确认数据使用 Native 配置中的应用 ID、Session ID 和 sdk_name=df_windows_rum_sdk
  4. 确认 Browser Log 的 warn 状态在 Native Log 中显示为 warning,且自定义属性被保留;
  5. Replay 关闭时,确认 getCapabilities() 不包含 records;开启时,确认录制数据正常上报;
  6. 混合模式关闭 Electron 页面后,确认 C++ SDK 仍在运行;全量模式退出应用后,确认 Bridge EXE 正常关闭。

可参考 Windows SDK 仓库中的 Electron Native Adapter Consumer AcceptanceElectron Sample 完成验收。本地联调可以使用 npm file: 依赖;正式应用使用发布包,并通过应用的 lockfile 管理实际安装版本。

文档评价

文档内容是否对您有帮助?