@pluve/logger-sdk 0.0.2 → 0.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 +40 -2
- package/dist/{cjs/index.d.ts → index.d.ts} +1 -1
- package/dist/{esm/index.js → index.js} +2 -2
- package/dist/{cjs/loggerSDK.d.ts → loggerSDK.d.ts} +1 -1
- package/dist/{esm/loggerSDK.js → loggerSDK.js} +8 -4
- package/dist/{esm/transportAdapter.js → transportAdapter.js} +34 -10
- package/dist/{esm/types.d.ts → types.d.ts} +5 -1
- package/dist/{esm/utils.d.ts → utils.d.ts} +17 -0
- package/dist/utils.js +361 -0
- package/package.json +3 -5
- package/dist/cjs/index.js +0 -41
- package/dist/cjs/loggerSDK.js +0 -158
- package/dist/cjs/transportAdapter.js +0 -182
- package/dist/cjs/types.d.ts +0 -46
- package/dist/cjs/types.js +0 -17
- package/dist/cjs/utils.d.ts +0 -30
- package/dist/cjs/utils.js +0 -208
- package/dist/esm/index.d.ts +0 -6
- package/dist/esm/loggerSDK.d.ts +0 -36
- package/dist/esm/transportAdapter.d.ts +0 -51
- package/dist/esm/utils.js +0 -229
- package/dist/umd/logger-sdk.min.js +0 -1
- package/lib/dbQueue.d.ts +0 -10
- package/lib/dbQueue.js +0 -133
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -9
- package/lib/loggerSDK.d.ts +0 -29
- package/lib/loggerSDK.js +0 -571
- package/lib/storeAdapter.d.ts +0 -7
- package/lib/storeAdapter.js +0 -99
- package/lib/transportAdapter.d.ts +0 -66
- package/lib/transportAdapter.js +0 -406
- package/lib/types.d.ts +0 -35
- package/lib/types.js +0 -1
- package/lib/utils.d.ts +0 -5
- package/lib/utils.js +0 -50
- /package/dist/{cjs/transportAdapter.d.ts → transportAdapter.d.ts} +0 -0
- /package/dist/{esm/types.js → types.js} +0 -0
package/README.md
CHANGED
|
@@ -35,6 +35,12 @@ sdk.track('error', 'TypeError: Cannot read property', {
|
|
|
35
35
|
},
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
+
// 记录带 traceId 的错误(用于关联多个日志)
|
|
39
|
+
sdk.track('error', 'Request failed', 'trace-abc-123', {
|
|
40
|
+
level: 'error',
|
|
41
|
+
tags: { api: '/api/user' },
|
|
42
|
+
});
|
|
43
|
+
|
|
38
44
|
// 记录自定义事件
|
|
39
45
|
sdk.track('custom', 'User clicked button', {
|
|
40
46
|
level: 'info',
|
|
@@ -48,6 +54,8 @@ sdk.track('custom', 'User clicked button', {
|
|
|
48
54
|
|
|
49
55
|
```typescript
|
|
50
56
|
{
|
|
57
|
+
"logId": "550e8400-e29b-41d4-a716-446655440000", // 日志 ID(UUID v4)
|
|
58
|
+
"traceId": "trace-123456", // 可选:追踪 ID(用于关联多个日志)
|
|
51
59
|
"eventType": "error", // 固定:error/crash/pageview/custom
|
|
52
60
|
"ts": 1690000000000, // 毫秒时间戳
|
|
53
61
|
"appId": "web-shop", // 应用标识
|
|
@@ -84,14 +92,15 @@ interface SDKOptions {
|
|
|
84
92
|
}
|
|
85
93
|
```
|
|
86
94
|
|
|
87
|
-
### `track(eventType, message, options?)`
|
|
95
|
+
### `track(eventType, message, traceId?, options?)`
|
|
88
96
|
|
|
89
|
-
|
|
97
|
+
记录事件日志。每条日志会自动生成唯一的 `logId`(UUID v4 格式)。
|
|
90
98
|
|
|
91
99
|
**参数:**
|
|
92
100
|
|
|
93
101
|
- `eventType`: 事件类型(`'error' | 'crash' | 'pageview' | 'custom'`)
|
|
94
102
|
- `message`: 摘要信息
|
|
103
|
+
- `traceId`: (可选) 追踪 ID,用于关联多个相关日志
|
|
95
104
|
- `options`: 可选配置
|
|
96
105
|
- `level?`: 日志级别(`'info' | 'warn' | 'error' | 'fatal'`),默认 `'info'`
|
|
97
106
|
- `stack?`: 堆栈信息
|
|
@@ -109,6 +118,12 @@ sdk.track('error', 'Failed to load resource', {
|
|
|
109
118
|
tags: { resource: 'image.png' },
|
|
110
119
|
});
|
|
111
120
|
|
|
121
|
+
// 记录带 traceId 的错误(用于关联多个日志)
|
|
122
|
+
sdk.track('error', 'API request failed', 'trace-xyz-789', {
|
|
123
|
+
level: 'error',
|
|
124
|
+
tags: { endpoint: '/api/users', statusCode: 500 },
|
|
125
|
+
});
|
|
126
|
+
|
|
112
127
|
// 记录页面浏览
|
|
113
128
|
sdk.track('pageview', 'User viewed product page', {
|
|
114
129
|
level: 'info',
|
|
@@ -116,6 +131,29 @@ sdk.track('pageview', 'User viewed product page', {
|
|
|
116
131
|
});
|
|
117
132
|
```
|
|
118
133
|
|
|
134
|
+
### 日志 ID 和追踪 ID
|
|
135
|
+
|
|
136
|
+
- **logId**: 每条日志自动生成的唯一标识符(UUID v4 格式),用于全局唯一定位日志
|
|
137
|
+
- **traceId**: 可选的追踪 ID,用于关联同一请求链路上的多个日志(例如:前端请求、后端处理、数据库查询等)
|
|
138
|
+
|
|
139
|
+
```typescript
|
|
140
|
+
// 在请求开始时生成 traceId
|
|
141
|
+
const traceId = `trace-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
142
|
+
|
|
143
|
+
// 在请求的不同阶段使用相同的 traceId
|
|
144
|
+
sdk.track('custom', 'Request started', traceId, {
|
|
145
|
+
level: 'info',
|
|
146
|
+
tags: { endpoint: '/api/checkout' },
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// ... 请求处理 ...
|
|
150
|
+
|
|
151
|
+
sdk.track('error', 'Request failed', traceId, {
|
|
152
|
+
level: 'error',
|
|
153
|
+
tags: { endpoint: '/api/checkout', error: 'Network timeout' },
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
119
157
|
### `identify(userId: string)`
|
|
120
158
|
|
|
121
159
|
设置用户 ID(用于后续日志关联)。
|
|
@@ -3,4 +3,4 @@ export { defaultTransport, TransportAdapters } from './transportAdapter';
|
|
|
3
3
|
export type { TransportAdapter, TransportOptions } from './transportAdapter';
|
|
4
4
|
export type { SDKOptions, LogEvent, LogEventType, LogEventLevel, Env } from './types';
|
|
5
5
|
export type { PlatformType, EnvironmentInfo } from './utils';
|
|
6
|
-
export { getEnvironmentInfo, parseBrowserInfo, isWeChatMiniProgram } from './utils';
|
|
6
|
+
export { getEnvironmentInfo, parseBrowserInfo, isWeChatMiniProgram, gzipCompress, isGzipSupported } from './utils';
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* @Author : 黄震 huangzhen@yfpharmacy.com
|
|
3
3
|
* @Date : 2025-11-21 14:25:26
|
|
4
4
|
* @LastEditors : 黄震 huangzhen@yfpharmacy.com
|
|
5
|
-
* @LastEditTime : 2025-12-04
|
|
5
|
+
* @LastEditTime : 2025-12-04 15:56:03
|
|
6
6
|
* @Description : 描述
|
|
7
7
|
* Copyright (c) 2025 by 益丰大药房连锁股份有限公司, All Rights Reserved.
|
|
8
8
|
*/
|
|
9
9
|
export { LoggerSDK } from "./loggerSDK";
|
|
10
10
|
export { defaultTransport, TransportAdapters } from "./transportAdapter";
|
|
11
|
-
export { getEnvironmentInfo, parseBrowserInfo, isWeChatMiniProgram } from "./utils";
|
|
11
|
+
export { getEnvironmentInfo, parseBrowserInfo, isWeChatMiniProgram, gzipCompress, isGzipSupported } from "./utils";
|
|
@@ -14,7 +14,7 @@ export declare class LoggerSDK {
|
|
|
14
14
|
/**
|
|
15
15
|
* 记录事件
|
|
16
16
|
*/
|
|
17
|
-
track(eventType: LogEventType, message: string, options?: {
|
|
17
|
+
track(eventType: LogEventType, message: string, traceId?: string, options?: {
|
|
18
18
|
level?: LogEventLevel;
|
|
19
19
|
stack?: string;
|
|
20
20
|
userId?: string;
|
|
@@ -11,7 +11,7 @@ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key i
|
|
|
11
11
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
12
12
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
13
13
|
import { defaultTransport } from "./transportAdapter";
|
|
14
|
-
import { isBrowser, isWeChatMiniProgram, now, getSessionId, getCurrentUrl, getEnvironmentInfo, parseBrowserInfo } from "./utils";
|
|
14
|
+
import { isBrowser, isWeChatMiniProgram, now, getSessionId, getCurrentUrl, getEnvironmentInfo, parseBrowserInfo, generateUUID } from "./utils";
|
|
15
15
|
export var LoggerSDK = /*#__PURE__*/function () {
|
|
16
16
|
function LoggerSDK(options) {
|
|
17
17
|
_classCallCheck(this, LoggerSDK);
|
|
@@ -26,7 +26,8 @@ export var LoggerSDK = /*#__PURE__*/function () {
|
|
|
26
26
|
env: options.env || 'dev',
|
|
27
27
|
debug: !!options.debug,
|
|
28
28
|
pixelParam: options.pixelParam || 'data',
|
|
29
|
-
maxPixelUrlLen: options.maxPixelUrlLen || 1900
|
|
29
|
+
maxPixelUrlLen: options.maxPixelUrlLen || 1900,
|
|
30
|
+
enableGzip: !!options.enableGzip
|
|
30
31
|
};
|
|
31
32
|
|
|
32
33
|
// 初始化时收集环境信息
|
|
@@ -88,7 +89,7 @@ export var LoggerSDK = /*#__PURE__*/function () {
|
|
|
88
89
|
}, {
|
|
89
90
|
key: "track",
|
|
90
91
|
value: (function () {
|
|
91
|
-
var _track = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(eventType, message, options) {
|
|
92
|
+
var _track = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(eventType, message, traceId, options) {
|
|
92
93
|
var logEvent;
|
|
93
94
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
94
95
|
while (1) switch (_context.prev = _context.next) {
|
|
@@ -103,6 +104,9 @@ export var LoggerSDK = /*#__PURE__*/function () {
|
|
|
103
104
|
|
|
104
105
|
// 构建标准化日志格式
|
|
105
106
|
logEvent = {
|
|
107
|
+
logId: "".concat(this.opts.appId).concat(generateUUID()).concat(now()),
|
|
108
|
+
// UUID
|
|
109
|
+
traceId: traceId,
|
|
106
110
|
eventType: eventType,
|
|
107
111
|
ts: now(),
|
|
108
112
|
appId: this.opts.appId || 'unknown',
|
|
@@ -134,7 +138,7 @@ export var LoggerSDK = /*#__PURE__*/function () {
|
|
|
134
138
|
}
|
|
135
139
|
}, _callee, this, [[5, 10]]);
|
|
136
140
|
}));
|
|
137
|
-
function track(_x, _x2, _x3) {
|
|
141
|
+
function track(_x, _x2, _x3, _x4) {
|
|
138
142
|
return _track.apply(this, arguments);
|
|
139
143
|
}
|
|
140
144
|
return track;
|
|
@@ -6,12 +6,12 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar
|
|
|
6
6
|
* @Author : 黄震 huangzhen@yfpharmacy.com
|
|
7
7
|
* @Date : 2025-11-21 14:35:48
|
|
8
8
|
* @LastEditors : 黄震 huangzhen@yfpharmacy.com
|
|
9
|
-
* @LastEditTime : 2025-12-04
|
|
9
|
+
* @LastEditTime : 2025-12-04 22:00:00
|
|
10
10
|
* @Description : 传输适配器 - Beacon、像素图和微信小程序方式
|
|
11
11
|
* Copyright (c) 2025 by 益丰大药房连锁股份有限公司, All Rights Reserved.
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
-
import { safeStringify, isBrowser, isWeChatMiniProgram, now } from "./utils";
|
|
14
|
+
import { safeStringify, isBrowser, isWeChatMiniProgram, now, gzipCompress } from "./utils";
|
|
15
15
|
|
|
16
16
|
/** 传输选项接口 */
|
|
17
17
|
|
|
@@ -40,22 +40,34 @@ export var beaconTransport = {
|
|
|
40
40
|
},
|
|
41
41
|
send: function send(payload, opts) {
|
|
42
42
|
return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
43
|
-
var body, endpoint, blob, success;
|
|
43
|
+
var body, endpoint, contentType, blob, success;
|
|
44
44
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
45
45
|
while (1) switch (_context.prev = _context.next) {
|
|
46
46
|
case 0:
|
|
47
47
|
body = typeof payload === 'string' ? payload : safeStringify(payload);
|
|
48
|
-
endpoint = getEndpoint(opts); //
|
|
48
|
+
endpoint = getEndpoint(opts); // 如果启用 gzip 压缩
|
|
49
|
+
contentType = 'application/json';
|
|
50
|
+
if (!(opts !== null && opts !== void 0 && opts.enableGzip)) {
|
|
51
|
+
_context.next = 8;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
_context.next = 6;
|
|
55
|
+
return gzipCompress(body);
|
|
56
|
+
case 6:
|
|
57
|
+
body = _context.sent;
|
|
58
|
+
contentType = 'application/json; charset=utf-8';
|
|
59
|
+
case 8:
|
|
60
|
+
// sendBeacon 使用 Blob 确保正确的 Content-Type
|
|
49
61
|
blob = new Blob([body], {
|
|
50
|
-
type:
|
|
62
|
+
type: contentType
|
|
51
63
|
});
|
|
52
64
|
success = navigator.sendBeacon(endpoint, blob);
|
|
53
65
|
if (success) {
|
|
54
|
-
_context.next =
|
|
66
|
+
_context.next = 12;
|
|
55
67
|
break;
|
|
56
68
|
}
|
|
57
69
|
throw new Error('sendBeacon failed (queue full or other error)');
|
|
58
|
-
case
|
|
70
|
+
case 12:
|
|
59
71
|
case "end":
|
|
60
72
|
return _context.stop();
|
|
61
73
|
}
|
|
@@ -79,13 +91,25 @@ export var wechatTransport = {
|
|
|
79
91
|
},
|
|
80
92
|
send: function send(payload, opts) {
|
|
81
93
|
return _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2() {
|
|
82
|
-
var body, endpoint, timeout;
|
|
94
|
+
var body, endpoint, timeout, contentType;
|
|
83
95
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
84
96
|
while (1) switch (_context2.prev = _context2.next) {
|
|
85
97
|
case 0:
|
|
86
98
|
body = typeof payload === 'string' ? payload : safeStringify(payload);
|
|
87
99
|
endpoint = getEndpoint(opts);
|
|
88
100
|
timeout = 10000; // 10秒超时
|
|
101
|
+
// 如果启用 gzip 压缩
|
|
102
|
+
contentType = 'application/json';
|
|
103
|
+
if (!(opts !== null && opts !== void 0 && opts.enableGzip)) {
|
|
104
|
+
_context2.next = 9;
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
_context2.next = 7;
|
|
108
|
+
return gzipCompress(body);
|
|
109
|
+
case 7:
|
|
110
|
+
body = _context2.sent;
|
|
111
|
+
contentType = 'application/json; charset=utf-8';
|
|
112
|
+
case 9:
|
|
89
113
|
return _context2.abrupt("return", new Promise(function (resolve, reject) {
|
|
90
114
|
var timeoutId = null;
|
|
91
115
|
var settled = false;
|
|
@@ -104,7 +128,7 @@ export var wechatTransport = {
|
|
|
104
128
|
method: 'POST',
|
|
105
129
|
data: body,
|
|
106
130
|
header: {
|
|
107
|
-
'Content-Type':
|
|
131
|
+
'Content-Type': contentType
|
|
108
132
|
},
|
|
109
133
|
success: function success(res) {
|
|
110
134
|
if (timeoutId) clearTimeout(timeoutId);
|
|
@@ -126,7 +150,7 @@ export var wechatTransport = {
|
|
|
126
150
|
}
|
|
127
151
|
});
|
|
128
152
|
}));
|
|
129
|
-
case
|
|
153
|
+
case 10:
|
|
130
154
|
case "end":
|
|
131
155
|
return _context2.stop();
|
|
132
156
|
}
|
|
@@ -9,7 +9,7 @@ export interface SDKOptions {
|
|
|
9
9
|
/** 上报端点 URL */
|
|
10
10
|
endpoint: string;
|
|
11
11
|
/** 应用 ID */
|
|
12
|
-
appId
|
|
12
|
+
appId: string;
|
|
13
13
|
/** 环境标识 */
|
|
14
14
|
env?: Env;
|
|
15
15
|
/** 是否开启调试模式 */
|
|
@@ -18,9 +18,13 @@ export interface SDKOptions {
|
|
|
18
18
|
pixelParam?: string;
|
|
19
19
|
/** 像素上报 URL 最大长度,默认 1900 */
|
|
20
20
|
maxPixelUrlLen?: number;
|
|
21
|
+
/** 是否启用 gzip 压缩,默认 false */
|
|
22
|
+
enableGzip?: boolean;
|
|
21
23
|
}
|
|
22
24
|
/** 标准化日志上报格式 */
|
|
23
25
|
export interface LogEvent {
|
|
26
|
+
logId: string;
|
|
27
|
+
traceId?: string;
|
|
24
28
|
/** 事件类型:error/crash/pageview/custom */
|
|
25
29
|
eventType: LogEventType;
|
|
26
30
|
/** 毫秒时间戳 */
|
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
export declare const now: () => number;
|
|
2
|
+
/**
|
|
3
|
+
* 生成 UUID v4
|
|
4
|
+
* 符合 RFC 4122 标准
|
|
5
|
+
* 格式: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
6
|
+
* 其中 x 是 0-f 的十六进制数字,y 是 8/9/a/b 之一
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateUUID(): string;
|
|
2
9
|
export declare function isBrowser(): boolean;
|
|
3
10
|
export declare function isWeChatMiniProgram(): boolean;
|
|
4
11
|
export declare function safeStringify(obj: any): string;
|
|
12
|
+
/**
|
|
13
|
+
* gzip 压缩字符串
|
|
14
|
+
* @param data - 需要压缩的字符串
|
|
15
|
+
* @returns 压缩后的 Base64 字符串
|
|
16
|
+
*/
|
|
17
|
+
export declare function gzipCompress(data: string): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* 检查是否支持 gzip 压缩
|
|
20
|
+
*/
|
|
21
|
+
export declare function isGzipSupported(): boolean;
|
|
5
22
|
export declare function getSessionId(): string;
|
|
6
23
|
export declare function getCurrentUrl(): string;
|
|
7
24
|
/** 平台类型 */
|