@be-link/cls-logger 1.0.1-beta.9 → 1.0.4
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/README.md +115 -31
- package/dist/ClsLogger.d.ts.map +1 -1
- package/dist/ClsLoggerCore.d.ts +4 -3
- package/dist/ClsLoggerCore.d.ts.map +1 -1
- package/dist/behaviorMonitor.d.ts.map +1 -1
- package/dist/errorMonitor.d.ts.map +1 -1
- package/dist/index.esm.js +176 -44
- package/dist/index.js +176 -44
- package/dist/index.umd.js +176 -44
- package/dist/mini.esm.js +111 -19
- package/dist/mini.js +111 -19
- package/dist/performanceMonitor.d.ts.map +1 -1
- package/dist/types.d.ts +19 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/web.esm.js +111 -19
- package/dist/web.js +111 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -562,6 +562,19 @@ function getPagePath$1() {
|
|
|
562
562
|
return '';
|
|
563
563
|
}
|
|
564
564
|
}
|
|
565
|
+
function getMpPagePath() {
|
|
566
|
+
try {
|
|
567
|
+
const pages = globalThis.getCurrentPages?.();
|
|
568
|
+
if (Array.isArray(pages) && pages.length > 0) {
|
|
569
|
+
const page = pages[pages.length - 1];
|
|
570
|
+
return page.route || page.__route__ || '';
|
|
571
|
+
}
|
|
572
|
+
return '';
|
|
573
|
+
}
|
|
574
|
+
catch {
|
|
575
|
+
return '';
|
|
576
|
+
}
|
|
577
|
+
}
|
|
565
578
|
function normalizeErrorLike(err, maxTextLength) {
|
|
566
579
|
if (err && typeof err === 'object') {
|
|
567
580
|
const anyErr = err;
|
|
@@ -721,6 +734,7 @@ function installMiniProgramErrorMonitor(report, options) {
|
|
|
721
734
|
return;
|
|
722
735
|
const e = normalizeErrorLike(msg, options.maxTextLength);
|
|
723
736
|
const payload = {
|
|
737
|
+
pagePath: getMpPagePath(),
|
|
724
738
|
source: 'wx.onError',
|
|
725
739
|
message: e.message,
|
|
726
740
|
errorName: e.name,
|
|
@@ -747,6 +761,7 @@ function installMiniProgramErrorMonitor(report, options) {
|
|
|
747
761
|
return;
|
|
748
762
|
const e = normalizeErrorLike(res?.reason, options.maxTextLength);
|
|
749
763
|
const payload = {
|
|
764
|
+
pagePath: getMpPagePath(),
|
|
750
765
|
source: 'wx.onUnhandledRejection',
|
|
751
766
|
message: e.message,
|
|
752
767
|
errorName: e.name,
|
|
@@ -778,6 +793,7 @@ function installMiniProgramErrorMonitor(report, options) {
|
|
|
778
793
|
if (sampleHit$1(options.sampleRate)) {
|
|
779
794
|
const e = normalizeErrorLike(args?.[0], options.maxTextLength);
|
|
780
795
|
const payload = {
|
|
796
|
+
pagePath: getMpPagePath(),
|
|
781
797
|
source: 'App.onError',
|
|
782
798
|
message: e.message,
|
|
783
799
|
errorName: e.name,
|
|
@@ -801,6 +817,7 @@ function installMiniProgramErrorMonitor(report, options) {
|
|
|
801
817
|
const reason = args?.[0]?.reason ?? args?.[0];
|
|
802
818
|
const e = normalizeErrorLike(reason, options.maxTextLength);
|
|
803
819
|
const payload = {
|
|
820
|
+
pagePath: getMpPagePath(),
|
|
804
821
|
source: 'App.onUnhandledRejection',
|
|
805
822
|
message: e.message,
|
|
806
823
|
errorName: e.name,
|
|
@@ -1108,18 +1125,28 @@ function installMiniProgramPerformanceMonitor(report, options) {
|
|
|
1108
1125
|
continue;
|
|
1109
1126
|
// Page Render: firstRender
|
|
1110
1127
|
if (entry.entryType === 'render' && entry.name === 'firstRender') {
|
|
1128
|
+
const duration = typeof entry.duration === 'number'
|
|
1129
|
+
? entry.duration
|
|
1130
|
+
: typeof entry.startTime === 'number' && typeof entry.endTime === 'number'
|
|
1131
|
+
? entry.endTime - entry.startTime
|
|
1132
|
+
: 0;
|
|
1111
1133
|
report(options.reportType, {
|
|
1112
1134
|
metric: 'page-render',
|
|
1113
|
-
duration
|
|
1135
|
+
duration,
|
|
1114
1136
|
pagePath: entry.path || '',
|
|
1115
1137
|
unit: 'ms',
|
|
1116
1138
|
});
|
|
1117
1139
|
}
|
|
1118
1140
|
// Route Switch: route
|
|
1119
1141
|
else if (entry.entryType === 'navigation' && entry.name === 'route') {
|
|
1142
|
+
const duration = typeof entry.duration === 'number'
|
|
1143
|
+
? entry.duration
|
|
1144
|
+
: typeof entry.startTime === 'number' && typeof entry.endTime === 'number'
|
|
1145
|
+
? entry.endTime - entry.startTime
|
|
1146
|
+
: 0;
|
|
1120
1147
|
report(options.reportType, {
|
|
1121
1148
|
metric: 'route',
|
|
1122
|
-
duration
|
|
1149
|
+
duration,
|
|
1123
1150
|
pagePath: entry.path || '',
|
|
1124
1151
|
unit: 'ms',
|
|
1125
1152
|
});
|
|
@@ -1463,7 +1490,7 @@ function installBehaviorMonitor(report, envType, options = {}) {
|
|
|
1463
1490
|
const tag = (el.tagName || '').toLowerCase();
|
|
1464
1491
|
const trackId = getAttr(el, clickTrackIdAttr);
|
|
1465
1492
|
// 过滤无效点击:白名单 tag + 没有 trackId
|
|
1466
|
-
if (clickWhiteList.includes(tag)
|
|
1493
|
+
if (clickWhiteList.includes(tag) || !trackId)
|
|
1467
1494
|
return;
|
|
1468
1495
|
void uvStatePromise.then(({ uvId, meta }) => {
|
|
1469
1496
|
if (destroyed)
|
|
@@ -1504,8 +1531,12 @@ function installBehaviorMonitor(report, envType, options = {}) {
|
|
|
1504
1531
|
g.Page = function patchedPage(conf) {
|
|
1505
1532
|
const originalOnShow = conf?.onShow;
|
|
1506
1533
|
conf.onShow = function (...args) {
|
|
1507
|
-
if (pvEnabled)
|
|
1508
|
-
|
|
1534
|
+
if (pvEnabled) {
|
|
1535
|
+
const pagePath = getPagePath();
|
|
1536
|
+
if (pagePath?.length > 0) {
|
|
1537
|
+
reportPv(pagePath);
|
|
1538
|
+
}
|
|
1539
|
+
}
|
|
1509
1540
|
return typeof originalOnShow === 'function' ? originalOnShow.apply(this, args) : undefined;
|
|
1510
1541
|
};
|
|
1511
1542
|
// 点击:wrap 页面 methods(bindtap 等会调用到这里的 handler)
|
|
@@ -1859,6 +1890,7 @@ class ClsLoggerCore {
|
|
|
1859
1890
|
this.endpoint = 'ap-shanghai.cls.tencentcs.com';
|
|
1860
1891
|
this.retryTimes = 10;
|
|
1861
1892
|
this.source = '127.0.0.1';
|
|
1893
|
+
this.enabled = true;
|
|
1862
1894
|
this.projectId = '';
|
|
1863
1895
|
this.projectName = '';
|
|
1864
1896
|
this.appId = '';
|
|
@@ -1889,9 +1921,14 @@ class ClsLoggerCore {
|
|
|
1889
1921
|
* 子类可按需重写(默认检测 wx)
|
|
1890
1922
|
*/
|
|
1891
1923
|
detectEnvType() {
|
|
1892
|
-
const
|
|
1893
|
-
|
|
1924
|
+
const g = globalThis;
|
|
1925
|
+
// 微信、支付宝、字节跳动、UniApp 等小程序环境通常都有特定全局变量
|
|
1926
|
+
if ((g.wx && typeof g.wx.getSystemInfoSync === 'function') ||
|
|
1927
|
+
(g.my && typeof g.my.getSystemInfoSync === 'function') ||
|
|
1928
|
+
(g.tt && typeof g.tt.getSystemInfoSync === 'function') ||
|
|
1929
|
+
(g.uni && typeof g.uni.getSystemInfoSync === 'function')) {
|
|
1894
1930
|
return 'miniprogram';
|
|
1931
|
+
}
|
|
1895
1932
|
return 'browser';
|
|
1896
1933
|
}
|
|
1897
1934
|
init(options) {
|
|
@@ -1929,6 +1966,7 @@ class ClsLoggerCore {
|
|
|
1929
1966
|
this.appId = options.appId ?? this.appId;
|
|
1930
1967
|
this.appVersion = options.appVersion ?? this.appVersion;
|
|
1931
1968
|
this.envType = nextEnvType;
|
|
1969
|
+
this.enabled = options.enabled ?? true;
|
|
1932
1970
|
// 可选:外部注入 SDK(优先级:sdkLoader > sdk)
|
|
1933
1971
|
this.sdkLoaderOverride = options.sdkLoader ?? this.sdkLoaderOverride;
|
|
1934
1972
|
this.sdkOverride = options.sdk ?? this.sdkOverride;
|
|
@@ -1945,15 +1983,17 @@ class ClsLoggerCore {
|
|
|
1945
1983
|
void this.getInstance().catch(() => {
|
|
1946
1984
|
// ignore
|
|
1947
1985
|
});
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1986
|
+
if (this.enabled) {
|
|
1987
|
+
// 启动时尝试发送失败缓存
|
|
1988
|
+
this.flushFailed();
|
|
1989
|
+
// 初始化后立即启动请求监听
|
|
1990
|
+
this.startRequestMonitor(options.requestMonitor);
|
|
1991
|
+
// 初始化后立即启动错误监控/性能监控
|
|
1992
|
+
this.startErrorMonitor(options.errorMonitor);
|
|
1993
|
+
this.startPerformanceMonitor(options.performanceMonitor);
|
|
1994
|
+
// 初始化后立即启动行为埋点(PV/UV/点击)
|
|
1995
|
+
this.startBehaviorMonitor(options.behaviorMonitor);
|
|
1996
|
+
}
|
|
1957
1997
|
}
|
|
1958
1998
|
getBaseFields() {
|
|
1959
1999
|
let auto = undefined;
|
|
@@ -2078,6 +2118,8 @@ class ClsLoggerCore {
|
|
|
2078
2118
|
* - 最终会把 fields 展开成 CLS 的 content(key/value 都会转成 string)
|
|
2079
2119
|
*/
|
|
2080
2120
|
put(fields, options = {}) {
|
|
2121
|
+
if (!this.enabled)
|
|
2122
|
+
return;
|
|
2081
2123
|
if (!fields)
|
|
2082
2124
|
return;
|
|
2083
2125
|
if (!this.topicId) {
|
|
@@ -2136,6 +2178,8 @@ class ClsLoggerCore {
|
|
|
2136
2178
|
* - 埋点入参必须是一维(扁平)Object,非原始值会被 stringify
|
|
2137
2179
|
*/
|
|
2138
2180
|
enqueue(fields, options = {}) {
|
|
2181
|
+
if (!this.enabled)
|
|
2182
|
+
return;
|
|
2139
2183
|
if (!fields)
|
|
2140
2184
|
return;
|
|
2141
2185
|
const time = Date.now();
|
|
@@ -2174,6 +2218,8 @@ class ClsLoggerCore {
|
|
|
2174
2218
|
* 批量上报(每条 item.data 展开为 log content)
|
|
2175
2219
|
*/
|
|
2176
2220
|
putBatch(queue) {
|
|
2221
|
+
if (!this.enabled)
|
|
2222
|
+
return;
|
|
2177
2223
|
if (!queue || queue.length === 0)
|
|
2178
2224
|
return;
|
|
2179
2225
|
if (!this.topicId) {
|
|
@@ -2217,6 +2263,8 @@ class ClsLoggerCore {
|
|
|
2217
2263
|
* 参考《一、概述》:统一上报入口(内存队列 + 批量发送)
|
|
2218
2264
|
*/
|
|
2219
2265
|
report(log) {
|
|
2266
|
+
if (!this.enabled)
|
|
2267
|
+
return;
|
|
2220
2268
|
if (!log?.type)
|
|
2221
2269
|
return;
|
|
2222
2270
|
if (!this.topicId) {
|
|
@@ -2264,15 +2312,57 @@ class ClsLoggerCore {
|
|
|
2264
2312
|
return nowTs + this.batchIntervalMs;
|
|
2265
2313
|
}
|
|
2266
2314
|
info(message, data = {}) {
|
|
2267
|
-
|
|
2315
|
+
let msg = '';
|
|
2316
|
+
let extra = {};
|
|
2317
|
+
if (message instanceof Error) {
|
|
2318
|
+
msg = message.message;
|
|
2319
|
+
extra = {
|
|
2320
|
+
stack: message.stack,
|
|
2321
|
+
name: message.name,
|
|
2322
|
+
...data,
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2325
|
+
else {
|
|
2326
|
+
msg = String(message);
|
|
2327
|
+
extra = data;
|
|
2328
|
+
}
|
|
2329
|
+
const payload = normalizeFlatFields({ message: msg, ...extra }, 'info');
|
|
2268
2330
|
this.report({ type: 'info', data: payload, timestamp: Date.now() });
|
|
2269
2331
|
}
|
|
2270
2332
|
warn(message, data = {}) {
|
|
2271
|
-
|
|
2333
|
+
let msg = '';
|
|
2334
|
+
let extra = {};
|
|
2335
|
+
if (message instanceof Error) {
|
|
2336
|
+
msg = message.message;
|
|
2337
|
+
extra = {
|
|
2338
|
+
stack: message.stack,
|
|
2339
|
+
name: message.name,
|
|
2340
|
+
...data,
|
|
2341
|
+
};
|
|
2342
|
+
}
|
|
2343
|
+
else {
|
|
2344
|
+
msg = String(message);
|
|
2345
|
+
extra = data;
|
|
2346
|
+
}
|
|
2347
|
+
const payload = normalizeFlatFields({ message: msg, ...extra }, 'warn');
|
|
2272
2348
|
this.report({ type: 'warn', data: payload, timestamp: Date.now() });
|
|
2273
2349
|
}
|
|
2274
2350
|
error(message, data = {}) {
|
|
2275
|
-
|
|
2351
|
+
let msg = '';
|
|
2352
|
+
let extra = {};
|
|
2353
|
+
if (message instanceof Error) {
|
|
2354
|
+
msg = message.message;
|
|
2355
|
+
extra = {
|
|
2356
|
+
stack: message.stack,
|
|
2357
|
+
name: message.name,
|
|
2358
|
+
...data,
|
|
2359
|
+
};
|
|
2360
|
+
}
|
|
2361
|
+
else {
|
|
2362
|
+
msg = String(message);
|
|
2363
|
+
extra = data;
|
|
2364
|
+
}
|
|
2365
|
+
const payload = normalizeFlatFields({ message: msg, ...extra }, 'error');
|
|
2276
2366
|
this.report({ type: 'error', data: payload, timestamp: Date.now() });
|
|
2277
2367
|
}
|
|
2278
2368
|
track(trackType, data = {}) {
|
|
@@ -2379,6 +2469,8 @@ class ClsLoggerCore {
|
|
|
2379
2469
|
writeStringStorage(this.failedCacheKey, JSON.stringify(next));
|
|
2380
2470
|
}
|
|
2381
2471
|
flushFailed() {
|
|
2472
|
+
if (!this.enabled)
|
|
2473
|
+
return;
|
|
2382
2474
|
const raw = readStringStorage(this.failedCacheKey);
|
|
2383
2475
|
if (!raw)
|
|
2384
2476
|
return;
|
|
@@ -2494,38 +2586,78 @@ class ClsLogger extends ClsLoggerCore {
|
|
|
2494
2586
|
}
|
|
2495
2587
|
}
|
|
2496
2588
|
const isMini = this.envType === 'miniprogram';
|
|
2497
|
-
//
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2589
|
+
// 3) 尝试 require / 全局变量
|
|
2590
|
+
// Mini Program: 尝试直接 require
|
|
2591
|
+
if (isMini) {
|
|
2592
|
+
// 显式使用字面量 require,帮助打包工具识别依赖(尤其是 CJS 构建模式下)
|
|
2593
|
+
try {
|
|
2594
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
2595
|
+
const req = typeof require === 'function' ? require('tencentcloud-cls-sdk-js-mini') : null;
|
|
2596
|
+
const reqSdk = normalizeSdk(req);
|
|
2597
|
+
if (reqSdk) {
|
|
2598
|
+
this.sdk = reqSdk;
|
|
2599
|
+
return reqSdk;
|
|
2600
|
+
}
|
|
2601
|
+
}
|
|
2602
|
+
catch {
|
|
2603
|
+
// ignore
|
|
2604
|
+
}
|
|
2605
|
+
// 尝试使用 tryRequire(作为补充)
|
|
2606
|
+
const reqMod = tryRequire('tencentcloud-cls-sdk-js-mini');
|
|
2607
|
+
const reqSdk = normalizeSdk(reqMod);
|
|
2608
|
+
if (reqSdk) {
|
|
2609
|
+
this.sdk = reqSdk;
|
|
2610
|
+
return reqSdk;
|
|
2611
|
+
}
|
|
2612
|
+
}
|
|
2613
|
+
else {
|
|
2614
|
+
// Web: 优先读全局变量 (UMD)
|
|
2502
2615
|
const g = readGlobal('tencentcloudClsSdkJsWeb');
|
|
2503
2616
|
const sdk = normalizeSdk(g);
|
|
2504
2617
|
if (sdk) {
|
|
2505
2618
|
this.sdk = sdk;
|
|
2506
2619
|
return sdk;
|
|
2507
2620
|
}
|
|
2621
|
+
// Web: 尝试 require
|
|
2622
|
+
const reqMod = tryRequire('tencentcloud-cls-sdk-js-web');
|
|
2623
|
+
const reqSdk = normalizeSdk(reqMod);
|
|
2624
|
+
if (reqSdk) {
|
|
2625
|
+
this.sdk = reqSdk;
|
|
2626
|
+
return reqSdk;
|
|
2627
|
+
}
|
|
2628
|
+
}
|
|
2629
|
+
// 4) 动态 import
|
|
2630
|
+
// 使用字符串字面量,确保 Bundler 能正确识别并进行 Code Splitting
|
|
2631
|
+
if (isMini) {
|
|
2632
|
+
this.sdkPromise = import('tencentcloud-cls-sdk-js-mini')
|
|
2633
|
+
.then((m) => {
|
|
2634
|
+
const sdk = normalizeSdk(m);
|
|
2635
|
+
if (!sdk)
|
|
2636
|
+
throw new Error(`ClsLogger.loadSdk: invalid sdk module for mini`);
|
|
2637
|
+
this.sdk = sdk;
|
|
2638
|
+
return sdk;
|
|
2639
|
+
})
|
|
2640
|
+
.catch((err) => {
|
|
2641
|
+
this.sdkPromise = null;
|
|
2642
|
+
console.error('[ClsLogger] Failed to load mini sdk:', err);
|
|
2643
|
+
throw err;
|
|
2644
|
+
});
|
|
2645
|
+
}
|
|
2646
|
+
else {
|
|
2647
|
+
this.sdkPromise = import('tencentcloud-cls-sdk-js-web')
|
|
2648
|
+
.then((m) => {
|
|
2649
|
+
const sdk = normalizeSdk(m);
|
|
2650
|
+
if (!sdk)
|
|
2651
|
+
throw new Error(`ClsLogger.loadSdk: invalid sdk module for web`);
|
|
2652
|
+
this.sdk = sdk;
|
|
2653
|
+
return sdk;
|
|
2654
|
+
})
|
|
2655
|
+
.catch((err) => {
|
|
2656
|
+
this.sdkPromise = null;
|
|
2657
|
+
console.error('[ClsLogger] Failed to load web sdk:', err);
|
|
2658
|
+
throw err;
|
|
2659
|
+
});
|
|
2508
2660
|
}
|
|
2509
|
-
// 尽量同步 require
|
|
2510
|
-
const reqMod = tryRequire(isMini ? MINI_SDK : WEB_SDK);
|
|
2511
|
-
const reqSdk = normalizeSdk(reqMod);
|
|
2512
|
-
if (reqSdk) {
|
|
2513
|
-
this.sdk = reqSdk;
|
|
2514
|
-
return reqSdk;
|
|
2515
|
-
}
|
|
2516
|
-
// 动态 import
|
|
2517
|
-
this.sdkPromise = (isMini ? import(MINI_SDK) : import(WEB_SDK))
|
|
2518
|
-
.then((m) => {
|
|
2519
|
-
const sdk = normalizeSdk(m);
|
|
2520
|
-
if (!sdk)
|
|
2521
|
-
throw new Error(`ClsLogger.loadSdk: invalid sdk module for ${isMini ? MINI_SDK : WEB_SDK}`);
|
|
2522
|
-
this.sdk = sdk;
|
|
2523
|
-
return sdk;
|
|
2524
|
-
})
|
|
2525
|
-
.catch((err) => {
|
|
2526
|
-
this.sdkPromise = null;
|
|
2527
|
-
throw err;
|
|
2528
|
-
});
|
|
2529
2661
|
return this.sdkPromise;
|
|
2530
2662
|
}
|
|
2531
2663
|
}
|