@dmhsq_monitor/processor
Version:
Data processor package for monitor system
3 lines (2 loc) • 9.07 kB
JavaScript
;var t=require("@dmhsq_monitor/core");const e="DMHSQMonitorProcessor",o="1.0.22",r=18e5,n=.85;var i,s;exports.GeoProvider=void 0,(i=exports.GeoProvider||(exports.GeoProvider={})).IPAPI="ipapi",i.IPINFO="ipinfo",i.CUSTOM="custom",exports.ProcessStatus=void 0,(s=exports.ProcessStatus||(exports.ProcessStatus={})).SUCCESS="success",s.FILTERED="filtered",s.DUPLICATE="duplicate",s.FAILED="failed";class a{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 c=new Map;function l(e){var o;let r="";switch(e.type){case t.EventType.ERROR:r=`${e.type}_${e.data.errorType}_${e.data.message}_${(null===(o=e.data.stack)||void 0===o?void 0:o.substring(0,100))||""}`;break;case t.EventType.PERFORMANCE:r=`${e.type}_${e.data.url||""}_${e.name}`;break;case t.EventType.BEHAVIOR:r=`${e.type}_${e.name}_${e.data.element||""}`;break;default:r=`${e.type}_${e.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()}(r)}function p(t,e=18e5){const o=l(t),r=Date.now();if(c.has(o)){if(r-(c.get(o)||0)<e){c.set(o,r);try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}");t[o]=r,localStorage.setItem("dmhsq_monitor_hashes",JSON.stringify(t))}catch(t){}return!0}}c.set(o,r);try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}");t[o]=r,localStorage.setItem("dmhsq_monitor_hashes",JSON.stringify(t))}catch(t){}return!1}function h(t=36e5){const e=Date.now();for(const[o,r]of c.entries())e-r>t&&c.delete(o);try{const o=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}");let r=!1;for(const n in o)e-o[n]>t&&(delete o[n],r=!0);r&&localStorage.setItem("dmhsq_monitor_hashes",JSON.stringify(o))}catch(t){}}function u(){try{const t=JSON.parse(localStorage.getItem("dmhsq_monitor_hashes")||"{}"),e=Date.now();for(const o in t){const r=t[o];e-r<36e5&&c.set(o,r)}}catch(t){}}function g(){u(),setInterval((()=>{h()}),6e4)}const f={ip:null,timestamp:0,isPrivate:!0};async function m(){const t=Date.now();if(f.ip&&t-f.timestamp<432e5)return{ip:f.ip,isPrivate:f.isPrivate};try{const e=await Promise.race([d(),y(),E()]);f.ip=e.ip,f.isPrivate=e.isPrivate,f.timestamp=t;try{localStorage.setItem("dmhsq_monitor_ip",JSON.stringify(f))}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];f.ip=e,f.isPrivate=v(e),f.timestamp=Date.now(),t.close()}},setTimeout((()=>t.close()),3e3)}catch(t){}return{ip:"0.0.0.0",isPrivate:!0}}()}}async function d(){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:v(e.ip)}}async function y(){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:v(e)}}async function E(){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:v(e.ip)}}function v(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 S=new Map;async function w(t,e=exports.GeoProvider.IPAPI){if(!t||"0.0.0.0"===t||v(t))return{country:"Local",region:"Local",city:"Local",isp:"Local",timezone:Intl.DateTimeFormat().resolvedOptions().timeZone};const o=S.get(t);if(o&&Date.now()-o.timestamp<864e5)return o.data;try{let o;switch(e){case exports.GeoProvider.IPAPI:o=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}}(t);break;case exports.GeoProvider.IPINFO:o=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}}(t);break;default:throw new Error(`Unsupported provider: ${e}`)}S.set(t,{data:o,timestamp:Date.now()});try{const e=JSON.parse(localStorage.getItem("dmhsq_monitor_geo_cache")||"{}");e[t]={data:o,timestamp:Date.now()},localStorage.setItem("dmhsq_monitor_geo_cache",JSON.stringify(e))}catch(t){}return o}catch(e){try{const e=JSON.parse(localStorage.getItem("dmhsq_monitor_geo_cache")||"{}");if(e[t]&&Date.now()-e[t].timestamp<6048e5)return e[t].data}catch(t){}return{}}}function I(t,e){const o=function(t,e){const o=t.length,r=e.length,n=Array(o+1).fill(0).map((()=>Array(r+1).fill(0)));for(let t=0;t<=o;t++)n[t][0]=t;for(let t=0;t<=r;t++)n[0][t]=t;for(let i=1;i<=o;i++)for(let o=1;o<=r;o++){const r=t[i-1]===e[o-1]?0:1;n[i][o]=Math.min(n[i-1][o]+1,n[i][o-1]+1,n[i-1][o-1]+r)}return n[o][r]}(t,e),r=Math.max(t.length,e.length);return 0===r?1:1-o/r}function P(e,o,r=.85){if(e.type!==t.EventType.ERROR||o.type!==t.EventType.ERROR)return!1;if(e.data.errorType!==o.data.errorType)return!1;return I(e.data.message||"",o.data.message||"")>=r}function _(e,o=.85){if(e.length<=1)return e;const r=e.filter((e=>e.type===t.EventType.ERROR)),n=e.filter((e=>e.type!==t.EventType.ERROR)),i=[];for(const t of r){let e=!1;for(const r of i){if(P(r[0],t,o)){r.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})),...n]}exports.DEFAULT_DEDUPLICATE_WINDOW=r,exports.DEFAULT_ERROR_SIMILARITY_THRESHOLD=n,exports.PROCESSOR_NAME=e,exports.PROCESSOR_VERSION=o,exports.Processor=class{constructor(){this._cleanupEventHashes=h,this.configManager=new a,g(),setInterval((()=>{h()}),36e5)}init(t){this.configManager.init(t),console.log(`[${e}] 初始化完成,版本: ${o}`)}async process(t,o){if(this.configManager.isDeduplicateEnabled()&&p(t,this.configManager.getDeduplicateWindow()))return console.log(`[${e}] 检测到重复事件,已过滤: ${t.type} - ${t.name}`),null;const r=this.configManager.getCustomProcessors();let n={...t};for(const t of r)try{const r=t(n,o);if(!r)return console.log(`[${e}] 事件被自定义处理器过滤: ${n.type} - ${n.name}`),null;n=r}catch(t){console.error(`[${e}] 自定义处理器执行失败:`,t)}return n=await this.enrichEvent(n,o),n}async batchProcess(t,o){const r=t.length;let n=[],i=0;for(const e of t){const t=await this.process(e,o);t?n.push(t):i++}if(this.configManager.shouldMergeSimilarErrors()){const t=n.length;n=_(n);const o=t-n.length;console.log(`[${e}] 合并了 ${o} 个相似错误`)}return console.log(`[${e}] 批量处理完成: 原始=${r}, 处理后=${n.length}, 去重=${i}`),n}getConfig(){return this.configManager.getConfig()}updateConfig(t){this.configManager.updateConfig(t)}cleanupCache(t){h(t)}async enrichEvent(t,r){var n;const i={...t},s={};if(this.configManager.shouldCollectUserIp())try{const t=await m();if(s.userIp=t.ip,s.isPrivateIp=t.isPrivate,this.configManager.shouldCollectGeoInfo()&&!t.isPrivate){const e=await w(t.ip);s.geo=e}}catch(t){console.error(`[${e}] 获取IP信息失败:`,t)}return"undefined"!=typeof navigator&&(s.browser={userAgent:navigator.userAgent,language:navigator.language,platform:navigator.platform}),i.data={...i.data,metadata:{...null===(n=i.data)||void 0===n?void 0:n.metadata,...s,processor:{name:e,version:o,processedAt:(new Date).toISOString()}}},i}},exports.areErrorsSimilar=P,exports.calculateErrorSimilarity=I,exports.cleanupEventHashes=h,exports.generateEventHash=l,exports.getGeoInfo=w,exports.getUserIp=m,exports.groupSimilarErrors=_,exports.initDeduplication=g,exports.isDuplicateEvent=p,exports.isPrivateIp=v,exports.loadStoredHashes=u;
//# sourceMappingURL=index.cjs.js.map