@be-link/cls-logger 1.0.1-beta.4 → 1.0.1-beta.6
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/ClsLogger.d.ts +9 -96
- package/dist/ClsLogger.d.ts.map +1 -1
- package/dist/ClsLoggerCore.d.ts +127 -0
- package/dist/ClsLoggerCore.d.ts.map +1 -0
- package/dist/ClsLoggerMini.d.ts +8 -0
- package/dist/ClsLoggerMini.d.ts.map +1 -0
- package/dist/ClsLoggerWeb.d.ts +8 -0
- package/dist/ClsLoggerWeb.d.ts.map +1 -0
- package/dist/clsSdkTypes.d.ts +18 -0
- package/dist/clsSdkTypes.d.ts.map +1 -0
- package/dist/index.esm.js +214 -31
- package/dist/index.js +214 -31
- package/dist/index.umd.js +218 -33
- package/dist/mini.d.ts +6 -0
- package/dist/mini.d.ts.map +1 -0
- package/dist/mini.esm.js +2553 -0
- package/dist/mini.js +2578 -0
- package/dist/sdkUtils.d.ts +3 -0
- package/dist/sdkUtils.d.ts.map +1 -0
- package/dist/types.d.ts +11 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/web.d.ts +6 -0
- package/dist/web.d.ts.map +1 -0
- package/dist/web.esm.js +2523 -0
- package/dist/web.js +2548 -0
- package/package.json +27 -2
package/dist/index.umd.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BeLinkClsLogger = {}
|
|
5
|
-
})(this, (function (exports
|
|
2
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
+
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.BeLinkClsLogger = {}));
|
|
5
|
+
})(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
7
|
function isPlainObject(value) {
|
|
8
8
|
return Object.prototype.toString.call(value) === '[object Object]';
|
|
@@ -1909,9 +1909,20 @@
|
|
|
1909
1909
|
g.__beLinkClsLoggerSendingCount__ = cur > 0 ? cur - 1 : 0;
|
|
1910
1910
|
};
|
|
1911
1911
|
}
|
|
1912
|
-
|
|
1912
|
+
/**
|
|
1913
|
+
* CLS Logger 核心基类
|
|
1914
|
+
* - 负责所有上报、队列、监控逻辑
|
|
1915
|
+
* - 不包含具体的 SDK 加载实现(由子类负责)
|
|
1916
|
+
* - 这样可以把 web/mini 的 SDK 依赖彻底解耦到子入口
|
|
1917
|
+
*/
|
|
1918
|
+
class ClsLoggerCore {
|
|
1913
1919
|
constructor() {
|
|
1920
|
+
this.sdk = null;
|
|
1921
|
+
this.sdkPromise = null;
|
|
1922
|
+
this.sdkOverride = null;
|
|
1923
|
+
this.sdkLoaderOverride = null;
|
|
1914
1924
|
this.client = null;
|
|
1925
|
+
this.clientPromise = null;
|
|
1915
1926
|
this.topicId = null;
|
|
1916
1927
|
this.endpoint = 'ap-shanghai.cls.tencentcs.com';
|
|
1917
1928
|
this.retryTimes = 10;
|
|
@@ -1942,6 +1953,15 @@
|
|
|
1942
1953
|
this.behaviorMonitorStarted = false;
|
|
1943
1954
|
this.behaviorMonitorCleanup = null;
|
|
1944
1955
|
}
|
|
1956
|
+
/**
|
|
1957
|
+
* 子类可按需重写(默认检测 wx)
|
|
1958
|
+
*/
|
|
1959
|
+
detectEnvType() {
|
|
1960
|
+
const wxAny = globalThis.wx;
|
|
1961
|
+
if (wxAny && typeof wxAny.getSystemInfoSync === 'function')
|
|
1962
|
+
return 'miniprogram';
|
|
1963
|
+
return 'browser';
|
|
1964
|
+
}
|
|
1945
1965
|
init(options) {
|
|
1946
1966
|
this.initTs = Date.now();
|
|
1947
1967
|
const topicId = options?.tencentCloud?.topicID ?? options?.topic_id ?? options?.topicID ?? this.topicId ?? null;
|
|
@@ -1953,6 +1973,19 @@
|
|
|
1953
1973
|
console.warn('ClsLogger.init 没有传 topicID/topic_id');
|
|
1954
1974
|
return;
|
|
1955
1975
|
}
|
|
1976
|
+
const nextEnvType = options.envType ?? this.detectEnvType();
|
|
1977
|
+
// envType/endpoint/retryTimes 变化时:重置 client(以及可能的 sdk)
|
|
1978
|
+
const envChanged = nextEnvType !== this.envType;
|
|
1979
|
+
const endpointChanged = endpoint !== this.endpoint;
|
|
1980
|
+
const retryChanged = retryTimes !== this.retryTimes;
|
|
1981
|
+
if (envChanged || endpointChanged || retryChanged) {
|
|
1982
|
+
this.client = null;
|
|
1983
|
+
this.clientPromise = null;
|
|
1984
|
+
}
|
|
1985
|
+
if (envChanged) {
|
|
1986
|
+
this.sdk = null;
|
|
1987
|
+
this.sdkPromise = null;
|
|
1988
|
+
}
|
|
1956
1989
|
this.topicId = topicId;
|
|
1957
1990
|
this.endpoint = endpoint;
|
|
1958
1991
|
this.retryTimes = retryTimes;
|
|
@@ -1963,7 +1996,10 @@
|
|
|
1963
1996
|
this.projectName = options.projectName ?? this.projectName;
|
|
1964
1997
|
this.appId = options.appId ?? this.appId;
|
|
1965
1998
|
this.appVersion = options.appVersion ?? this.appVersion;
|
|
1966
|
-
this.envType =
|
|
1999
|
+
this.envType = nextEnvType;
|
|
2000
|
+
// 可选:外部注入 SDK(优先级:sdkLoader > sdk)
|
|
2001
|
+
this.sdkLoaderOverride = options.sdkLoader ?? this.sdkLoaderOverride;
|
|
2002
|
+
this.sdkOverride = options.sdk ?? this.sdkOverride;
|
|
1967
2003
|
this.userGenerateBaseFields = options.generateBaseFields ?? this.userGenerateBaseFields;
|
|
1968
2004
|
this.autoGenerateBaseFields = createAutoDeviceInfoBaseFields(this.envType, options.deviceInfo);
|
|
1969
2005
|
this.storageKey = options.storageKey ?? this.storageKey;
|
|
@@ -1973,8 +2009,10 @@
|
|
|
1973
2009
|
this.startupDelayMs = options.batch?.startupDelayMs ?? this.startupDelayMs;
|
|
1974
2010
|
this.failedCacheKey = options.failedCacheKey ?? this.failedCacheKey;
|
|
1975
2011
|
this.failedCacheMax = options.failedCacheMax ?? this.failedCacheMax;
|
|
1976
|
-
//
|
|
1977
|
-
this.getInstance()
|
|
2012
|
+
// 预热(避免首条日志触发 import/初始化开销)
|
|
2013
|
+
void this.getInstance().catch(() => {
|
|
2014
|
+
// ignore
|
|
2015
|
+
});
|
|
1978
2016
|
// 启动时尝试发送失败缓存
|
|
1979
2017
|
this.flushFailed();
|
|
1980
2018
|
// 初始化后立即启动请求监听
|
|
@@ -2078,20 +2116,29 @@
|
|
|
2078
2116
|
this.behaviorMonitorCleanup = null;
|
|
2079
2117
|
this.behaviorMonitorStarted = false;
|
|
2080
2118
|
}
|
|
2081
|
-
|
|
2119
|
+
/**
|
|
2120
|
+
* 获取 CLS client(按环境懒加载 SDK)
|
|
2121
|
+
*/
|
|
2122
|
+
async getInstance() {
|
|
2082
2123
|
if (this.client)
|
|
2083
2124
|
return this.client;
|
|
2084
|
-
this.
|
|
2085
|
-
|
|
2086
|
-
|
|
2125
|
+
if (this.clientPromise)
|
|
2126
|
+
return this.clientPromise;
|
|
2127
|
+
this.clientPromise = this.loadSdk()
|
|
2128
|
+
.then(({ AsyncClient }) => {
|
|
2129
|
+
const client = new AsyncClient({
|
|
2130
|
+
endpoint: this.endpoint,
|
|
2131
|
+
retry_times: this.retryTimes,
|
|
2132
|
+
});
|
|
2133
|
+
this.client = client;
|
|
2134
|
+
return client;
|
|
2135
|
+
})
|
|
2136
|
+
.catch((err) => {
|
|
2137
|
+
// 失败后允许下次重试
|
|
2138
|
+
this.clientPromise = null;
|
|
2139
|
+
throw err;
|
|
2087
2140
|
});
|
|
2088
|
-
return this.
|
|
2089
|
-
}
|
|
2090
|
-
detectEnvType() {
|
|
2091
|
-
const wxAny = globalThis.wx;
|
|
2092
|
-
if (wxAny && typeof wxAny.getSystemInfoSync === 'function')
|
|
2093
|
-
return 'miniprogram';
|
|
2094
|
-
return 'browser';
|
|
2141
|
+
return this.clientPromise;
|
|
2095
2142
|
}
|
|
2096
2143
|
/**
|
|
2097
2144
|
* 直接上报:埋点入参必须是一维(扁平)Object
|
|
@@ -2117,22 +2164,33 @@
|
|
|
2117
2164
|
appVersion: this.appVersion || undefined,
|
|
2118
2165
|
...normalizedFields,
|
|
2119
2166
|
});
|
|
2120
|
-
|
|
2121
|
-
|
|
2167
|
+
// 同步 API:内部异步发送,避免把网络异常冒泡到业务(尤其小程序)
|
|
2168
|
+
void this.putAsync(finalFields).catch(() => {
|
|
2169
|
+
// ignore
|
|
2170
|
+
});
|
|
2171
|
+
}
|
|
2172
|
+
async putAsync(finalFields) {
|
|
2173
|
+
if (!this.topicId)
|
|
2174
|
+
return;
|
|
2175
|
+
const sdk = await this.loadSdk();
|
|
2176
|
+
const client = await this.getInstance();
|
|
2177
|
+
const logGroup = new sdk.LogGroup('127.0.0.1');
|
|
2122
2178
|
logGroup.setSource(this.source);
|
|
2123
|
-
const log = new
|
|
2179
|
+
const log = new sdk.Log(Date.now());
|
|
2124
2180
|
for (const key of Object.keys(finalFields)) {
|
|
2125
2181
|
log.addContent(key, stringifyLogValue(finalFields[key]));
|
|
2126
2182
|
}
|
|
2127
2183
|
logGroup.addLog(log);
|
|
2128
|
-
const request = new
|
|
2184
|
+
const request = new sdk.PutLogsRequest(this.topicId, logGroup);
|
|
2129
2185
|
const exit = enterClsSendingGuard();
|
|
2186
|
+
let p;
|
|
2130
2187
|
try {
|
|
2131
|
-
client.PutLogs(request);
|
|
2188
|
+
p = client.PutLogs(request);
|
|
2132
2189
|
}
|
|
2133
2190
|
finally {
|
|
2134
2191
|
exit();
|
|
2135
2192
|
}
|
|
2193
|
+
await p;
|
|
2136
2194
|
}
|
|
2137
2195
|
/**
|
|
2138
2196
|
* 直接上报:把 data 序列化后放入指定 key(默认 “日志内容”)
|
|
@@ -2191,11 +2249,19 @@
|
|
|
2191
2249
|
console.warn('ClsLogger.putBatch:未初始化 topic_id');
|
|
2192
2250
|
return;
|
|
2193
2251
|
}
|
|
2194
|
-
|
|
2195
|
-
|
|
2252
|
+
void this.putBatchAsync(queue).catch(() => {
|
|
2253
|
+
// ignore
|
|
2254
|
+
});
|
|
2255
|
+
}
|
|
2256
|
+
async putBatchAsync(queue) {
|
|
2257
|
+
if (!this.topicId)
|
|
2258
|
+
return;
|
|
2259
|
+
const sdk = await this.loadSdk();
|
|
2260
|
+
const client = await this.getInstance();
|
|
2261
|
+
const logGroup = new sdk.LogGroup('127.0.0.1');
|
|
2196
2262
|
logGroup.setSource(this.source);
|
|
2197
2263
|
for (const item of queue) {
|
|
2198
|
-
const log = new
|
|
2264
|
+
const log = new sdk.Log(item.time);
|
|
2199
2265
|
const data = item.data ?? {};
|
|
2200
2266
|
for (const key of Object.keys(data)) {
|
|
2201
2267
|
log.addContent(key, stringifyLogValue(data[key]));
|
|
@@ -2204,14 +2270,16 @@
|
|
|
2204
2270
|
}
|
|
2205
2271
|
if (logGroup.getLogs().length === 0)
|
|
2206
2272
|
return;
|
|
2207
|
-
const request = new
|
|
2273
|
+
const request = new sdk.PutLogsRequest(this.topicId, logGroup);
|
|
2208
2274
|
const exit = enterClsSendingGuard();
|
|
2275
|
+
let p;
|
|
2209
2276
|
try {
|
|
2210
|
-
client.PutLogs(request);
|
|
2277
|
+
p = client.PutLogs(request);
|
|
2211
2278
|
}
|
|
2212
2279
|
finally {
|
|
2213
2280
|
exit();
|
|
2214
2281
|
}
|
|
2282
|
+
await p;
|
|
2215
2283
|
}
|
|
2216
2284
|
/**
|
|
2217
2285
|
* 参考《一、概述》:统一上报入口(内存队列 + 批量发送)
|
|
@@ -2324,12 +2392,13 @@
|
|
|
2324
2392
|
async sendReportLogs(logs) {
|
|
2325
2393
|
if (!this.topicId)
|
|
2326
2394
|
return;
|
|
2327
|
-
const
|
|
2328
|
-
const
|
|
2395
|
+
const sdk = await this.loadSdk();
|
|
2396
|
+
const client = await this.getInstance();
|
|
2397
|
+
const logGroup = new sdk.LogGroup('127.0.0.1');
|
|
2329
2398
|
logGroup.setSource(this.source);
|
|
2330
2399
|
for (const item of logs) {
|
|
2331
2400
|
const fields = this.buildReportFields(item);
|
|
2332
|
-
const log = new
|
|
2401
|
+
const log = new sdk.Log(fields.timestamp);
|
|
2333
2402
|
for (const key of Object.keys(fields)) {
|
|
2334
2403
|
if (key === 'timestamp')
|
|
2335
2404
|
continue;
|
|
@@ -2337,7 +2406,7 @@
|
|
|
2337
2406
|
}
|
|
2338
2407
|
logGroup.addLog(log);
|
|
2339
2408
|
}
|
|
2340
|
-
const request = new
|
|
2409
|
+
const request = new sdk.PutLogsRequest(this.topicId, logGroup);
|
|
2341
2410
|
// 只在“发起网络请求”的同步阶段打标记,避免 requestMonitor 监控 CLS 上报请求导致递归
|
|
2342
2411
|
const exit = enterClsSendingGuard();
|
|
2343
2412
|
let p;
|
|
@@ -2413,6 +2482,122 @@
|
|
|
2413
2482
|
}
|
|
2414
2483
|
}
|
|
2415
2484
|
|
|
2485
|
+
function readGlobal(key) {
|
|
2486
|
+
try {
|
|
2487
|
+
const g = globalThis;
|
|
2488
|
+
return g[key] ?? null;
|
|
2489
|
+
}
|
|
2490
|
+
catch {
|
|
2491
|
+
return null;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
function tryRequire(moduleName) {
|
|
2495
|
+
try {
|
|
2496
|
+
// 说明:
|
|
2497
|
+
// - ESM 构建(exports.import/module)里通常不存在模块作用域的 require
|
|
2498
|
+
// - 一些小程序运行时/构建链路会把 require 挂到 globalThis 上
|
|
2499
|
+
// 因此这里同时探测“模块作用域 require”与 “globalThis.require”
|
|
2500
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
2501
|
+
const localReq = (typeof require === 'function' ? require : null);
|
|
2502
|
+
const globalReq = readGlobal('require');
|
|
2503
|
+
const candidates = [localReq, globalReq].filter((fn) => typeof fn === 'function');
|
|
2504
|
+
for (const fn of candidates) {
|
|
2505
|
+
try {
|
|
2506
|
+
return fn(moduleName);
|
|
2507
|
+
}
|
|
2508
|
+
catch {
|
|
2509
|
+
// continue
|
|
2510
|
+
}
|
|
2511
|
+
}
|
|
2512
|
+
return null;
|
|
2513
|
+
}
|
|
2514
|
+
catch {
|
|
2515
|
+
return null;
|
|
2516
|
+
}
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
/**
|
|
2520
|
+
* 兼容版 ClsLogger(默认入口)
|
|
2521
|
+
* - 保留了自动识别环境 + 动态 import 的逻辑
|
|
2522
|
+
* - 如果业务想瘦身,建议改用 @be-link/cls-logger/web 或 /mini
|
|
2523
|
+
*/
|
|
2524
|
+
class ClsLogger extends ClsLoggerCore {
|
|
2525
|
+
async loadSdk() {
|
|
2526
|
+
if (this.sdk)
|
|
2527
|
+
return this.sdk;
|
|
2528
|
+
if (this.sdkPromise)
|
|
2529
|
+
return this.sdkPromise;
|
|
2530
|
+
const normalizeSdk = (m) => {
|
|
2531
|
+
const mod = (m?.default && m.default.AsyncClient ? m.default : m);
|
|
2532
|
+
if (mod?.AsyncClient && mod?.Log && mod?.LogGroup && mod?.PutLogsRequest) {
|
|
2533
|
+
return {
|
|
2534
|
+
AsyncClient: mod.AsyncClient,
|
|
2535
|
+
Log: mod.Log,
|
|
2536
|
+
LogGroup: mod.LogGroup,
|
|
2537
|
+
PutLogsRequest: mod.PutLogsRequest,
|
|
2538
|
+
};
|
|
2539
|
+
}
|
|
2540
|
+
return null;
|
|
2541
|
+
};
|
|
2542
|
+
// 1) 外部注入的 loader(最高优先级)
|
|
2543
|
+
if (this.sdkLoaderOverride) {
|
|
2544
|
+
try {
|
|
2545
|
+
const loaded = await this.sdkLoaderOverride();
|
|
2546
|
+
const sdk = normalizeSdk(loaded);
|
|
2547
|
+
if (sdk) {
|
|
2548
|
+
this.sdk = sdk;
|
|
2549
|
+
return sdk;
|
|
2550
|
+
}
|
|
2551
|
+
}
|
|
2552
|
+
catch {
|
|
2553
|
+
// ignore and fallback
|
|
2554
|
+
}
|
|
2555
|
+
}
|
|
2556
|
+
// 2) 外部直接注入的 sdk
|
|
2557
|
+
if (this.sdkOverride) {
|
|
2558
|
+
const sdk = normalizeSdk(this.sdkOverride);
|
|
2559
|
+
if (sdk) {
|
|
2560
|
+
this.sdk = sdk;
|
|
2561
|
+
return sdk;
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
const isMini = this.envType === 'miniprogram';
|
|
2565
|
+
// 静态字面量,方便打包器识别(但在此兼容入口里,仍然可能被一起分析)
|
|
2566
|
+
const WEB_SDK = 'tencentcloud-cls-sdk-js-web';
|
|
2567
|
+
const MINI_SDK = 'tencentcloud-cls-sdk-js-mini';
|
|
2568
|
+
// UMD(浏览器脚本)优先读全局变量
|
|
2569
|
+
if (!isMini) {
|
|
2570
|
+
const g = readGlobal('tencentcloudClsSdkJsWeb');
|
|
2571
|
+
const sdk = normalizeSdk(g);
|
|
2572
|
+
if (sdk) {
|
|
2573
|
+
this.sdk = sdk;
|
|
2574
|
+
return sdk;
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
// 尽量同步 require
|
|
2578
|
+
const reqMod = tryRequire(isMini ? MINI_SDK : WEB_SDK);
|
|
2579
|
+
const reqSdk = normalizeSdk(reqMod);
|
|
2580
|
+
if (reqSdk) {
|
|
2581
|
+
this.sdk = reqSdk;
|
|
2582
|
+
return reqSdk;
|
|
2583
|
+
}
|
|
2584
|
+
// 动态 import
|
|
2585
|
+
this.sdkPromise = (isMini ? import(MINI_SDK) : import(WEB_SDK))
|
|
2586
|
+
.then((m) => {
|
|
2587
|
+
const sdk = normalizeSdk(m);
|
|
2588
|
+
if (!sdk)
|
|
2589
|
+
throw new Error(`ClsLogger.loadSdk: invalid sdk module for ${isMini ? MINI_SDK : WEB_SDK}`);
|
|
2590
|
+
this.sdk = sdk;
|
|
2591
|
+
return sdk;
|
|
2592
|
+
})
|
|
2593
|
+
.catch((err) => {
|
|
2594
|
+
this.sdkPromise = null;
|
|
2595
|
+
throw err;
|
|
2596
|
+
});
|
|
2597
|
+
return this.sdkPromise;
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
|
|
2416
2601
|
const clsLogger = new ClsLogger();
|
|
2417
2602
|
|
|
2418
2603
|
exports.ClsLogger = ClsLogger;
|
package/dist/mini.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mini.d.ts","sourceRoot":"","sources":["../src/mini.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,cAAc,SAAS,CAAC;AACxB,OAAO,EAAE,aAAa,IAAI,SAAS,EAAE,CAAC;AACtC,eAAO,MAAM,SAAS,eAAsB,CAAC;AAC7C,eAAe,SAAS,CAAC"}
|