logbeacon
Version:
浏览器端日志采集与上报工具,支持多种日志服务后端,包括阿里云日志服务(SLS)和Grafana Loki
3 lines (2 loc) • 11.4 kB
JavaScript
var commonjsGlobal="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function getDefaultExportFromCjs(x){return x&&x.__esModule&&Object.prototype.hasOwnProperty.call(x,"default")?x.default:x}var module,root,definition,loglevel$1={exports:{}};root=commonjsGlobal,definition=function(){var noop=function(){},isIE="undefined"!=typeof window&&void 0!==window.navigator&&/Trident\/|MSIE /.test(window.navigator.userAgent),logMethods=["trace","debug","info","warn","error"],_loggersByName={},defaultLogger=null;function bindMethod(obj,methodName){var method=obj[methodName];if("function"==typeof method.bind)return method.bind(obj);try{return Function.prototype.bind.call(method,obj)}catch(e){return function(){return Function.prototype.apply.apply(method,[obj,arguments])}}}function traceForIE(){console.log&&(console.log.apply||Function.prototype.apply.apply(console.log,[console,arguments])),console.trace}function replaceLoggingMethods(){for(var level=this.getLevel(),i=0;i<logMethods.length;i++){var methodName=logMethods[i];this[methodName]=i<level?noop:this.methodFactory(methodName,level,this.name)}if(this.log=this.debug,"undefined"==typeof console&&level<this.levels.SILENT)return"No console available for logging"}function enableLoggingWhenConsoleArrives(methodName){return function(){"undefined"!=typeof console&&(replaceLoggingMethods.call(this),this[methodName].apply(this,arguments))}}function defaultMethodFactory(methodName,_level,_loggerName){return function(methodName){return"debug"===methodName&&(methodName="log"),"undefined"!=typeof console&&("trace"===methodName&&isIE?traceForIE:void 0!==console[methodName]?bindMethod(console,methodName):void 0!==console.log?bindMethod(console,"log"):noop)}(methodName)||enableLoggingWhenConsoleArrives.apply(this,arguments)}function Logger(name,factory){var inheritedLevel,defaultLevel,userLevel,self=this,storageKey="loglevel";function getPersistedLevel(){var storedLevel;if("undefined"!=typeof window&&storageKey){try{storedLevel=window.localStorage[storageKey]}catch(ignore){}if(void 0===storedLevel)try{var cookie=window.document.cookie,cookieName=encodeURIComponent(storageKey),location=cookie.indexOf(cookieName+"=");-1!==location&&(storedLevel=/^([^;]+)/.exec(cookie.slice(location+cookieName.length+1))[1])}catch(ignore){}return void 0===self.levels[storedLevel]&&(storedLevel=void 0),storedLevel}}function normalizeLevel(input){var level=input;if("string"==typeof level&&void 0!==self.levels[level.toUpperCase()]&&(level=self.levels[level.toUpperCase()]),"number"==typeof level&&level>=0&&level<=self.levels.SILENT)return level;throw new TypeError("log.setLevel() called with invalid level: "+input)}"string"==typeof name?storageKey+=":"+name:"symbol"==typeof name&&(storageKey=void 0),self.name=name,self.levels={TRACE:0,DEBUG:1,INFO:2,WARN:3,ERROR:4,SILENT:5},self.methodFactory=factory||defaultMethodFactory,self.getLevel=function(){return null!=userLevel?userLevel:null!=defaultLevel?defaultLevel:inheritedLevel},self.setLevel=function(level,persist){return userLevel=normalizeLevel(level),!1!==persist&&function(levelNum){var levelName=(logMethods[levelNum]||"silent").toUpperCase();if("undefined"!=typeof window&&storageKey){try{return void(window.localStorage[storageKey]=levelName)}catch(ignore){}try{window.document.cookie=encodeURIComponent(storageKey)+"="+levelName+";"}catch(ignore){}}}(userLevel),replaceLoggingMethods.call(self)},self.setDefaultLevel=function(level){defaultLevel=normalizeLevel(level),getPersistedLevel()||self.setLevel(level,!1)},self.resetLevel=function(){userLevel=null,function(){if("undefined"!=typeof window&&storageKey){try{window.localStorage.removeItem(storageKey)}catch(ignore){}try{window.document.cookie=encodeURIComponent(storageKey)+"=; expires=Thu, 01 Jan 1970 00:00:00 UTC"}catch(ignore){}}}(),replaceLoggingMethods.call(self)},self.enableAll=function(persist){self.setLevel(self.levels.TRACE,persist)},self.disableAll=function(persist){self.setLevel(self.levels.SILENT,persist)},self.rebuild=function(){if(defaultLogger!==self&&(inheritedLevel=normalizeLevel(defaultLogger.getLevel())),replaceLoggingMethods.call(self),defaultLogger===self)for(var childName in _loggersByName)_loggersByName[childName].rebuild()},inheritedLevel=normalizeLevel(defaultLogger?defaultLogger.getLevel():"WARN");var initialLevel=getPersistedLevel();null!=initialLevel&&(userLevel=normalizeLevel(initialLevel)),replaceLoggingMethods.call(self)}(defaultLogger=new Logger).getLogger=function(name){if("symbol"!=typeof name&&"string"!=typeof name||""===name)throw new TypeError("You must supply a name when creating a logger.");var logger=_loggersByName[name];return logger||(logger=_loggersByName[name]=new Logger(name,defaultLogger.methodFactory)),logger};var _log="undefined"!=typeof window?window.log:void 0;return defaultLogger.noConflict=function(){return"undefined"!=typeof window&&window.log===defaultLogger&&(window.log=_log),defaultLogger},defaultLogger.getLoggers=function(){return _loggersByName},defaultLogger.default=defaultLogger,defaultLogger},(module=loglevel$1).exports?module.exports=definition():root.log=definition();var loglevel=getDefaultExportFromCjs(loglevel$1.exports);const ARRAY_SAMPLING_CONFIG={primitive:{threshold:20,head:10,tail:4,middle:3},complex:{threshold:10,head:5,tail:3,middle:2}};function serializeLogContent(content){const serializableObject=serializeSingleValue(content);try{const result=JSON.stringify(serializableObject);return result.length>1e5?result.slice(0,1e5)+"...":result}catch(e){return`[序列化失败: ${e.message}]`}}function serializeSingleValue(value,options={maxDepth:10,sensitiveKeys:["password","token","secret","auth"]},currentDepth=0,seen=new WeakSet){const{maxDepth:maxDepth,sensitiveKeys:sensitiveKeys}=options,type=typeof value;if(null===value||["string","number","boolean","undefined"].includes(type))return value;if("bigint"===type)return`${value.toString()}n`;if("symbol"===type)return value.toString();if("function"===type)return`[Function: ${value.name||"anonymous"}]`;if("object"==typeof value){if(seen.has(value))return"[循环引用]";seen.add(value)}if(currentDepth>=maxDepth)return`[达到最大深度: ${Object.prototype.toString.call(value)}]`;if(value instanceof Error)return`${value.name}: ${value.message}\nStack: ${value.stack||""}`;if(value instanceof Date)return value.toISOString();if(value instanceof RegExp)return value.toString();if("undefined"!=typeof Map&&value instanceof Map){const obj={};for(const[k,v]of value.entries()){obj["object"==typeof k&&null!==k?"[object]":String(k)]=serializeSingleValue(v,options,currentDepth+1,seen)}return obj}if("undefined"!=typeof Set&&value instanceof Set){const arr=[];for(const v of value.values())arr.push(serializeSingleValue(v,options,currentDepth+1,seen));return arr}if(Array.isArray(value)){const rules=value.length>0&&"object"==typeof value[0]&&null!==value[0]?ARRAY_SAMPLING_CONFIG.complex:ARRAY_SAMPLING_CONFIG.primitive;if(value.length<=rules.threshold)return value.map((item=>serializeSingleValue(item,options,currentDepth+1,seen)));const sampledResult={_t:"arr",_l:value.length,_e:{}},indices=new Set;for(let i=0;i<rules.head&&i<value.length;i++)indices.add(i);for(let i=0;i<rules.tail&&value.length-1-i>=0;i++)indices.add(value.length-1-i);const midStart=Math.floor(value.length/2-rules.middle/2);for(let i=0;i<rules.middle&&midStart+i<value.length;i++)indices.add(midStart+i);const sortedIndices=Array.from(indices).sort(((a,b)=>a-b));for(const index of sortedIndices)sampledResult._e[index]=serializeSingleValue(value[index],options,currentDepth+1,seen);return sampledResult}if("undefined"!=typeof window&&value instanceof window.Element)return`<${value.tagName.toLowerCase()} class="${value.className}" id="${value.id}">`;if("object"==typeof value&&null!==value){if("function"==typeof value.toJSON)return serializeSingleValue(value.toJSON(),options,currentDepth+1,seen);const result={};for(const key of Object.keys(value))sensitiveKeys.includes(key.toLowerCase())?result[key]="[敏感信息已过滤]":result[key]=serializeSingleValue(value[key],options,currentDepth+1,seen);return result}return String(value)}function getOrCreateUUID(){if("undefined"==typeof window)return"";const key="_client_uuid";let uuid=window.localStorage.getItem(key);return uuid||(window.crypto&&window.crypto.randomUUID?(uuid=window.crypto.randomUUID(),window.localStorage.setItem(key,uuid)):(uuid=Math.random().toString(36).substring(2)+Date.now().toString(36),window.localStorage.setItem(key,uuid))),uuid}async function sendLog(level,logs){if("undefined"==typeof window)return;const extraInfo="undefined"==typeof window||void 0===window.document?{}:{time:Date.now(),clientUuid:getOrCreateUUID(),userAgent:window.navigator.userAgent,screen:serializeSingleValue({width:window.screen.width,height:window.screen.height}),window:serializeSingleValue({width:window.innerWidth,height:window.innerHeight}),url:window.location.href,referrer:document.referrer},msg={type:"log",payload:{level:level,content:serializeLogContent(logs),...extraInfo}};try{const serviceWorker=await async function(scope="/beacon/"){if(!navigator.serviceWorker)return null;try{const swRegistration=(await navigator.serviceWorker.getRegistrations()).find((reg=>reg.scope.includes(scope)));if(!swRegistration)return null;if(swRegistration.active)return swRegistration.active;if(swRegistration.installing&&swRegistration.waiting)return null;const worker=swRegistration.installing||swRegistration.waiting;if(!worker)return null;const waitForActivation=new Promise(((resolve,reject)=>{worker.addEventListener("statechange",(function(){"activated"===this.state?resolve(swRegistration.active):"redundant"===this.state&&reject(new Error("Service Worker installation failed"))}))})),timeout=new Promise(((_,reject)=>{setTimeout((()=>reject(new Error("Service Worker activation timeout"))),6e4)}));return await Promise.race([waitForActivation,timeout])}catch(e){return null}}("/beacon/");if(serviceWorker)serviceWorker.postMessage(msg);else{const event=new CustomEvent("sendLog",{detail:msg});window.dispatchEvent(event)}}catch(e){}}const logFilter={setKeyWords(keyWords){"undefined"!=typeof window&&"string"==typeof keyWords&&window.localStorage.setItem("_logFilterKeyWords",keyWords)},getKeyWords:()=>"undefined"==typeof window?"":window.localStorage.getItem("_logFilterKeyWords")},LOG_METHODS=["trace","debug","info","warn","error"],log=new Proxy(loglevel,{get(target,prop){const orig=target[prop];return"function"==typeof orig?(fnName=prop,new Proxy(orig,{apply:(target,thisArg,argumentsList)=>{if(!LOG_METHODS.includes(fnName))return target.apply(thisArg,argumentsList);if("setKeyWords"===fnName)return logFilter.setKeyWords(argumentsList[0]);if("undefined"!=typeof window&&sendLog(fnName,argumentsList),"string"!=typeof argumentsList[0])return target.apply(thisArg,argumentsList);const keyWords=logFilter.getKeyWords();return keyWords?argumentsList[0].startsWith(keyWords)?target.apply(thisArg,argumentsList):void 0:target.apply(thisArg,argumentsList)}})):orig;var fnName}});if("undefined"==typeof window){let logLevel="undefined"!=typeof process&&process.env&&process.env.LOGS_LEVEL;logLevel=logLevel||loglevel.levels.TRACE,loglevel.setLevel(logLevel)}export{log as default};
//# sourceMappingURL=logs.js.map