跳转至

Electron 监测

Windows SDK 通过 Native Bridge 接入 Electron:Renderer 中的 Browser RUM 和 Browser Logs 负责采集页面数据,Electron Main Process 将数据交给 Windows Native Core,由 Native Core 统一管理应用 ID、Session、采样、全局上下文、持久化队列和上传。

根据 Native SDK 的初始化所有者选择一种模式:

模式 适用场景 vcpkg Feature SDK 所有者
混合模式 C++ 桌面应用中嵌入 Electron 页面 electron-adapter C++ 宿主
全量模式 应用本身是 Electron electron-bridge guance_windows_electron_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

安装依赖

在需要采集的 Renderer 项目中安装 Browser SDK:

npm install @cloudcare/browser-rum @cloudcare/browser-logs@^3.3.6

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

按照快速开始配置 GuanceCloud vcpkg 注册表。当前 Electron Adapter 仅支持动态 x64-windows

全量模式使用 electron-bridge

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

混合模式使用 electron-adapter

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

vcpkg.json 所在目录执行:

vcpkg install --triplet x64-windows

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

  • electron/main/index.cjs:Main Process 的全量模式和混合模式入口;
  • electron/preload/standalone.cjs:应用没有现有 Preload 时直接使用;
  • electron/preload/install.cjs:应用已有 Preload 时,由 bundler 合并到业务 Preload。

不要复制、修改或直接引用 electron/internal/ 下的文件。

开发运行时从项目的 vcpkg_installed 目录加载 Adapter,打包后从 process.resourcesPath 加载:

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",
    );

const mainAdapterPath = path.join(
  sdkDirectory,
  "electron",
  "main",
  "index.cjs",
);

开发目录的相对层级应按应用结构调整,不要依赖当前工作目录或写死开发机绝对路径。

初始化 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 { ipcMain } = require("electron");
const { connectMixedMode } = require(mainAdapterPath);

const rumBridge = await connectMixedMode({
  ipcMain,
  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:

const { app, ipcMain } = require("electron");
const { startFullMode } = require(mainAdapterPath);

const rumBridge = await startFullMode({
  ipcMain,
  nativeDirectory: sdkDirectory,
  enableAppLaunch: true,
  nativeSettings: {
    applicationId: "<rum-application-id>",
    datakitUrl: "http://127.0.0.1:9529",
    service: "electron-desktop-client",
    environment: "prod",
    version: app.getVersion(),
    cachePath: path.join(app.getPath("userData"), "native-rum-cache"),
    sampleRate: 1,
    loggingEnabled: true,
    loggingSampleRate: 1,
    replayEnabled: false,
    replaySampleRate: 1,
    replayPrivacy: "mask",
    debug: false,
  },
});

Native RUM、Log 和 Replay 的采样率取值均为 01。应用退出前需要等待 rumBridge.stop() 完成。

connectMixedMode()startFullMode() 默认启用 enableAppLaunch。Adapter 会结合 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 = path.join(
  sdkDirectory,
  "electron",
  "preload",
  "standalone.cjs",
);

const window = new BrowserWindow({
  webPreferences: {
    preload: standalonePreloadPath,
    contextIsolation: true,
    nodeIntegration: false,
    sandbox: true,
  },
});

const detachWindow = rumBridge.attachWindow(window);
window.webContents.once("destroyed", detachWindow);

应用已有 Preload 时,将 electron/preload/install.cjs 配置为 webpack、esbuild 等 bundler 的构建依赖,并在业务 Preload 中调用一次:

const { installElectronRumPreload } = require("guance-electron-preload");

installElectronRumPreload();

这里的 guance-electron-preload 是指向 install.cjs 的构建别名,不是 npm 包。启用 sandbox: true 时,最终 Preload 产物必须是一个可由 webPreferences.preload 直接加载的 bundle。

不需要采集的页面不要加载 Guance Preload,也不要调用 attachWindow()。对于多窗口应用,每个窗口都要独立登记,并在销毁时调用 attachWindow() 返回的移除函数。

初始化 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 配置和录制生命周期保持一致。

打包资源

使用 electron-builder 时,全量模式需要把整个 SDK 工具目录加入应用资源:

{
  "build": {
    "extraResources": [
      {
        "from": "vcpkg_installed/x64-windows/tools/guance-windows-native",
        "to": "guance-windows-native"
      }
    ]
  }
}

全量模式必须交付同一 SDK 版本的 Bridge EXE、Native DLL 和 electron/ 目录。混合模式只需复制 tools/guance-windows-native/electron/;Native DLL 仍由 C++ 宿主原有的部署流程交付。不要依赖当前工作目录或开发机绝对路径定位资源。

集成边界

  • Main Process 只使用 electron/main/index.cjs 的公开接口,不自行注册 SDK 内部 IPC Channel;
  • 不要将应用 ID、Client Token、DataKit/Dataway 地址、原生 Session 或完整 Native 配置暴露给 Renderer;
  • Main Process 只登记可信的 webContents。远程页面还需要限制导航、弹窗、权限和允许域名;
  • Trace 仍通过 Windows SDK Trace API 独立配置,Electron Adapter 不向 Renderer 注入 Trace 配置;
  • 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 vcpkg Consumer AcceptanceElectron Sample 完成验收。

文档评价

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