UNPKG

@dmhsq_monitor/processor

Version:
3 lines (2 loc) 9.2 kB
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("@dmhsq_monitor/core")):"function"==typeof define&&define.amd?define(["exports","@dmhsq_monitor/core"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).DMHSQMonitorProcessor={},t.DMHSQMonitorCore)}(this,(function(t,e){"use strict";const o="DMHSQMonitorProcessor",n="1.0.22",r=18e5,i=.85;var a,s;t.GeoProvider=void 0,(a=t.GeoProvider||(t.GeoProvider={})).IPAPI="ipapi",a.IPINFO="ipinfo",a.CUSTOM="custom",t.ProcessStatus=void 0,(s=t.ProcessStatus||(t.ProcessStatus={})).SUCCESS="success",s.FILTERED="filtered",s.DUPLICATE="duplicate",s.FAILED="failed";class c{constructor(){this.config={enableDeduplicate:!0,deduplicateWindow:r,collectUserIp:!0,collectGeoInfo:!1,mergeSimilarErrors:!0,customProcessors:[]}}init(t){this.config={...this.config,...t}}updateConfig(t){this.config={...this.config,...t}}getConfig(){return{...this.config}}isDeduplicateEnabled(){return!!this.config.enableDeduplicate}getDeduplicateWindow(){return this.config.deduplicateWindow||r}shouldCollectUserIp(){return!!this.config.collectUserIp}shouldCollectGeoInfo(){return!!this.config.collectGeoInfo}shouldMergeSimilarErrors(){return!!this.config.mergeSimilarErrors}getCustomProcessors(){return this.config.customProcessors||[]}}const l=new Map;function h(t){var o;let n="";switch(t.type){case e.EventType.ERROR:n=`${t.type}_${t.data.errorType}_${t.data.message}_${(null===(o=t.data.stack)||void 0===o?void 0:o.substring(0,100))||""}`;break;case e.EventType.PERFORMANCE:n=`${t.type}_${t.data.url||""}_${t.name}`;break;case e.EventType.BEHAVIOR:n=`${t.type}_${t.name}_${t.data.element||""}`;break;default:n=`${t.type}_${t.name}`}return function(t){let e=0;if(0===t.length)return e.toString();for(let o=0;o<t.length;o++){e=(e<<5)-e+t.charCodeAt(o),e|=0}return e.toString()}(n)}function u(t,e=18e5){const o=h(t),n=Date.now();if(l.has(o)){if(n-(l.get(o)||0)<e){l.set(o,n);try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}");t[o]=n,localStorage.setItem("dmhsq_monitor_hashes",JSON.stringify(t))}catch(t){}return!0}}l.set(o,n);try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}");t[o]=n,localStorage.setItem("dmhsq_monitor_hashes",JSON.stringify(t))}catch(t){}return!1}function f(t=36e5){const e=Date.now();for(const[o,n]of l.entries())e-n>t&&l.delete(o);try{const o=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}");let n=!1;for(const r in o)e-o[r]>t&&(delete o[r],n=!0);n&&localStorage.setItem("dmhsq_monitor_hashes",JSON.stringify(o))}catch(t){}}function p(){try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}"),e=Date.now();for(const o in t){const n=t[o];e-n<36e5&&l.set(o,n)}}catch(t){}}function g(){p(),setInterval((()=>{f()}),6e4)}const m={ip:null,timestamp:0,isPrivate:!0};async function d(){const t=Date.now();if(m.ip&&t-m.timestamp<432e5)return{ip:m.ip,isPrivate:m.isPrivate};try{const e=await Promise.race([y(),E(),v()]);m.ip=e.ip,m.isPrivate=e.isPrivate,m.timestamp=t;try{localStorage.setItem("dmhsq_monitor_ip",JSON.stringify(m))}catch(t){}return e}catch(t){try{const t=localStorage.getItem("dmhsq_monitor_ip");if(t){const e=JSON.parse(t);return{ip:e.ip,isPrivate:e.isPrivate}}}catch(t){}return function(){try{const t=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"}]});t.createDataChannel(""),t.createOffer().then((e=>t.setLocalDescription(e))),t.onicecandidate=e=>{if(!e.candidate)return;const o=/([0-9]{1,3}(\.[0-9]{1,3}){3})/.exec(e.candidate.candidate);if(o&&o[1]){const e=o[1];m.ip=e,m.isPrivate=S(e),m.timestamp=Date.now(),t.close()}},setTimeout((()=>t.close()),3e3)}catch(t){}return{ip:"0.0.0.0",isPrivate:!0}}()}}async function y(){const t=await fetch("https://api.ipify.org?format=json",{method:"GET",mode:"cors",cache:"no-cache",timeout:3e3});if(!t.ok)throw new Error("ipify服务失败");const e=await t.json();return{ip:e.ip,isPrivate:S(e.ip)}}async function E(){const t=await fetch("https://checkip.amazonaws.com/",{method:"GET",mode:"cors",cache:"no-cache",timeout:3e3});if(!t.ok)throw new Error("Amazon服务失败");const e=(await t.text()).trim();return{ip:e,isPrivate:S(e)}}async function v(){const t=await fetch("https://ipinfo.io/json",{method:"GET",mode:"cors",cache:"no-cache",timeout:3e3});if(!t.ok)throw new Error("ipinfo服务失败");const e=await t.json();return{ip:e.ip,isPrivate:S(e.ip)}}function S(t){if("127.0.0.1"===t||"localhost"===t||"::1"===t)return!0;const e=t.split(".").map((t=>parseInt(t,10)));return 10===e[0]||(172===e[0]&&e[1]>=16&&e[1]<=31||192===e[0]&&168===e[1])}const w=new Map;async function I(e,o=t.GeoProvider.IPAPI){if(!e||"0.0.0.0"===e||S(e))return{country:"Local",region:"Local",city:"Local",isp:"Local",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone};const n=w.get(e);if(n&&Date.now()-n.timestamp<864e5)return n.data;try{let n;switch(o){case t.GeoProvider.IPAPI:n=await async function(t){const e=await fetch(`https://ip-api.com/json/${t}?fields=country,regionName,city,isp,timezone`,{method:"GET",mode:"cors",cache:"no-cache",timeout:3e3});if(!e.ok)throw new Error("ip-api.com服务失败");const o=await e.json();return{country:o.country,region:o.regionName,city:o.city,isp:o.isp,timezone:o.timezone}}(e);break;case t.GeoProvider.IPINFO:n=await async function(t){const e=await fetch(`https://ipinfo.io/${t}/json`,{method:"GET",mode:"cors",cache:"no-cache",timeout:3e3});if(!e.ok)throw new Error("ipinfo.io服务失败");const o=await e.json();return{country:o.country,region:o.region,city:o.city,isp:o.org,timezone:o.timezone}}(e);break;default:throw new Error(`Unsupported provider: ${o}`)}w.set(e,{data:n,timestamp:Date.now()});try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_geo_cache")||"{}");t[e]={data:n,timestamp:Date.now()},localStorage.setItem("dmhsq_monitor_geo_cache",JSON.stringify(t))}catch(t){}return n}catch(t){try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_geo_cache")||"{}");if(t[e]&&Date.now()-t[e].timestamp<6048e5)return t[e].data}catch(t){}return{}}}function P(t,e){const o=function(t,e){const o=t.length,n=e.length,r=Array(o+1).fill(0).map((()=>Array(n+1).fill(0)));for(let t=0;t<=o;t++)r[t][0]=t;for(let t=0;t<=n;t++)r[0][t]=t;for(let i=1;i<=o;i++)for(let o=1;o<=n;o++){const n=t[i-1]===e[o-1]?0:1;r[i][o]=Math.min(r[i-1][o]+1,r[i][o-1]+1,r[i-1][o-1]+n)}return r[o][n]}(t,e),n=Math.max(t.length,e.length);return 0===n?1:1-o/n}function _(t,o,n=.85){if(t.type!==e.EventType.ERROR||o.type!==e.EventType.ERROR)return!1;if(t.data.errorType!==o.data.errorType)return!1;return P(t.data.message||"",o.data.message||"")>=n}function O(t,o=.85){if(t.length<=1)return t;const n=t.filter((t=>t.type===e.EventType.ERROR)),r=t.filter((t=>t.type!==e.EventType.ERROR)),i=[];for(const t of n){let e=!1;for(const n of i){if(_(n[0],t,o)){n.push(t),e=!0;break}}e||i.push([t])}return[...i.map((t=>{const e={...t[0]};return t.length>1&&(e.data={...e.data,occurrences:t.length,firstOccurrence:t[0].timestamp,lastOccurrence:t[t.length-1].timestamp}),e})),...r]}t.DEFAULT_DEDUPLICATE_WINDOW=r,t.DEFAULT_ERROR_SIMILARITY_THRESHOLD=i,t.PROCESSOR_NAME=o,t.PROCESSOR_VERSION=n,t.Processor=class{constructor(){this._cleanupEventHashes=f,this.configManager=new c,g(),setInterval((()=>{f()}),36e5)}init(t){this.configManager.init(t),console.log(`[${o}] 初始化完成,版本: ${n}`)}async process(t,e){if(this.configManager.isDeduplicateEnabled()&&u(t,this.configManager.getDeduplicateWindow()))return console.log(`[${o}] 检测到重复事件,已过滤: ${t.type} - ${t.name}`),null;const n=this.configManager.getCustomProcessors();let r={...t};for(const t of n)try{const n=t(r,e);if(!n)return console.log(`[${o}] 事件被自定义处理器过滤: ${r.type} - ${r.name}`),null;r=n}catch(t){console.error(`[${o}] 自定义处理器执行失败:`,t)}return r=await this.enrichEvent(r,e),r}async batchProcess(t,e){const n=t.length;let r=[],i=0;for(const o of t){const t=await this.process(o,e);t?r.push(t):i++}if(this.configManager.shouldMergeSimilarErrors()){const t=r.length;r=O(r);const e=t-r.length;console.log(`[${o}] 合并了 ${e} 个相似错误`)}return console.log(`[${o}] 批量处理完成: 原始=${n}, 处理后=${r.length}, 去重=${i}`),r}getConfig(){return this.configManager.getConfig()}updateConfig(t){this.configManager.updateConfig(t)}cleanupCache(t){f(t)}async enrichEvent(t,e){var r;const i={...t},a={};if(this.configManager.shouldCollectUserIp())try{const t=await d();if(a.userIp=t.ip,a.isPrivateIp=t.isPrivate,this.configManager.shouldCollectGeoInfo()&&!t.isPrivate){const e=await I(t.ip);a.geo=e}}catch(t){console.error(`[${o}] 获取IP信息失败:`,t)}return"undefined"!=typeof navigator&&(a.browser={userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform}),i.data={...i.data,metadata:{...null===(r=i.data)||void 0===r?void 0:r.metadata,...a,processor:{name:o,version:n,processedAt:(new Date).toISOString()}}},i}},t.areErrorsSimilar=_,t.calculateErrorSimilarity=P,t.cleanupEventHashes=f,t.generateEventHash=h,t.getGeoInfo=I,t.getUserIp=d,t.groupSimilarErrors=O,t.initDeduplication=g,t.isDuplicateEvent=u,t.isPrivateIp=S,t.loadStoredHashes=p})); //# sourceMappingURL=index.umd.js.map