From 810817575d8519b63a78af46b4ddd1a968d3330f Mon Sep 17 00:00:00 2001 From: ShiKhu Date: Fri, 27 Aug 2021 09:52:41 +0300 Subject: [PATCH] feat (tracker): 3.2.4 - performance,selector options + beaconSizeLimit + debug_report_edp --- tracker/tracker/package.json | 2 +- tracker/tracker/src/main/app/index.ts | 38 +++++++++++++++---- tracker/tracker/src/main/index.ts | 10 +++-- tracker/tracker/src/main/modules/mouse.ts | 26 ++++++++++--- .../tracker/src/main/modules/performance.ts | 16 +++++++- tracker/tracker/src/messages/webworker.ts | 1 + tracker/tracker/src/webworker/index.ts | 3 +- 7 files changed, 74 insertions(+), 22 deletions(-) diff --git a/tracker/tracker/package.json b/tracker/tracker/package.json index eb760e700..8c6f6c172 100644 --- a/tracker/tracker/package.json +++ b/tracker/tracker/package.json @@ -1,7 +1,7 @@ { "name": "@openreplay/tracker", "description": "The OpenReplay tracker main package", - "version": "3.2.1", + "version": "3.2.4", "keywords": [ "logging", "replay" diff --git a/tracker/tracker/src/main/app/index.ts b/tracker/tracker/src/main/app/index.ts index f7aef2fce..dfe8ba4f3 100644 --- a/tracker/tracker/src/main/app/index.ts +++ b/tracker/tracker/src/main/app/index.ts @@ -19,13 +19,16 @@ export type Options = { local_uuid_key: string; ingestPoint: string; __is_snippet: boolean; + __debug_report_edp: string | null; onStart?: (info: { sessionID: string, sessionToken: string, userUUID: string }) => void; } & ObserverOptions & WebworkerOptions; type Callback = () => void; type CommitCallback = (messages: Array) => void; -export const DEFAULT_INGEST_POINT = 'https://ingest.openreplay.com'; + +// TODO: use backendHost only +export const DEFAULT_INGEST_POINT = 'https://api.openreplay.com/ingest'; export default class App { readonly nodes: Nodes; @@ -57,6 +60,7 @@ export default class App { local_uuid_key: '__openreplay_uuid', ingestPoint: DEFAULT_INGEST_POINT, __is_snippet: false, + __debug_report_edp: null, obscureTextEmails: true, obscureTextNumbers: false, }, @@ -99,8 +103,23 @@ export default class App { this.attachEventListener(window, 'beforeunload', alertWorker, false); this.attachEventListener(document, 'mouseleave', alertWorker, false, false); this.attachEventListener(document, 'visibilitychange', alertWorker, false); - } catch (e) { /* TODO: send report */} + } catch (e) { + this.sendDebugReport("worker_start", e); + } } + + private sendDebugReport(context: string, e: any) { + if(this.options.__debug_report_edp !== null) { + fetch(this.options.__debug_report_edp, { + method: 'POST', + body: JSON.stringify({ + context, + error: `${e}` + }) + }); + } + } + send(message: Message, urgent = false): void { if (!this.isActive) { return; @@ -230,14 +249,17 @@ export default class App { if (r.status === 200) { return r.json() } else { // TODO: handle canceling && 403 - throw new Error("Server error"); + return r.text().then(text => { + throw new Error(`Server error: ${r.status}. ${text}`); + }); } }) .then(r => { - const { token, userUUID, sessionID } = r; + const { token, userUUID, sessionID, beaconSizeLimit } = r; if (typeof token !== 'string' || - typeof userUUID !== 'string') { - throw new Error("Incorrect server response"); + typeof userUUID !== 'string' || + (typeof beaconSizeLimit !== 'number' && typeof beaconSizeLimit !== 'undefined')) { + throw new Error(`Incorrect server response: ${ JSON.stringify(r) }`); } sessionStorage.setItem(this.options.session_token_key, token); localStorage.setItem(this.options.local_uuid_key, userUUID); @@ -247,7 +269,7 @@ export default class App { if (!this.worker) { throw new Error("Stranger things: no worker found after start request"); } - this.worker.postMessage({ token }); + this.worker.postMessage({ token, beaconSizeLimit }); this.startCallbacks.forEach((cb) => cb()); this.observer.observe(); this.ticker.start(); @@ -259,7 +281,7 @@ export default class App { }) .catch(e => { this.stop(); - /* TODO: send report */ + this.sendDebugReport("session_start", e); }) } } diff --git a/tracker/tracker/src/main/index.ts b/tracker/tracker/src/main/index.ts index 0829651cc..e56eab6ec 100644 --- a/tracker/tracker/src/main/index.ts +++ b/tracker/tracker/src/main/index.ts @@ -20,12 +20,14 @@ import CSSRules from './modules/cssrules'; import { IN_BROWSER, deprecationWarn } from './utils'; import { Options as AppOptions } from './app'; -import { Options as ExceptionOptions } from './modules/exception'; import { Options as ConsoleOptions } from './modules/console'; +import { Options as ExceptionOptions } from './modules/exception'; import { Options as InputOptions } from './modules/input'; +import { Options as MouseOptions } from './modules/mouse'; +import { Options as PerformanceOptions } from './modules/performance'; import { Options as TimingOptions } from './modules/timing'; export type Options = Partial< - AppOptions & ConsoleOptions & ExceptionOptions & InputOptions & TimingOptions + AppOptions & ConsoleOptions & ExceptionOptions & InputOptions & MouseOptions & PerformanceOptions & TimingOptions > & { projectID?: number; // For the back compatibility only (deprecated) projectKey: string; @@ -92,9 +94,9 @@ export default class API { Exception(this.app, options); Img(this.app); Input(this.app, options); - Mouse(this.app); + Mouse(this.app, options); Timing(this.app, options); - Performance(this.app); + Performance(this.app, options); Scroll(this.app); Longtasks(this.app); (window as any).__OPENREPLAY__ = (window as any).__OPENREPLAY__ || this; diff --git a/tracker/tracker/src/main/modules/mouse.ts b/tracker/tracker/src/main/modules/mouse.ts index cae32142f..96b973e14 100644 --- a/tracker/tracker/src/main/modules/mouse.ts +++ b/tracker/tracker/src/main/modules/mouse.ts @@ -1,14 +1,10 @@ +import type { Options as FinderOptions } from '../vendors/finder/finder'; import { finder } from '../vendors/finder/finder'; import { normSpaces, hasOpenreplayAttribute, getLabelAttribute } from '../utils'; import App from '../app'; import { MouseMove, MouseClick } from '../../messages'; import { getInputLabel } from './input'; -const selectorMap: {[id:number]: string} = {}; -function getSelector(id: number, target: Element): string { - return selectorMap[id] = selectorMap[id] || finder(target); -} - function getTarget(target: EventTarget | null): Element | null { if (target instanceof Element) { return _getTarget(target); @@ -76,7 +72,18 @@ function getTargetLabel(target: Element): string { return ''; } -export default function (app: App): void { +export interface Options { + selectorFinder: boolean | FinderOptions; +} + +export default function (app: App, opts: Partial): void { + const options: Options = Object.assign( + { + selectorFinder: true, + }, + opts, + ); + let mousePositionX = -1; let mousePositionY = -1; let mousePositionChanged = false; @@ -97,6 +104,13 @@ export default function (app: App): void { } }; + const selectorMap: {[id:number]: string} = {}; + function getSelector(id: number, target: Element): string { + if (options.selectorFinder === false) { return '' } + return selectorMap[id] = selectorMap[id] || + finder(target, options.selectorFinder === true ? undefined : options.selectorFinder); + } + app.attachEventListener( document.documentElement, 'mouseover', diff --git a/tracker/tracker/src/main/modules/performance.ts b/tracker/tracker/src/main/modules/performance.ts index 2a4edd149..7deac3ef5 100644 --- a/tracker/tracker/src/main/modules/performance.ts +++ b/tracker/tracker/src/main/modules/performance.ts @@ -11,7 +11,7 @@ type Perf = { } } -const perf: Perf = IN_BROWSER && 'memory' in performance // works in Chrome only +const perf: Perf = IN_BROWSER && 'performance' in window && 'memory' in performance // works in Chrome only ? performance as any : { memory: {} } @@ -19,7 +19,19 @@ const perf: Perf = IN_BROWSER && 'memory' in performance // works in Chrome only export const deviceMemory = IN_BROWSER ? ((navigator as any).deviceMemory || 0) * 1024 : 0; export const jsHeapSizeLimit = perf.memory.jsHeapSizeLimit || 0; -export default function (app: App): void { +export interface Options { + capturePerformance: boolean; +} + +export default function (app: App, opts: Partial): void { + const options: Options = Object.assign( + { + capturePerformance: true, + }, + opts, + ); + if (!options.capturePerformance) { return; } + let frames: number | undefined; let ticks: number | undefined; diff --git a/tracker/tracker/src/messages/webworker.ts b/tracker/tracker/src/messages/webworker.ts index e5eb8eef7..e4bc97818 100644 --- a/tracker/tracker/src/messages/webworker.ts +++ b/tracker/tracker/src/messages/webworker.ts @@ -11,6 +11,7 @@ type Settings = { pageNo?: number; startTimestamp?: number; timeAdjustment?: number; + beaconSizeLimit?: number; } & Partial; export type WorkerMessageData = null | "stop" | Settings | Array<{ _id: number }>; \ No newline at end of file diff --git a/tracker/tracker/src/webworker/index.ts b/tracker/tracker/src/webworker/index.ts index 5553610ca..1c6cde40f 100644 --- a/tracker/tracker/src/webworker/index.ts +++ b/tracker/tracker/src/webworker/index.ts @@ -6,7 +6,7 @@ import type { WorkerMessageData } from '../messages/webworker'; const SEND_INTERVAL = 20 * 1000; -const BEACON_SIZE_LIMIT = 1e6 // Limit is set in the backend/services/http +let BEACON_SIZE_LIMIT = 1e6 // Limit is set in the backend/services/http let beaconSize = 4 * 1e5; // Default 400kB @@ -123,6 +123,7 @@ self.onmessage = ({ data }: MessageEvent) => { timeAdjustment = data.timeAdjustment || timeAdjustment; MAX_ATTEMPTS_COUNT = data.connAttemptCount || MAX_ATTEMPTS_COUNT; ATTEMPT_TIMEOUT = data.connAttemptGap || ATTEMPT_TIMEOUT; + BEACON_SIZE_LIMIT = data.beaconSizeLimit || BEACON_SIZE_LIMIT; beaconSize = Math.min(BEACON_SIZE_LIMIT, data.beaconSize || beaconSize); if (writer.isEmpty()) { writeBatchMeta();