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