Electron 모니터링¶
Windows SDK는 Native Bridge를 통해 Electron에 연동됩니다. Renderer의 Browser RUM과 Browser Logs가 페이지 데이터를 수집하고, Electron Main Process가 데이터를 Windows Native Core에 전달합니다. Native Core가 애플리케이션 ID, 세션, 샘플링, 전역 컨텍스트, 영속 큐 및 업로드를 통합 관리합니다.
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 이상이 필요합니다. 대상 OS와 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: truenodeIntegration: falsesandbox: 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 주소, 네이티브 세션 또는 전체 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로 실제 설치 버전을 관리합니다.