@mtn-ui-z/monitor 0.0.1

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 ADDED
@@ -0,0 +1,344 @@
1
+ # @mtn-ui-z/monitor
2
+
3
+ 前端监控 SDK,用于监控前端错误、性能、PV、API 请求、用户行为等数据。
4
+
5
+ ## 功能特性
6
+
7
+ - **错误监控** - JS 错误、Promise 未捕获异常、资源加载失败、Vue 组件错误
8
+ - **性能监控** - FP/FCP/LCP/FID/CLS/TTI/TTFB/DNS/TCP 等关键性能指标
9
+ - **PV 监控** - 自动监听路由变化,支持 SPA 应用
10
+ - **API 监控** - 拦截 fetch/XMLHttpRequest,记录请求耗时、状态码、接口报错
11
+ - **用户行为监控** - 点击事件、滚动行为、页面可见性变化
12
+ - **自定义事件** - 支持手动埋点上报自定义事件
13
+ - **长任务监控** - Long Task、内存使用情况
14
+ - **采样控制** - 支持采样率配置
15
+ - **多种上报方式** - 支持 sendBeacon、fetch、自定义上报函数
16
+
17
+ ## 安装
18
+
19
+ ```bash
20
+ pnpm add @mtn-ui-z/monitor
21
+ ```
22
+
23
+ ## 快速开始
24
+
25
+ ### Vue 插件方式
26
+
27
+ ```ts
28
+ import { createApp } from 'vue'
29
+ import { MtnMonitor } from '@mtn-ui-z/monitor'
30
+ import App from './App.vue'
31
+
32
+ const app = createApp(App)
33
+
34
+ app.use(MtnMonitor, {
35
+ reportUrl: 'https://your-api.com/monitor',
36
+ appId: 'my-app',
37
+ env: 'production',
38
+ sampleRate: 1,
39
+ })
40
+
41
+ app.mount('#app')
42
+ ```
43
+
44
+ ### 手动初始化
45
+
46
+ ```ts
47
+ import { monitor } from '@mtn-ui-z/monitor'
48
+
49
+ monitor.init({
50
+ reportUrl: 'https://your-api.com/monitor',
51
+ appId: 'my-app',
52
+ env: 'production',
53
+ })
54
+
55
+ // 手动上报错误
56
+ try {
57
+ // your code
58
+ } catch (error) {
59
+ monitor.reportError(error as Error)
60
+ }
61
+ ```
62
+
63
+ ### Vue 组件中使用
64
+
65
+ ```ts
66
+ import { getCurrentInstance } from 'vue'
67
+
68
+ export default {
69
+ setup() {
70
+ const { proxy } = getCurrentInstance()
71
+
72
+ // 使用 $monitor
73
+ proxy.$monitor.reportError(new Error('xxx'))
74
+
75
+ // 或使用 provide/inject
76
+ const monitor = inject('monitor')
77
+ }
78
+ }
79
+ ```
80
+
81
+ ## 配置选项
82
+
83
+ | 属性 | 类型 | 默认值 | 说明 |
84
+ |------|------|--------|------|
85
+ | `reportUrl` | `string` | - | 上报地址 |
86
+ | `appId` | `string` | - | 应用标识 |
87
+ | `env` | `'development' \| 'production' \| 'test'` | `'production'` | 环境 |
88
+ | `errorEnabled` | `boolean` | `true` | 是否启用错误监控 |
89
+ | `performanceEnabled` | `boolean` | `true` | 是否启用性能监控 |
90
+ | `pvEnabled` | `boolean` | `true` | 是否启用 PV 监控 |
91
+ | `apiEnabled` | `boolean` | `true` | 是否启用 API 监控 |
92
+ | `behaviorEnabled` | `boolean` | `false` | 是否启用用户行为监控 |
93
+ | `longTaskEnabled` | `boolean` | `false` | 是否启用长任务监控 |
94
+ | `sampleRate` | `number` | `1` | 采样率 (0-1) |
95
+ | `report` | `(data: MonitorData) => void` | - | 自定义上报函数 |
96
+
97
+ ## 上报数据结构
98
+
99
+ ### 错误数据 (ErrorData)
100
+
101
+ ```json
102
+ {
103
+ "type": "error",
104
+ "errorType": "js",
105
+ "message": "Error message",
106
+ "stack": "Error stack...",
107
+ "url": "https://example.com/page",
108
+ "line": 10,
109
+ "column": 5,
110
+ "userId": "user123",
111
+ "timestamp": 1699999999999,
112
+ "appId": "my-app",
113
+ "env": "production"
114
+ }
115
+ ```
116
+
117
+ ### 性能数据 (PerformanceData)
118
+
119
+ ```json
120
+ {
121
+ "type": "performance",
122
+ "metric": "fcp",
123
+ "value": 1200,
124
+ "url": "https://example.com/page",
125
+ "timestamp": 1699999999999,
126
+ "appId": "my-app",
127
+ "env": "production"
128
+ }
129
+ ```
130
+
131
+ ### PV 数据 (PvData)
132
+
133
+ ```json
134
+ {
135
+ "type": "pv",
136
+ "url": "https://example.com/page",
137
+ "referrer": "https://example.com/other",
138
+ "userId": "user123",
139
+ "timestamp": 1699999999999,
140
+ "appId": "my-app",
141
+ "env": "production"
142
+ }
143
+ ```
144
+
145
+ ### API 数据 (ApiData)
146
+
147
+ ```json
148
+ {
149
+ "type": "api",
150
+ "url": "https://example.com/api/user",
151
+ "method": "GET",
152
+ "status": 200,
153
+ "duration": 120,
154
+ "success": true,
155
+ "timestamp": 1699999999999,
156
+ "appId": "my-app",
157
+ "env": "production"
158
+ }
159
+ ```
160
+
161
+ ### 用户行为数据 (BehaviorData)
162
+
163
+ ```json
164
+ {
165
+ "type": "behavior",
166
+ "behaviorType": "click",
167
+ "element": "button",
168
+ "text": "提交",
169
+ "path": "div > form > button",
170
+ "x": 100,
171
+ "y": 50,
172
+ "timestamp": 1699999999999,
173
+ "appId": "my-app",
174
+ "env": "production"
175
+ }
176
+ ```
177
+
178
+ ### 自定义事件数据 (CustomData)
179
+
180
+ ```json
181
+ {
182
+ "type": "custom",
183
+ "eventName": "button_click",
184
+ "data": { "buttonId": "submit-btn" },
185
+ "url": "https://example.com/page",
186
+ "timestamp": 1699999999999,
187
+ "appId": "my-app",
188
+ "env": "production"
189
+ }
190
+ ```
191
+
192
+ ### 长任务数据 (LongTaskData)
193
+
194
+ ```json
195
+ {
196
+ "type": "longtask",
197
+ "taskType": "longTask",
198
+ "duration": 120,
199
+ "attribution": "script",
200
+ "url": "https://example.com/page",
201
+ "timestamp": 1699999999999,
202
+ "appId": "my-app",
203
+ "env": "production"
204
+ }
205
+ ```
206
+
207
+ ## API
208
+
209
+ ### monitor.init(options)
210
+
211
+ 初始化监控 SDK。
212
+
213
+ ### monitor.reportError(error, errorType?)
214
+
215
+ 手动上报错误。
216
+
217
+ - `error` - Error 对象
218
+ - `errorType` - 错误类型 `'js' | 'resource' | 'promise' | 'vue'`
219
+
220
+ ### monitor.reportPerformance(metric, value)
221
+
222
+ 手动上报性能数据。
223
+
224
+ - `metric` - 指标类型 `'page' | 'resource' | 'fcp' | 'fp' | 'lcp' | 'fid' | 'cls' | 'tti' | 'ttfb' | 'dns' | 'tcp' | 'download'`
225
+ - `value` - 指标值 (ms)
226
+
227
+ ### monitor.reportCustomEvent(eventName, eventData?)
228
+
229
+ 手动上报自定义事件。
230
+
231
+ - `eventName` - 事件名称
232
+ - `eventData` - 事件数据对象
233
+
234
+ ### monitor.reportPv()
235
+
236
+ 手动上报页面访问。
237
+
238
+ ### monitor.setUserId(userId)
239
+
240
+ 设置用户 ID。
241
+
242
+ ### monitor.destroy()
243
+
244
+ 销毁监控实例。
245
+
246
+ ## 配合后端使用
247
+
248
+ 监控 SDK 上报的数据为 JSON 格式,后端只需提供一个 POST 接口即可接收:
249
+
250
+ ```ts
251
+ // 示例: Express 接口
252
+ app.post('/api/monitor', (req, res) => {
253
+ const data = req.body
254
+ console.log('[Monitor]', data.type, data)
255
+
256
+ // 存储到数据库或发送到日志服务
257
+ saveToDatabase(data)
258
+
259
+ res.json({ success: true })
260
+ })
261
+ ```
262
+
263
+ ## Vue 错误捕获
264
+
265
+ 在 Vue 3 中使用 app.config.errorHandler 配合监控:
266
+
267
+ ```ts
268
+ import { createApp } from 'vue'
269
+ import { MtnMonitor, monitor } from '@mtn-ui-z/monitor'
270
+ import App from './App.vue'
271
+
272
+ const app = createApp(App)
273
+
274
+ app.use(MtnMonitor, {
275
+ reportUrl: 'https://your-api.com/monitor',
276
+ })
277
+
278
+ // Vue 全局错误处理(可选,插件已自动处理)
279
+ app.config.errorHandler = (err, instance, info) => {
280
+ console.error('Vue Error:', err, info)
281
+ // 错误已通过 ErrorMonitor 自动上报
282
+ }
283
+
284
+ app.mount('#app')
285
+ ```
286
+
287
+ ## 用户行为监控
288
+
289
+ 启用用户行为监控后,会自动采集以下数据:
290
+
291
+ ### 点击事件
292
+
293
+ ```json
294
+ {
295
+ "type": "behavior",
296
+ "behaviorType": "click",
297
+ "element": "button",
298
+ "text": "提交订单",
299
+ "path": "div > form > button.submit-btn",
300
+ "x": 200,
301
+ "y": 100
302
+ }
303
+ ```
304
+
305
+ 可通过 `data-monitor-id` 或 `data-monitor-label` 属性添加自定义标识:
306
+
307
+ ```html
308
+ <button data-monitor-id="submit-btn" data-monitor-label="提交订单">
309
+ 提交
310
+ </button>
311
+ ```
312
+
313
+ ### 滚动事件
314
+
315
+ ```json
316
+ {
317
+ "type": "behavior",
318
+ "behaviorType": "scroll",
319
+ "scrollTop": 500,
320
+ "scrollPercent": 50
321
+ }
322
+ ```
323
+
324
+ ### 页面可见性
325
+
326
+ ```json
327
+ {
328
+ "type": "behavior",
329
+ "behaviorType": "pageHide"
330
+ }
331
+ ```
332
+
333
+ ## 浏览器兼容性
334
+
335
+ - Chrome 80+
336
+ - Firefox 75+
337
+ - Safari 14+
338
+ - Edge 80+
339
+
340
+ 需要浏览器支持以下 API:
341
+ - Performance Observer
342
+ - Promise.prototype.finally
343
+ - fetch / navigator.sendBeacon
344
+ - Long Task API (可选,内存监控需要)