@error-monitor/sdk
Version:
Monitor SDK - 多平台前端监控SDK解决方案,支持自动环境检测,Web、Taro小程序一站式监控方案
3 lines (2 loc) • 18.7 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).MonitorWebSDK={})}(this,function(e){"use strict";function t(){return Date.now().toString(36)+Math.random().toString(36).substr(2)}function r(){return Date.now()}function i(){return`session_${Date.now().toString(36)}_${Math.random().toString(36).substr(2,9)}`}function o(e){if(!e)return null;if(e instanceof Error)return{name:e.name,message:e.message,stack:e.stack,...Object.getOwnPropertyNames(e).reduce((t,r)=>(["name","message","stack"].includes(r)||(t[r]=e[r]),t),{})};if("string"==typeof e)return{message:e};try{return JSON.parse(JSON.stringify(e))}catch(t){return{message:String(e)}}}function n(e){if(e&&e.stack)return e.stack.split("\n").filter(e=>e.trim()).slice(0,20).join("\n")}function s(){return"undefined"!=typeof globalThis&&void 0!==globalThis.location&&void 0!==globalThis.document?{url:globalThis.location.href,title:globalThis.document.title,referrer:globalThis.document.referrer}:{url:"",title:"",referrer:""}}function a(){return"undefined"!=typeof globalThis&&void 0!==globalThis.navigator?globalThis.navigator.userAgent:""}class c{constructor(e,t){this.dataQueue=[],this.isInitialized=!1,this.isEnabled=!0,this.listeners=new Map,this.config=this.mergeConfig(e),this.platformAdapter=t,this.sessionId=i()}mergeConfig(e){return this.deepMerge({enableInDev:!1,sampleRate:1,error:{enabled:!0,maxErrors:100,filters:[],sampleRate:1},performance:{enabled:!0,maxPerformance:100,enableResourceTiming:!0,enableUserTiming:!0},behavior:{enabled:!0,maxBehaviors:200,autoTrackClick:!0,autoTrackPageView:!0},report:{interval:1e4,maxQueueSize:500,batchSize:20,timeout:5e3,maxRetries:3,retryDelay:2e3,enableOfflineCache:!0}},e)}deepMerge(e,t){const r={...e};for(const i in t)t.hasOwnProperty(i)&&("object"!=typeof t[i]||null===t[i]||Array.isArray(t[i])?r[i]=t[i]:r[i]=this.deepMerge(e[i]||{},t[i]));return r}async init(){if(!this.isInitialized)if(this.shouldEnable())try{await this.platformAdapter.init(this.config),this.initErrorMonitor(),this.initPerformanceMonitor(),this.initBehaviorMonitor(),this.startReportTimer(),this.isInitialized=!0,this.emit("init",this.getStatus())}catch(e){throw this.emit("error",e),e}else this.isEnabled=!1}shouldEnable(){return!(this.isDevelopment()&&!this.config.enableInDev)&&!(Math.random()>(this.config.sampleRate||1))}isDevelopment(){return("undefined"==typeof process||!process.env)&&("undefined"!=typeof globalThis&&void 0!==globalThis.location&&("localhost"===globalThis.location.hostname||"127.0.0.1"===globalThis.location.hostname))}initErrorMonitor(){var e;(null===(e=this.config.error)||void 0===e?void 0:e.enabled)&&this.platformAdapter.errorCapture.initErrorListeners(e=>{this.addToQueue(e),this.emit("error",e)})}initPerformanceMonitor(){var e;(null===(e=this.config.performance)||void 0===e?void 0:e.enabled)&&this.platformAdapter.performance.initPerformanceMonitor(e=>{this.addToQueue(e),this.emit("performance",e)})}initBehaviorMonitor(){var e;(null===(e=this.config.behavior)||void 0===e?void 0:e.enabled)&&this.platformAdapter.behavior.initBehaviorMonitor(e=>{this.addToQueue(e),this.emit("behavior",e)})}addToQueue(e){var t;if(!this.isEnabled)return;e.projectId=this.config.projectId,e.userId=this.config.userId,e.sessionId=this.sessionId,e.platform=this.platformAdapter.platformInfo.platform,this.config.projectVersion&&(e.projectVersion=this.config.projectVersion),this.config.tags&&(e.tags={...e.tags,...this.config.tags});const r=(null===(t=this.config.report)||void 0===t?void 0:t.maxQueueSize)||500;this.dataQueue.length>=r&&this.dataQueue.shift(),this.dataQueue.push(e),this.emit("dataAdded",e)}startReportTimer(){var e;const t=(null===(e=this.config.report)||void 0===e?void 0:e.interval)||1e4;this.reportTimer=setInterval(()=>{this.flush()},t)}async flush(){var e;if(!this.isEnabled||0===this.dataQueue.length)return;const t=(null===(e=this.config.report)||void 0===e?void 0:e.batchSize)||20,r=this.dataQueue.splice(0,t);try{await this.sendData(r),this.emit("dataReported",r)}catch(e){throw this.dataQueue.unshift(...r),this.emit("reportError",e),e}}async sendData(e){var t,r;const i=`${this.config.serverUrl}/api/monitor/report`,o={timeout:(null===(t=this.config.report)||void 0===t?void 0:t.timeout)||5e3,retries:(null===(r=this.config.report)||void 0===r?void 0:r.maxRetries)||3,headers:this.config.apiKey?{"X-API-Key":this.config.apiKey}:void 0};await this.platformAdapter.network.sendData(i,e,o)}captureError(e,t){var r;if(!(null===(r=this.config.error)||void 0===r?void 0:r.enabled))return;const i=this.platformAdapter.errorCapture.captureError(e,t);this.addToQueue(i)}recordPerformance(e,t){var r;if(!(null===(r=this.config.performance)||void 0===r?void 0:r.enabled))return;const i=this.platformAdapter.performance.recordPerformance(e,t);this.addToQueue(i)}recordBehavior(e,t){var r;if(!(null===(r=this.config.behavior)||void 0===r?void 0:r.enabled))return;const i=this.platformAdapter.behavior.recordBehavior(e,t);this.addToQueue(i)}getStatus(){var e,t,r,i,o;const n=this.dataQueue.filter(e=>"type"in e&&e.type).length,s=this.dataQueue.filter(e=>"metrics"in e).length,a=this.dataQueue.filter(e=>"event"in e).length;return{initialized:this.isInitialized,enabled:this.isEnabled,queue:{size:this.dataQueue.length,maxSize:(null===(e=this.config.report)||void 0===e?void 0:e.maxQueueSize)||500,isFull:this.dataQueue.length>=((null===(t=this.config.report)||void 0===t?void 0:t.maxQueueSize)||500),errorCount:n,performanceCount:s,behaviorCount:a},lastReportTime:Date.now(),errorMonitor:!!(null===(r=this.config.error)||void 0===r?void 0:r.enabled),performanceMonitor:!!(null===(i=this.config.performance)||void 0===i?void 0:i.enabled),behaviorMonitor:!!(null===(o=this.config.behavior)||void 0===o?void 0:o.enabled)}}destroy(){this.isInitialized&&(this.reportTimer&&(clearInterval(this.reportTimer),this.reportTimer=void 0),this.flush().catch(e=>{}),this.platformAdapter.destroy(),this.dataQueue=[],this.listeners.clear(),this.isInitialized=!1,this.isEnabled=!1,this.emit("destroy"))}on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){if(this.listeners.has(e))if(t){const r=this.listeners.get(e),i=r.indexOf(t);i>-1&&r.splice(i,1)}else this.listeners.delete(e)}emit(e,...t){if(!this.listeners.has(e))return!1;return this.listeners.get(e).forEach(e=>{try{e(...t)}catch(e){}}),!0}once(e,t){const r=(...i)=>{this.off(e,r),t(...i)};this.on(e,r)}}var l,d,u;e.ErrorType=void 0,(l=e.ErrorType||(e.ErrorType={})).JS_ERROR="js_error",l.PROMISE_ERROR="promise_error",l.RESOURCE_ERROR="resource_error",l.HTTP_ERROR="http_error",l.CUSTOM_ERROR="custom_error",l.FRAMEWORK_ERROR="framework_error",e.PerformanceType=void 0,(d=e.PerformanceType||(e.PerformanceType={})).PAGE_LOAD="page_load",d.HTTP_REQUEST="http_request",d.RESOURCE_LOAD="resource_load",d.USER_INTERACTION="user_interaction",d.CUSTOM_METRIC="custom_metric",e.BehaviorType=void 0,(u=e.BehaviorType||(e.BehaviorType={})).PAGE_VIEW="page_view",u.CLICK="click",u.SCROLL="scroll",u.FORM_SUBMIT="form_submit",u.ROUTE_CHANGE="route_change",u.CUSTOM="custom";class h{constructor(){this.listeners=[]}initErrorListeners(e){this.setupGlobalErrorHandler(e),this.setupUnhandledRejectionHandler(e),this.setupResourceErrorHandler(e)}setupGlobalErrorHandler(c){const l=l=>{const d={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.ErrorType.JS_ERROR,message:l.message,filename:l.filename,lineno:l.lineno,colno:l.colno,stack:l.error?n(l.error):void 0,error:o(l.error)};c(d)};window.addEventListener("error",l),this.listeners.push(()=>window.removeEventListener("error",l))}setupUnhandledRejectionHandler(c){const l=l=>{const d=l.reason,u={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.ErrorType.PROMISE_ERROR,message:d instanceof Error?d.message:String(d),stack:d instanceof Error?n(d):void 0,error:o(d)};c(u)};window.addEventListener("unhandledrejection",l),this.listeners.push(()=>window.removeEventListener("unhandledrejection",l))}setupResourceErrorHandler(o){const n=n=>{var c,l;const d=n.target;if(!(d&&d!==window&&d instanceof HTMLElement))return;const u=null===(c=d.tagName)||void 0===c?void 0:c.toLowerCase(),h=d.src||d.href;if(!h)return;const p={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.ErrorType.RESOURCE_ERROR,message:`Failed to load ${u}: ${h}`,filename:h,error:{tagName:u,resourceUrl:h,outerHTML:null===(l=d.outerHTML)||void 0===l?void 0:l.substring(0,200)}};o(p)};window.addEventListener("error",n,!0),this.listeners.push(()=>window.removeEventListener("error",n,!0))}destroyErrorListeners(){this.listeners.forEach(e=>e()),this.listeners=[]}captureError(c,l){return{id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.ErrorType.CUSTOM_ERROR,message:c instanceof Error?c.message:String(c),stack:c instanceof Error?n(c):void 0,error:o(c),...l}}captureHttpError(o){return{id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.ErrorType.HTTP_ERROR,message:`HTTP ${o.status} ${o.statusText}: ${o.method} ${o.url}`,error:{url:o.url,method:o.method,status:o.status,statusText:o.statusText,duration:o.duration}}}}class p{initPerformanceMonitor(e){this.onPerformance=e,this.setupNavigationTiming(),this.setupResourceTiming(),this.setupUserTiming()}setupNavigationTiming(){"undefined"!=typeof performance&&("complete"===document.readyState?this.collectNavigationTiming():window.addEventListener("load",()=>{setTimeout(()=>this.collectNavigationTiming(),0)}))}collectNavigationTiming(){var o;if(!performance.timing)return;const n=performance.timing,c={dnsTime:n.domainLookupEnd-n.domainLookupStart,tcpTime:n.connectEnd-n.connectStart,requestTime:n.responseStart-n.requestStart,responseTime:n.responseEnd-n.responseStart,domParseTime:n.domContentLoadedEventStart-n.domLoading,resourceLoadTime:n.loadEventStart-n.domContentLoadedEventStart,totalTime:n.loadEventEnd-n.navigationStart},l={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.PerformanceType.PAGE_LOAD,metrics:c};null===(o=this.onPerformance)||void 0===o||o.call(this,l)}setupResourceTiming(){performance.getEntriesByType&&(this.observer=new PerformanceObserver(e=>{for(const t of e.getEntries())"resource"===t.entryType&&this.handleResourceEntry(t)}),this.observer.observe({entryTypes:["resource"]}))}handleResourceEntry(o){var n;const c={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.PerformanceType.RESOURCE_LOAD,metrics:{duration:o.duration,size:o.transferSize||0,dnsTime:o.domainLookupEnd-o.domainLookupStart,tcpTime:o.connectEnd-o.connectStart,requestTime:o.responseStart-o.requestStart,responseTime:o.responseEnd-o.responseStart},resource:{name:o.name,size:o.transferSize||0,duration:o.duration,type:this.getResourceType(o.name)}};null===(n=this.onPerformance)||void 0===n||n.call(this,c)}getResourceType(e){var t;const r=null===(t=e.split(".").pop())||void 0===t?void 0:t.toLowerCase();return r?["js","jsx","ts","tsx"].includes(r)?"script":["css","scss","sass","less"].includes(r)?"stylesheet":["png","jpg","jpeg","gif","svg","webp"].includes(r)?"image":["woff","woff2","ttf","otf","eot"].includes(r)?"font":"other":"other"}setupUserTiming(){performance.getEntriesByType&&(this.observer=new PerformanceObserver(e=>{for(const t of e.getEntries())"measure"===t.entryType&&this.handleMeasureEntry(t)}),this.observer.observe({entryTypes:["measure"]}))}handleMeasureEntry(o){var n;const c={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.PerformanceType.USER_INTERACTION,metrics:{duration:o.duration,startTime:o.startTime}};null===(n=this.onPerformance)||void 0===n||n.call(this,c)}destroyPerformanceMonitor(){this.observer&&(this.observer.disconnect(),this.observer=void 0)}recordPerformance(o,n){return{id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.PerformanceType.CUSTOM_METRIC,metrics:n}}getPagePerformance(){if(!performance.timing)return{};const e=performance.timing;return{dnsTime:e.domainLookupEnd-e.domainLookupStart,tcpTime:e.connectEnd-e.connectStart,requestTime:e.responseStart-e.requestStart,responseTime:e.responseEnd-e.responseStart,domParseTime:e.domContentLoadedEventStart-e.domLoading,totalTime:e.loadEventEnd-e.navigationStart}}}class m{constructor(){this.listeners=[]}initBehaviorMonitor(e){this.onBehavior=e,this.setupClickTracking(),this.setupPageViewTracking(),this.setupScrollTracking()}setupClickTracking(){const o=o=>{var n,c;const l=o.target,d={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.BehaviorType.CLICK,event:"click",target:this.getElementSelector(l),xpath:this.getElementXPath(l),data:{x:o.clientX,y:o.clientY,tagName:l.tagName,className:l.className,id:l.id,text:null===(n=l.textContent)||void 0===n?void 0:n.substring(0,100)}};null===(c=this.onBehavior)||void 0===c||c.call(this,d)};document.addEventListener("click",o,!0),this.listeners.push(()=>document.removeEventListener("click",o,!0))}setupPageViewTracking(){this.recordPageView();const e=history.pushState,t=history.replaceState;history.pushState=(...t)=>{e.apply(history,t),setTimeout(()=>this.recordPageView(),0)},history.replaceState=(...e)=>{t.apply(history,e),setTimeout(()=>this.recordPageView(),0)};const r=()=>{setTimeout(()=>this.recordPageView(),0)};window.addEventListener("popstate",r),this.listeners.push(()=>{window.removeEventListener("popstate",r),history.pushState=e,history.replaceState=t})}recordPageView(){var o;const n=s(),c={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:n.url,userAgent:a(),platform:"web",type:e.BehaviorType.PAGE_VIEW,event:"page_view",data:{title:n.title,referrer:n.referrer}};null===(o=this.onBehavior)||void 0===o||o.call(this,c)}setupScrollTracking(){let o=0;const n=()=>{var n;const c=Date.now();if(c-o<1e3)return;o=c;const l={id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.BehaviorType.SCROLL,event:"scroll",data:{scrollTop:window.pageYOffset||document.documentElement.scrollTop,scrollLeft:window.pageXOffset||document.documentElement.scrollLeft,scrollHeight:document.documentElement.scrollHeight,clientHeight:document.documentElement.clientHeight}};null===(n=this.onBehavior)||void 0===n||n.call(this,l)};window.addEventListener("scroll",n,{passive:!0}),this.listeners.push(()=>window.removeEventListener("scroll",n))}getElementSelector(e){if(e.id)return`#${e.id}`;if(e.className){const t=e.className.split(" ").filter(e=>e).join(".");if(t)return`${e.tagName.toLowerCase()}.${t}`}return e.tagName.toLowerCase()}getElementXPath(e){if(e.id)return`//*[@id="${e.id}"]`;const t=[];let r=e;for(;r&&r.nodeType===Node.ELEMENT_NODE;){let e=1,i=r.previousSibling;for(;i;)i.nodeType===Node.ELEMENT_NODE&&i.nodeName===r.nodeName&&e++,i=i.previousSibling;t.unshift(`${r.nodeName.toLowerCase()}[${e}]`),r=r.parentElement}return"/"+t.join("/")}destroyBehaviorMonitor(){this.listeners.forEach(e=>e()),this.listeners=[]}recordBehavior(o,n){return{id:t(),timestamp:r(),projectId:"",sessionId:i(),url:s().url,userAgent:a(),platform:"web",type:e.BehaviorType.CUSTOM,event:o,data:n}}}class f{interceptNetwork(e,t,r){this.interceptXHR(e,t,r),this.interceptFetch(e,t,r)}interceptXHR(e,t,r){const i=window.XMLHttpRequest;window.XMLHttpRequest=function(){const o=new i,n=o.open,s=o.send;let a={method:"",url:"",startTime:0,headers:{}};return o.open=function(e,t,r=!0,i,o){return a.method=e,a.url=t,a.startTime=Date.now(),n.call(this,e,t,r,i,o)},o.send=function(i){e(a);return o.addEventListener("load",()=>{var e;const i={...a,status:o.status,statusText:o.statusText,duration:Date.now()-a.startTime,responseSize:(null===(e=o.responseText)||void 0===e?void 0:e.length)||0};o.status>=400?r(i):t(i)}),o.addEventListener("error",()=>r(a)),o.addEventListener("timeout",()=>r({...a,error:"timeout"})),s.apply(this,[i])},o}}interceptFetch(e,t,r){const i=window.fetch;window.fetch=async function(o,n){const s=Date.now(),a={url:"string"==typeof o?o:o.toString(),method:(null==n?void 0:n.method)||"GET",startTime:s,headers:(null==n?void 0:n.headers)||{}};e(a);try{const e=await i(o,n),c={...a,status:e.status,statusText:e.statusText,duration:Date.now()-s};return e.status>=400?r(c):t(c),e}catch(e){throw r({...a,error:e instanceof Error?e.message:String(e)}),e}}}async sendData(e,t,r){const i={method:"POST",headers:{"Content-Type":"application/json",...null==r?void 0:r.headers},body:JSON.stringify(t)};if(null==r?void 0:r.timeout){const e=new AbortController;setTimeout(()=>e.abort(),r.timeout),i.signal=e.signal}const o=await fetch(e,i);if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);return o.json()}}class g{setItem(e,t){try{localStorage.setItem(e,t)}catch(e){}}getItem(e){try{return localStorage.getItem(e)}catch(e){return null}}removeItem(e){try{localStorage.removeItem(e)}catch(e){}}clear(){try{localStorage.clear()}catch(e){}}}class v{constructor(){this.platformInfo={platform:"web",version:"1.0.0",userAgent:a(),deviceInfo:{language:navigator.language,cookieEnabled:navigator.cookieEnabled,onLine:navigator.onLine,screen:{width:screen.width,height:screen.height,colorDepth:screen.colorDepth}}},this.errorCapture=new h,this.performance=new p,this.behavior=new m,this.network=new f,this.storage=new g}init(e){}destroy(){this.errorCapture.destroyErrorListeners(),this.performance.destroyPerformanceMonitor(),this.behavior.destroyBehaviorMonitor()}}class T extends c{constructor(e){super(e,new v)}static init(e){return T.instance||(T.instance=new T(e),T.instance.init().catch(e=>{})),T.instance}static getInstance(){return T.instance}static destroy(){T.instance&&(T.instance.destroy(),T.instance=null)}}T.instance=null;const E={init:e=>T.init(e),setVersionInfo:e=>{T.getInstance()},getInstance:()=>T.getInstance(),captureError:(e,t)=>{const r=T.getInstance();r&&r.captureError(e,t)},recordPerformance:(e,t)=>{const r=T.getInstance();r&&r.recordPerformance(e,t)},recordBehavior:(e,t)=>{const r=T.getInstance();r&&r.recordBehavior(e,t)},flush:async()=>{const e=T.getInstance();e&&await e.flush()},getStatus:()=>{const e=T.getInstance();return e?e.getStatus():null},destroy:()=>T.destroy(),on:(e,t)=>{const r=T.getInstance();r&&r.on(e,t)},off:(e,t)=>{const r=T.getInstance();r&&r.off(e,t)}};"undefined"!=typeof window&&(window.MonitorSDK=E),e.WebMonitorSDK=T,e.default=E,Object.defineProperty(e,"__esModule",{value:!0})});
//# sourceMappingURL=index.umd.js.map