UNPKG

hc-web-log-mon

Version:

基于 JS 跨平台插件,为前端项目提供【 行为、性能、异常、请求、资源、路由、曝光、录屏 】监控手段

135 lines (124 loc) 4.22 kB
import { sendData } from './sendData' import { AnyFun } from '../types' import { debounce, throttle, groupArray } from '../utils' const SETTIMEA = 2000 const SETTIMEB = 20000 const MAXLENGTHA = 5 const GROUPARRAYKEY = ['errMessage', 'eventId', 'requestUrl'] /** * 判断是否为批量错误 * 判断流程: * 1. 先把所有错误都放入 a栈 * 2. 每次发生错误后防抖 2s查 a栈是否有批量错误(批量错误: errMessage、errType相同且发生个数大于等于5) * 1. 如果为批量错误则合并这些错误并加入[时间区间参数、发生个数参数]后放入 b栈 * 2. 不为批量错误则发送这些错误 * 3. 每次推入错误到b栈后延迟 20s查 b栈并发送这些错误 * 4. 在这个过程中,如果用户关闭了网页,会统一把 a栈、b栈内的数据发送 * 5. 在这个过程中,a栈每满50个错误也会强制触发a栈和b栈的错误处理(处理结果为直接发送批量错误) */ class BatchError { cacheErrorA: any[] cacheErrorB: any[] throttleProxyAddCacheErrorA: AnyFun throttleProxyAddCacheErrorB: AnyFun constructor() { this.cacheErrorA = [] this.cacheErrorB = [] this.throttleProxyAddCacheErrorA = debounce( this.proxyAddCacheErrorA, SETTIMEA ) this.throttleProxyAddCacheErrorB = throttle( this.proxyAddCacheErrorB, SETTIMEB ) } proxyAddCacheErrorA() { let len = this.cacheErrorA.length if (!len) return const arr = groupArray(this.cacheErrorA, ...GROUPARRAYKEY) const arrA = arr.filter(item => item.length < MAXLENGTHA) const arrB = arr.filter(item => item.length >= MAXLENGTHA) if (arrA.length) { sendData.emit(arrA.flat(Infinity)) } if (arrB.length) { const arrBsum: any[] = [] arrB.forEach(item => { const sumItem = item[0] sumItem.batchError = true sumItem.batchErrorLength = item.length sumItem.batchErrorLastHappenTime = item[item.length - 1].triggerTime arrBsum.push(sumItem) }) this.cacheErrorB.push(...arrBsum) this.throttleProxyAddCacheErrorB() } while (len--) { this.cacheErrorA.shift() } } proxyAddCacheErrorB() { let len = this.cacheErrorB.length if (!len) return const arr = groupArray(this.cacheErrorB, ...GROUPARRAYKEY) while (len--) { this.cacheErrorB.shift() } // 将区间报错合并 const emitList: any[] = [] arr.forEach((itemList: any[]) => { const sumItem = itemList[0] if (itemList.length > 1) { sumItem.batchErrorLength = itemList.reduce( (p, item) => (p += item.batchErrorLength), 0 ) sumItem.batchErrorLastHappenTime = itemList[itemList.length - 1].triggerTime } emitList.push(sumItem) }) sendData.emit(emitList) } /** * 获取所有的错误 * 用户突然关闭页面时调用此方法集成错误 */ sendAllCacheError() { const errInfoList = this.cacheErrorA.concat(this.cacheErrorB) const arr = groupArray(errInfoList, ...GROUPARRAYKEY) const arrA = arr.filter(item => item.length < MAXLENGTHA) const arrB = arr.filter(item => item.length >= MAXLENGTHA) if (arrA.length) { sendData.emit(arrA.flat(Infinity), true) } if (arrB.length) { const arrBsum: any[] = [] arrB.forEach(item => { const sumItem = item[0] sumItem.batchError = true sumItem.batchErrorLength = item.length sumItem.batchErrorLastHappenTime = item[item.length - 1].triggerTime arrBsum.push(sumItem) }) sendData.emit(arrBsum, true) } } pushCacheErrorA(errorInfo: any) { this.cacheErrorA.push(errorInfo) this.throttleProxyAddCacheErrorA() // 每 50 个触发一次强制发送事件 if (this.cacheErrorA.length >= 50) { this.proxyAddCacheErrorA() this.proxyAddCacheErrorB() } } } export let batchError: BatchError /** * 初始化错误缓存 */ export function initBatchError() { batchError = new BatchError() }