@be-link/cls-logger 1.0.1-beta.8 → 1.0.3

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/web.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,
@@ -1086,140 +1103,68 @@ function installBrowserPerformanceMonitor(report, options) {
1086
1103
  }
1087
1104
  }
1088
1105
  }
1089
- function wrapMiniProgramRouteApi(report, reportType, apiName, options) {
1090
- const wxAny = globalThis.wx;
1091
- if (!wxAny || typeof wxAny[apiName] !== 'function')
1092
- return;
1093
- const flagKey = `__beLinkClsLoggerMpRouteWrapped__${apiName}`;
1094
- if (wxAny[flagKey])
1095
- return;
1096
- wxAny[flagKey] = true;
1097
- const raw = wxAny[apiName].bind(wxAny);
1098
- wxAny[apiName] = (opts) => {
1099
- const start = Date.now();
1100
- const url = opts?.url ? String(opts.url) : '';
1101
- const wrapCb = (cb, success) => {
1102
- return (...args) => {
1103
- try {
1104
- if (sampleHit(options.sampleRate)) {
1105
- report(reportType, {
1106
- metric: 'route',
1107
- api: apiName,
1108
- url,
1109
- duration: Date.now() - start,
1110
- success: success ? 1 : 0,
1111
- error: success ? '' : truncate$1(stringifyLogValue(args?.[0]), options.maxTextLength),
1112
- unit: 'ms',
1113
- });
1114
- }
1115
- }
1116
- catch {
1117
- // ignore
1118
- }
1119
- if (typeof cb === 'function')
1120
- return cb(...args);
1121
- return undefined;
1122
- };
1123
- };
1124
- const next = { ...(opts ?? {}) };
1125
- next.success = wrapCb(next.success, true);
1126
- next.fail = wrapCb(next.fail, false);
1127
- return raw(next);
1128
- };
1129
- }
1130
- function installMiniProgramPageRenderMonitor(report, reportType, options) {
1131
- const g = globalThis;
1132
- if (typeof g.Page !== 'function')
1133
- return;
1134
- if (g.__beLinkClsLoggerPageWrapped__)
1135
- return;
1136
- g.__beLinkClsLoggerPageWrapped__ = true;
1137
- const rawPage = g.Page;
1138
- g.Page = (pageOptions) => {
1139
- const next = { ...(pageOptions ?? {}) };
1140
- const rawOnLoad = next.onLoad;
1141
- const rawOnReady = next.onReady;
1142
- next.onLoad = function (...args) {
1143
- try {
1144
- this.__beLinkClsLoggerPageLoadTs__ = Date.now();
1145
- }
1146
- catch {
1147
- // ignore
1148
- }
1149
- if (typeof rawOnLoad === 'function')
1150
- return rawOnLoad.apply(this, args);
1151
- return undefined;
1152
- };
1153
- next.onReady = function (...args) {
1154
- try {
1155
- const start = this.__beLinkClsLoggerPageLoadTs__;
1156
- if (typeof start === 'number' && sampleHit(options.sampleRate)) {
1157
- report(reportType, {
1158
- metric: 'page-render',
1159
- route: this?.route ? String(this.route) : '',
1160
- duration: Date.now() - start,
1161
- unit: 'ms',
1162
- });
1163
- }
1164
- }
1165
- catch {
1166
- // ignore
1167
- }
1168
- if (typeof rawOnReady === 'function')
1169
- return rawOnReady.apply(this, args);
1170
- return undefined;
1171
- };
1172
- return rawPage(next);
1173
- };
1174
- }
1175
1106
  function installMiniProgramPerformanceMonitor(report, options) {
1176
1107
  const g = globalThis;
1108
+ const ctx = g.wx || g.Taro;
1109
+ if (!ctx || typeof ctx.getPerformance !== 'function')
1110
+ return;
1177
1111
  if (g.__beLinkClsLoggerMpPerfInstalled__)
1178
1112
  return;
1179
1113
  g.__beLinkClsLoggerMpPerfInstalled__ = true;
1180
- // 路由切换耗时(用 API 回调近似)
1181
- for (const apiName of ['navigateTo', 'redirectTo', 'switchTab', 'reLaunch']) {
1182
- try {
1183
- wrapMiniProgramRouteApi(report, options.reportType, apiName, options);
1184
- }
1185
- catch {
1186
- // ignore
1187
- }
1188
- }
1189
- // 页面渲染耗时(onLoad -> onReady)
1190
- try {
1191
- installMiniProgramPageRenderMonitor(report, options.reportType, options);
1192
- }
1193
- catch {
1194
- // ignore
1195
- }
1196
- // wx.getPerformance()(若可用,尝试读取已有 entries)
1197
1114
  try {
1198
- const wxAny = globalThis.wx;
1199
- if (wxAny && typeof wxAny.getPerformance === 'function') {
1200
- const perf = wxAny.getPerformance();
1201
- if (perf && isPlainObject(perf)) {
1202
- // 不同基础库实现差异较大:尽量容错
1203
- setTimeout(() => {
1204
- try {
1205
- if (!sampleHit(options.sampleRate))
1206
- return;
1207
- const entries = typeof perf.getEntries === 'function'
1208
- ? perf.getEntries()
1209
- : typeof perf.getEntriesByType === 'function'
1210
- ? perf.getEntriesByType('navigation')
1211
- : [];
1115
+ const perf = ctx.getPerformance();
1116
+ if (!perf || typeof perf.createObserver !== 'function')
1117
+ return;
1118
+ const observer = perf.createObserver((entryList) => {
1119
+ try {
1120
+ const entries = entryList.getEntries();
1121
+ for (const entry of entries) {
1122
+ if (!sampleHit(options.sampleRate))
1123
+ continue;
1124
+ // Page Render: firstRender
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;
1212
1131
  report(options.reportType, {
1213
- metric: 'mp-performance',
1214
- entries: truncate$1(stringifyLogValue(entries), options.maxTextLength),
1132
+ metric: 'page-render',
1133
+ duration,
1134
+ pagePath: entry.path || '',
1135
+ unit: 'ms',
1215
1136
  });
1216
1137
  }
1217
- catch {
1218
- // ignore
1138
+ // Route Switch: route
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;
1145
+ report(options.reportType, {
1146
+ metric: 'route',
1147
+ duration,
1148
+ pagePath: entry.path || '',
1149
+ unit: 'ms',
1150
+ });
1219
1151
  }
1220
- }, 0);
1152
+ // App Launch: appLaunch (Cold)
1153
+ else if (entry.entryType === 'navigation' && entry.name === 'appLaunch') {
1154
+ report(options.reportType, {
1155
+ metric: 'app-launch',
1156
+ duration: entry.duration,
1157
+ launchType: 'cold',
1158
+ unit: 'ms',
1159
+ });
1160
+ }
1161
+ }
1221
1162
  }
1222
- }
1163
+ catch {
1164
+ // ignore
1165
+ }
1166
+ });
1167
+ observer.observe({ entryTypes: ['navigation', 'render'] });
1223
1168
  }
1224
1169
  catch {
1225
1170
  // ignore
@@ -1543,7 +1488,7 @@ function installBehaviorMonitor(report, envType, options = {}) {
1543
1488
  const tag = (el.tagName || '').toLowerCase();
1544
1489
  const trackId = getAttr(el, clickTrackIdAttr);
1545
1490
  // 过滤无效点击:白名单 tag + 没有 trackId
1546
- if (clickWhiteList.includes(tag) && !trackId)
1491
+ if (clickWhiteList.includes(tag) || !trackId)
1547
1492
  return;
1548
1493
  void uvStatePromise.then(({ uvId, meta }) => {
1549
1494
  if (destroyed)
@@ -1584,8 +1529,12 @@ function installBehaviorMonitor(report, envType, options = {}) {
1584
1529
  g.Page = function patchedPage(conf) {
1585
1530
  const originalOnShow = conf?.onShow;
1586
1531
  conf.onShow = function (...args) {
1587
- if (pvEnabled)
1588
- reportPv(getPagePath());
1532
+ if (pvEnabled) {
1533
+ const pagePath = getPagePath();
1534
+ if (pagePath?.length > 0) {
1535
+ reportPv(pagePath);
1536
+ }
1537
+ }
1589
1538
  return typeof originalOnShow === 'function' ? originalOnShow.apply(this, args) : undefined;
1590
1539
  };
1591
1540
  // 点击:wrap 页面 methods(bindtap 等会调用到这里的 handler)
@@ -1969,9 +1918,14 @@ class ClsLoggerCore {
1969
1918
  * 子类可按需重写(默认检测 wx)
1970
1919
  */
1971
1920
  detectEnvType() {
1972
- const wxAny = globalThis.wx;
1973
- if (wxAny && typeof wxAny.getSystemInfoSync === 'function')
1921
+ const g = globalThis;
1922
+ // 微信、支付宝、字节跳动、UniApp 等小程序环境通常都有特定全局变量
1923
+ if ((g.wx && typeof g.wx.getSystemInfoSync === 'function') ||
1924
+ (g.my && typeof g.my.getSystemInfoSync === 'function') ||
1925
+ (g.tt && typeof g.tt.getSystemInfoSync === 'function') ||
1926
+ (g.uni && typeof g.uni.getSystemInfoSync === 'function')) {
1974
1927
  return 'miniprogram';
1928
+ }
1975
1929
  return 'browser';
1976
1930
  }
1977
1931
  init(options) {
@@ -2344,15 +2298,57 @@ class ClsLoggerCore {
2344
2298
  return nowTs + this.batchIntervalMs;
2345
2299
  }
2346
2300
  info(message, data = {}) {
2347
- const payload = normalizeFlatFields({ message, ...data }, 'info');
2301
+ let msg = '';
2302
+ let extra = {};
2303
+ if (message instanceof Error) {
2304
+ msg = message.message;
2305
+ extra = {
2306
+ stack: message.stack,
2307
+ name: message.name,
2308
+ ...data,
2309
+ };
2310
+ }
2311
+ else {
2312
+ msg = String(message);
2313
+ extra = data;
2314
+ }
2315
+ const payload = normalizeFlatFields({ message: msg, ...extra }, 'info');
2348
2316
  this.report({ type: 'info', data: payload, timestamp: Date.now() });
2349
2317
  }
2350
2318
  warn(message, data = {}) {
2351
- const payload = normalizeFlatFields({ message, ...data }, 'warn');
2319
+ let msg = '';
2320
+ let extra = {};
2321
+ if (message instanceof Error) {
2322
+ msg = message.message;
2323
+ extra = {
2324
+ stack: message.stack,
2325
+ name: message.name,
2326
+ ...data,
2327
+ };
2328
+ }
2329
+ else {
2330
+ msg = String(message);
2331
+ extra = data;
2332
+ }
2333
+ const payload = normalizeFlatFields({ message: msg, ...extra }, 'warn');
2352
2334
  this.report({ type: 'warn', data: payload, timestamp: Date.now() });
2353
2335
  }
2354
2336
  error(message, data = {}) {
2355
- const payload = normalizeFlatFields({ message, ...data }, 'error');
2337
+ let msg = '';
2338
+ let extra = {};
2339
+ if (message instanceof Error) {
2340
+ msg = message.message;
2341
+ extra = {
2342
+ stack: message.stack,
2343
+ name: message.name,
2344
+ ...data,
2345
+ };
2346
+ }
2347
+ else {
2348
+ msg = String(message);
2349
+ extra = data;
2350
+ }
2351
+ const payload = normalizeFlatFields({ message: msg, ...extra }, 'error');
2356
2352
  this.report({ type: 'error', data: payload, timestamp: Date.now() });
2357
2353
  }
2358
2354
  track(trackType, data = {}) {