sobey-monitor-sdk 1.1.3 → 1.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +134 -93
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +134 -93
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +134 -93
- package/dist/index.umd.js.map +1 -1
- package/dist/reporter/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.umd.js
CHANGED
|
@@ -280,13 +280,22 @@
|
|
|
280
280
|
* 策略:优先使用 sendBeacon(更可靠),不支持或失败时降级为 fetch
|
|
281
281
|
*/
|
|
282
282
|
doSend(data) {
|
|
283
|
+
// 检查配置是否已初始化
|
|
284
|
+
if (!config.isInitialized()) {
|
|
285
|
+
// 配置未初始化,数据放回缓冲区等待下次发送
|
|
286
|
+
this.buffer.unshift(...data);
|
|
287
|
+
this.scheduleFlush();
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
283
290
|
const cfg = config.get();
|
|
284
291
|
const dsn = cfg.dsn;
|
|
285
|
-
// dsn
|
|
292
|
+
// dsn 未配置,将数据放回缓冲区等待下次发送
|
|
286
293
|
if (!dsn) {
|
|
287
294
|
if (cfg.debug) {
|
|
288
|
-
console.warn('[Monitor] dsn not configured,
|
|
295
|
+
console.warn('[Monitor] dsn not configured, buffering data for later');
|
|
289
296
|
}
|
|
297
|
+
this.buffer.unshift(...data);
|
|
298
|
+
this.scheduleFlush();
|
|
290
299
|
return;
|
|
291
300
|
}
|
|
292
301
|
const payload = JSON.stringify(data);
|
|
@@ -407,25 +416,83 @@
|
|
|
407
416
|
}
|
|
408
417
|
}
|
|
409
418
|
/**
|
|
410
|
-
*
|
|
419
|
+
* 发送早期缓存的数据(根据最新配置过滤)
|
|
411
420
|
*/
|
|
412
421
|
flushEarlyBuffer() {
|
|
422
|
+
const cfg = config.get();
|
|
423
|
+
let skippedCount = 0;
|
|
424
|
+
// 全局开关检查:如果 enabled 为 false,清空缓存不上报
|
|
425
|
+
if (cfg.enabled === false) {
|
|
426
|
+
const totalCount = this.earlyBuffer.length;
|
|
427
|
+
this.earlyBuffer = [];
|
|
428
|
+
if (cfg.debug) {
|
|
429
|
+
console.log(`[Monitor] SDK disabled, discarded ${totalCount} early buffered items`);
|
|
430
|
+
}
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
413
433
|
while (this.earlyBuffer.length > 0) {
|
|
414
434
|
const item = this.earlyBuffer.shift();
|
|
415
435
|
if (!item)
|
|
416
436
|
continue;
|
|
437
|
+
// 根据最新配置过滤数据
|
|
417
438
|
switch (item.type) {
|
|
418
439
|
case 'error':
|
|
440
|
+
// 检查错误监控是否启用
|
|
441
|
+
if (cfg.error?.enabled === false) {
|
|
442
|
+
skippedCount++;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
// 根据错误类型检查具体开关
|
|
446
|
+
const errorType = item.data?.type;
|
|
447
|
+
if (errorType === 'js_error' && cfg.error?.jsError === false) {
|
|
448
|
+
skippedCount++;
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
if (errorType === 'promise_error' && cfg.error?.promiseError === false) {
|
|
452
|
+
skippedCount++;
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (errorType === 'resource_error' && cfg.error?.resourceError === false) {
|
|
456
|
+
skippedCount++;
|
|
457
|
+
continue;
|
|
458
|
+
}
|
|
459
|
+
if (errorType === 'http_error' && cfg.error?.httpError === false) {
|
|
460
|
+
skippedCount++;
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
419
463
|
this.reportError(item.data);
|
|
420
464
|
break;
|
|
421
465
|
case 'performance':
|
|
466
|
+
// 检查性能监控是否启用
|
|
467
|
+
if (cfg.performance?.enabled === false) {
|
|
468
|
+
skippedCount++;
|
|
469
|
+
continue;
|
|
470
|
+
}
|
|
422
471
|
this.reportPerformance(item.data);
|
|
423
472
|
break;
|
|
424
473
|
case 'behavior':
|
|
474
|
+
// 检查行为监控是否启用
|
|
475
|
+
if (cfg.behavior?.enabled === false) {
|
|
476
|
+
skippedCount++;
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
// 根据行为类型检查具体开关
|
|
480
|
+
const action = item.data?.action;
|
|
481
|
+
if (action === 'pv' && cfg.behavior?.pv === false) {
|
|
482
|
+
skippedCount++;
|
|
483
|
+
continue;
|
|
484
|
+
}
|
|
485
|
+
if (action === 'route' && cfg.behavior?.route === false) {
|
|
486
|
+
skippedCount++;
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
425
489
|
this.reportBehavior(item.data);
|
|
426
490
|
break;
|
|
427
491
|
}
|
|
428
492
|
}
|
|
493
|
+
if (skippedCount > 0 && cfg.debug) {
|
|
494
|
+
console.log(`[Monitor] Filtered out ${skippedCount} early buffered items based on config`);
|
|
495
|
+
}
|
|
429
496
|
}
|
|
430
497
|
/**
|
|
431
498
|
* 缓存早期数据
|
|
@@ -553,15 +620,16 @@
|
|
|
553
620
|
* 安装 JS 错误监听
|
|
554
621
|
*/
|
|
555
622
|
function installJsErrorHandler() {
|
|
556
|
-
const cfg = config.get();
|
|
557
|
-
if (!cfg.error?.enabled || !cfg.error?.jsError) {
|
|
558
|
-
return;
|
|
559
|
-
}
|
|
560
623
|
window.addEventListener('error', (event) => {
|
|
561
624
|
// 过滤资源加载错误(由 resourceError 处理)
|
|
562
625
|
if (event.target !== window) {
|
|
563
626
|
return;
|
|
564
627
|
}
|
|
628
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
629
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
630
|
+
if (cfg?.error?.enabled === false || cfg?.error?.jsError === false) {
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
565
633
|
const errorData = {
|
|
566
634
|
type: 'js_error',
|
|
567
635
|
message: event.message || 'Unknown error',
|
|
@@ -582,9 +650,7 @@
|
|
|
582
650
|
});
|
|
583
651
|
reporter.reportError(errorData);
|
|
584
652
|
}, true);
|
|
585
|
-
|
|
586
|
-
console.log('[Monitor] JS error handler installed');
|
|
587
|
-
}
|
|
653
|
+
console.log('[Monitor] JS error handler installed');
|
|
588
654
|
}
|
|
589
655
|
|
|
590
656
|
/**
|
|
@@ -594,11 +660,12 @@
|
|
|
594
660
|
* 安装 Promise 错误监听
|
|
595
661
|
*/
|
|
596
662
|
function installPromiseErrorHandler() {
|
|
597
|
-
const cfg = config.get();
|
|
598
|
-
if (!cfg.error?.enabled || !cfg.error?.promiseError) {
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
663
|
window.addEventListener('unhandledrejection', (event) => {
|
|
664
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
665
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
666
|
+
if (cfg?.error?.enabled === false || cfg?.error?.promiseError === false) {
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
602
669
|
let message = 'Unhandled Promise rejection';
|
|
603
670
|
let stack;
|
|
604
671
|
const reason = event.reason;
|
|
@@ -627,9 +694,7 @@
|
|
|
627
694
|
});
|
|
628
695
|
reporter.reportError(errorData);
|
|
629
696
|
});
|
|
630
|
-
|
|
631
|
-
console.log('[Monitor] Promise error handler installed');
|
|
632
|
-
}
|
|
697
|
+
console.log('[Monitor] Promise error handler installed');
|
|
633
698
|
}
|
|
634
699
|
|
|
635
700
|
/**
|
|
@@ -639,16 +704,17 @@
|
|
|
639
704
|
* 安装资源错误监听
|
|
640
705
|
*/
|
|
641
706
|
function installResourceErrorHandler() {
|
|
642
|
-
const cfg = config.get();
|
|
643
|
-
if (!cfg.error?.enabled || !cfg.error?.resourceError) {
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
707
|
window.addEventListener('error', (event) => {
|
|
647
708
|
const target = event.target;
|
|
648
709
|
// 只处理资源加载错误(target 不是 window)
|
|
649
710
|
if (!target || target === window || !(target instanceof HTMLElement)) {
|
|
650
711
|
return;
|
|
651
712
|
}
|
|
713
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
714
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
715
|
+
if (cfg?.error?.enabled === false || cfg?.error?.resourceError === false) {
|
|
716
|
+
return;
|
|
717
|
+
}
|
|
652
718
|
const tagName = target.tagName.toLowerCase();
|
|
653
719
|
// 只监控特定标签的资源
|
|
654
720
|
if (!['img', 'script', 'link', 'video', 'audio', 'source'].includes(tagName)) {
|
|
@@ -677,9 +743,7 @@
|
|
|
677
743
|
});
|
|
678
744
|
reporter.reportError(errorData);
|
|
679
745
|
}, true); // 使用捕获阶段
|
|
680
|
-
|
|
681
|
-
console.log('[Monitor] Resource error handler installed');
|
|
682
|
-
}
|
|
746
|
+
console.log('[Monitor] Resource error handler installed');
|
|
683
747
|
}
|
|
684
748
|
|
|
685
749
|
/**
|
|
@@ -694,23 +758,16 @@
|
|
|
694
758
|
* 安装 HTTP 错误拦截
|
|
695
759
|
*/
|
|
696
760
|
function installHttpErrorHandler() {
|
|
697
|
-
const cfg = config.get();
|
|
698
|
-
if (!cfg.error?.enabled || !cfg.error?.httpError) {
|
|
699
|
-
return;
|
|
700
|
-
}
|
|
701
761
|
interceptXHR();
|
|
702
762
|
interceptFetch();
|
|
703
|
-
|
|
704
|
-
console.log('[Monitor] HTTP error handler installed');
|
|
705
|
-
}
|
|
763
|
+
console.log('[Monitor] HTTP error handler installed');
|
|
706
764
|
}
|
|
707
|
-
/**
|
|
708
|
-
* 拦截 XMLHttpRequest
|
|
709
|
-
*/
|
|
710
765
|
/**
|
|
711
766
|
* 检查是否是 SDK 自身的请求
|
|
712
767
|
*/
|
|
713
768
|
function isSdkRequest(url) {
|
|
769
|
+
if (!config.isInitialized())
|
|
770
|
+
return false;
|
|
714
771
|
const cfg = config.get();
|
|
715
772
|
if (!cfg.dsn)
|
|
716
773
|
return false;
|
|
@@ -880,10 +937,6 @@
|
|
|
880
937
|
reporter.reportError(errorData);
|
|
881
938
|
}
|
|
882
939
|
|
|
883
|
-
/**
|
|
884
|
-
* 白屏检测插件
|
|
885
|
-
* 使用 DOM 采样检测页面是否白屏
|
|
886
|
-
*/
|
|
887
940
|
// 采样点 - 页面关键区域
|
|
888
941
|
const SAMPLE_POINTS = [
|
|
889
942
|
{ x: 0.5, y: 0.1 }, // 顶部中间
|
|
@@ -898,10 +951,6 @@
|
|
|
898
951
|
* 安装白屏检测
|
|
899
952
|
*/
|
|
900
953
|
function installWhiteScreenDetector() {
|
|
901
|
-
const cfg = config.get();
|
|
902
|
-
if (!cfg.error?.enabled) {
|
|
903
|
-
return;
|
|
904
|
-
}
|
|
905
954
|
// 在页面加载完成后检测
|
|
906
955
|
if (document.readyState === 'complete') {
|
|
907
956
|
scheduleDetection();
|
|
@@ -911,9 +960,7 @@
|
|
|
911
960
|
scheduleDetection();
|
|
912
961
|
});
|
|
913
962
|
}
|
|
914
|
-
|
|
915
|
-
console.log('[Monitor] White screen detector installed');
|
|
916
|
-
}
|
|
963
|
+
console.log('[Monitor] White screen detector installed');
|
|
917
964
|
}
|
|
918
965
|
/**
|
|
919
966
|
* 调度检测(延迟执行,给页面渲染时间)
|
|
@@ -985,10 +1032,6 @@
|
|
|
985
1032
|
* 安装 Web Vitals 采集
|
|
986
1033
|
*/
|
|
987
1034
|
function installWebVitals() {
|
|
988
|
-
const cfg = config.get();
|
|
989
|
-
if (!cfg.performance?.enabled || !cfg.performance?.webVitals) {
|
|
990
|
-
return;
|
|
991
|
-
}
|
|
992
1035
|
// 页面加载完成后采集
|
|
993
1036
|
if (document.readyState === 'complete') {
|
|
994
1037
|
collectMetrics();
|
|
@@ -999,14 +1042,17 @@
|
|
|
999
1042
|
setTimeout(collectMetrics, 3000);
|
|
1000
1043
|
});
|
|
1001
1044
|
}
|
|
1002
|
-
|
|
1003
|
-
console.log('[Monitor] Web Vitals collector installed');
|
|
1004
|
-
}
|
|
1045
|
+
console.log('[Monitor] Web Vitals collector installed');
|
|
1005
1046
|
}
|
|
1006
1047
|
/**
|
|
1007
1048
|
* 采集性能指标
|
|
1008
1049
|
*/
|
|
1009
1050
|
function collectMetrics() {
|
|
1051
|
+
// 检查配置(在采集时检查,而不是安装时)
|
|
1052
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1053
|
+
if (cfg?.performance?.enabled === false || cfg?.performance?.webVitals === false) {
|
|
1054
|
+
return;
|
|
1055
|
+
}
|
|
1010
1056
|
const metrics = {};
|
|
1011
1057
|
// 使用 Performance API
|
|
1012
1058
|
if (!window.performance) {
|
|
@@ -1115,22 +1161,13 @@
|
|
|
1115
1161
|
installWebVitals();
|
|
1116
1162
|
}
|
|
1117
1163
|
|
|
1118
|
-
/**
|
|
1119
|
-
* PV (Page View) 统计插件
|
|
1120
|
-
*/
|
|
1121
1164
|
/**
|
|
1122
1165
|
* 安装 PV 统计
|
|
1123
1166
|
*/
|
|
1124
1167
|
function installPVTracker() {
|
|
1125
|
-
|
|
1126
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.pv) {
|
|
1127
|
-
return;
|
|
1128
|
-
}
|
|
1129
|
-
// 页面加载时上报
|
|
1168
|
+
// 页面加载时上报(reporter 会缓存直到 SDK 就绪)
|
|
1130
1169
|
reportPV();
|
|
1131
|
-
|
|
1132
|
-
console.log('[Monitor] PV tracker installed');
|
|
1133
|
-
}
|
|
1170
|
+
console.log('[Monitor] PV tracker installed');
|
|
1134
1171
|
}
|
|
1135
1172
|
/**
|
|
1136
1173
|
* 上报 PV
|
|
@@ -1153,11 +1190,12 @@
|
|
|
1153
1190
|
* 安装点击追踪
|
|
1154
1191
|
*/
|
|
1155
1192
|
function installClickTracker() {
|
|
1156
|
-
const cfg = config.get();
|
|
1157
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.click) {
|
|
1158
|
-
return;
|
|
1159
|
-
}
|
|
1160
1193
|
document.addEventListener('click', (event) => {
|
|
1194
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1195
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1196
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.click === false) {
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1161
1199
|
const target = event.target;
|
|
1162
1200
|
if (!target)
|
|
1163
1201
|
return;
|
|
@@ -1175,9 +1213,7 @@
|
|
|
1175
1213
|
// data: clickData,
|
|
1176
1214
|
// });
|
|
1177
1215
|
}, true);
|
|
1178
|
-
|
|
1179
|
-
console.log('[Monitor] Click tracker installed');
|
|
1180
|
-
}
|
|
1216
|
+
console.log('[Monitor] Click tracker installed');
|
|
1181
1217
|
}
|
|
1182
1218
|
/**
|
|
1183
1219
|
* 提取点击数据
|
|
@@ -1256,10 +1292,6 @@
|
|
|
1256
1292
|
* 安装路由监控
|
|
1257
1293
|
*/
|
|
1258
1294
|
function installRouteTracker() {
|
|
1259
|
-
const cfg = config.get();
|
|
1260
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.route) {
|
|
1261
|
-
return;
|
|
1262
|
-
}
|
|
1263
1295
|
// 拦截 pushState
|
|
1264
1296
|
history.pushState = function (...args) {
|
|
1265
1297
|
const result = originalPushState.apply(this, args);
|
|
@@ -1280,14 +1312,17 @@
|
|
|
1280
1312
|
window.addEventListener('hashchange', () => {
|
|
1281
1313
|
handleRouteChange('hashchange');
|
|
1282
1314
|
});
|
|
1283
|
-
|
|
1284
|
-
console.log('[Monitor] Route tracker installed');
|
|
1285
|
-
}
|
|
1315
|
+
console.log('[Monitor] Route tracker installed');
|
|
1286
1316
|
}
|
|
1287
1317
|
/**
|
|
1288
1318
|
* 处理路由变化
|
|
1289
1319
|
*/
|
|
1290
1320
|
function handleRouteChange(trigger) {
|
|
1321
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1322
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1323
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.route === false) {
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1291
1326
|
const routeData = {
|
|
1292
1327
|
url: getPageUrl(),
|
|
1293
1328
|
title: getPageTitle(),
|
|
@@ -1322,16 +1357,16 @@
|
|
|
1322
1357
|
* 安装控制台追踪
|
|
1323
1358
|
*/
|
|
1324
1359
|
function installConsoleTracker() {
|
|
1325
|
-
const cfg = config.get();
|
|
1326
|
-
// 默认启用控制台追踪(跟随 behavior.enabled)
|
|
1327
|
-
if (!cfg.behavior?.enabled) {
|
|
1328
|
-
return;
|
|
1329
|
-
}
|
|
1330
1360
|
const levels = ['log', 'info', 'warn', 'error'];
|
|
1331
1361
|
levels.forEach((level) => {
|
|
1332
1362
|
console[level] = function (...args) {
|
|
1333
1363
|
// 调用原始方法
|
|
1334
1364
|
originalConsole[level].apply(console, args);
|
|
1365
|
+
// 检查配置(在调用时检查,而不是安装时)
|
|
1366
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1367
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1368
|
+
return;
|
|
1369
|
+
}
|
|
1335
1370
|
// 添加到面包屑(只记录 warn 和 error)
|
|
1336
1371
|
if (level === 'warn' || level === 'error') {
|
|
1337
1372
|
const message = formatConsoleArgs(args);
|
|
@@ -1346,9 +1381,7 @@
|
|
|
1346
1381
|
}
|
|
1347
1382
|
};
|
|
1348
1383
|
});
|
|
1349
|
-
|
|
1350
|
-
originalConsole.log('[Monitor] Console tracker installed');
|
|
1351
|
-
}
|
|
1384
|
+
originalConsole.log('[Monitor] Console tracker installed');
|
|
1352
1385
|
}
|
|
1353
1386
|
/**
|
|
1354
1387
|
* 格式化控制台参数
|
|
@@ -1380,24 +1413,22 @@
|
|
|
1380
1413
|
* 安装输入追踪
|
|
1381
1414
|
*/
|
|
1382
1415
|
function installInputTracker() {
|
|
1383
|
-
const cfg = config.get();
|
|
1384
|
-
// 默认启用输入追踪(跟随 behavior.enabled)
|
|
1385
|
-
if (!cfg.behavior?.enabled) {
|
|
1386
|
-
return;
|
|
1387
|
-
}
|
|
1388
1416
|
// 监听 input 事件(使用 change 事件减少数据量)
|
|
1389
1417
|
document.addEventListener('change', handleInputChange, true);
|
|
1390
1418
|
// 监听焦点事件
|
|
1391
1419
|
document.addEventListener('focus', handleFocus, true);
|
|
1392
1420
|
document.addEventListener('blur', handleBlur, true);
|
|
1393
|
-
|
|
1394
|
-
console.log('[Monitor] Input tracker installed');
|
|
1395
|
-
}
|
|
1421
|
+
console.log('[Monitor] Input tracker installed');
|
|
1396
1422
|
}
|
|
1397
1423
|
/**
|
|
1398
1424
|
* 处理输入变化
|
|
1399
1425
|
*/
|
|
1400
1426
|
function handleInputChange(event) {
|
|
1427
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1428
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1429
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1430
|
+
return;
|
|
1431
|
+
}
|
|
1401
1432
|
const target = event.target;
|
|
1402
1433
|
if (!target || !isFormElement(target))
|
|
1403
1434
|
return;
|
|
@@ -1412,6 +1443,11 @@
|
|
|
1412
1443
|
* 处理焦点获取
|
|
1413
1444
|
*/
|
|
1414
1445
|
function handleFocus(event) {
|
|
1446
|
+
// 检查配置
|
|
1447
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1448
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1415
1451
|
const target = event.target;
|
|
1416
1452
|
if (!target || !isFormElement(target))
|
|
1417
1453
|
return;
|
|
@@ -1425,6 +1461,11 @@
|
|
|
1425
1461
|
* 处理焦点失去
|
|
1426
1462
|
*/
|
|
1427
1463
|
function handleBlur(event) {
|
|
1464
|
+
// 检查配置
|
|
1465
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1466
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1467
|
+
return;
|
|
1468
|
+
}
|
|
1428
1469
|
const target = event.target;
|
|
1429
1470
|
if (!target || !isFormElement(target))
|
|
1430
1471
|
return;
|