UNPKG

@waiting/log

Version:

Lightweight logging for browser

298 lines (281 loc) 8.37 kB
/** * @waiting/log * Lightweight logging for browser * * @version 1.0.2 * @author waiting * @license MIT * @link https://github.com/waitingsong/log#readme */ const defaultConfig = { maxMsgLength: 1024, runLevel: 'log', persist: true, persistTTL: 7 * 24 * 3600, storagePrefix: 'log', }; var LogLevel; (function (LogLevel) { LogLevel[LogLevel['trace'] = 0] = 'trace'; LogLevel[LogLevel['debug'] = 1] = 'debug'; LogLevel[LogLevel['log'] = 2] = 'log'; LogLevel[LogLevel['info'] = 3] = 'info'; LogLevel[LogLevel['warn'] = 4] = 'warn'; LogLevel[LogLevel['error'] = 5] = 'error'; LogLevel[LogLevel['silent'] = 6] = 'silent'; })(LogLevel || (LogLevel = {})); /** Whether the key of LocalStorage item is generated myself */ function isLocalStorageKey(key, storagePrefix) { const arr = key.split('-'); /* istanbul ignore else */ if (arr.length < 3) { return false } const prefix = arr.shift(); const level = arr.shift(); const time = arr.join('-'); /* istanbul ignore else */ if (prefix !== storagePrefix) { return false } /* istanbul ignore else */ if (!level) { return false } if (!time) { return false } else { const dd = new Date(time); /* istanbul ignore else */ if (typeof dd.getTime !== 'function' || Number.isNaN(dd.getTime())) { return false } } return true } /** Whether supress the log level if lower then the runLevel */ function isSuppressLogLevel(runLevel, logLevel) { return LogLevel[logLevel] < LogLevel[runLevel] ? true : false } function isLogLevelToPrune(logLevel, pruneLevel) { /* istanbul ignore else */ if (!logLevel) { return false } /* istanbul ignore else */ if (!pruneLevel) { return true } return logLevel === pruneLevel ? true : false } function isTimeToPrune(time, pruneTime) { if (!time) { return false } const dd = new Date(time); return dd < pruneTime ? true : false } function setMaxMsgLength(length) { validateMaxMsgLength(length); defaultConfig.maxMsgLength = Math.ceil(length); } function validateMaxMsgLength(length) { /* istanbul ignore else */ if (typeof length !== 'number' || length <= 0) { throw new TypeError('Value of parameter maxMsgLenth invalid') } } function setPersist(persist) { validatePersist(persist); defaultConfig.persist = persist; } function validatePersist(persist) { /* istanbul ignore else */ if (typeof persist !== 'boolean') { throw new TypeError('Value of parameter persist invalid') } } function setPersistTTL(ttl) { validatePersistTTL(ttl); defaultConfig.persistTTL = Math.ceil(ttl); } function validatePersistTTL(ttl) { /* istanbul ignore else */ if (typeof ttl !== 'number') { throw new TypeError('Value of parameter ttl invalid') } /* istanbul ignore else */ if (+ttl < 0) { throw new TypeError('Value of parameter ttl invalid') } } /** Set runLevel to supressing the logLevel listed in ENUM LogLevel which lower then the runLevel */ function setRunLevel(runLevel) { validateLogLevel(runLevel); defaultConfig.runLevel = runLevel; } function validateLogLevel(logLevel) { /* istanbul ignore else */ // @ts-ignore if (logLevel !== 'silent' && typeof console[logLevel] !== 'function') { throw new TypeError(`Function console.${logLevel}() NOT exists`) } /* istanbul ignore else */ else if (!logLevel || typeof LogLevel[logLevel] !== 'number') { throw new TypeError('Value of parameter logLevel invalid: ' + logLevel) } } /** minus(-) be convert to underline _ */ function setStoragePrefix(key) { validateStoragePrefix(key); defaultConfig.storagePrefix = key.replace(/-/g, '_'); } function validateStoragePrefix(key) { /* istanbul ignore else */ if (!key || typeof key !== 'string') { throw new TypeError('Value of parameter key invalid') } } /** * Save message into LocalStorage * * @returns key of LocalStorage item, blank if 'silent' */ function localSave(level, data, prefix, maxLen) { /* istanbul ignore else */ if (level === 'silent') { return '' } const time = new Date().toISOString(); const key = `${prefix}-${level}-${time}`; save(key, data, maxLen); return key } function save(key, data, maxLen) { let cont = data; /* istanbul ignore else */ if (typeof data === 'string' && data.length > maxLen) { cont = data.slice(0, maxLen) + ' ...'; } const content = JSON.stringify(cont); /* istanbul ignore else */ if (typeof localStorage === 'object') { try { localStorage.setItem(encodeURIComponent(key), content); } catch (ex) { console.error(ex); } } } function logger(level, message) { /* istanbul ignore else */ if (level === 'silent') { return } if (Array.isArray(message)) { console.group('Group log:'); // tslint:disable-next-line:prefer-for-of for (let i = 0; i < message.length; i++) { // @ts-ignore console[level](message[i]); } console.groupEnd(); } else { // @ts-ignore console[level](message); } } function trace(data, persist) { return proxy('trace', data, persist) } function debug(data, persist) { return proxy('debug', data, persist) } function log(data, persist) { return proxy('log', data, persist) } function info(data, persist) { return proxy('info', data, persist) } function warn(data, persist) { return proxy('warn', data, persist) } function error(data, persist) { return proxy('error', data, persist) } function silent(data, persist) { return proxy('silent', data, persist) } /** Get copy of defaultConfig */ function getConfig() { return Object.assign({}, defaultConfig) } /** Set value of key of defaultConfig and return copy of defaultConfig */ function setConfig(config) { if (config && typeof config === 'object') { for (const [key, value] of Object.entries(config)) { switch (key) { case 'maxMsgLength': setMaxMsgLength(value); break case 'persist': setPersist(value); break case 'persistTTL': setPersistTTL(value); break case 'runLevel': setRunLevel(value); break case 'storagePrefix': setStoragePrefix(value); break /* istanbul ignore next */ default: info(`setConfig(config): value of param invalid: key "${key}"/value "${value}"`); break } } } else { info(`setConfig(config): value of param invalid: "${config}"`); } return getConfig() } function getAvailableLogLevel() { const ret = []; Object.keys(LogLevel).forEach(key => { if (key && typeof key === 'string' && Number.isNaN(+key)) { try { validateLogLevel(key); ret.push(key); } catch (ex) { // void } } }); return ret } /** * @returns void or key of LocalStorage Item (if persist true) */ function proxy(level, data, persist) { /* istanbul ignore else */ if (isSuppressLogLevel(defaultConfig.runLevel, level)) { return } /* istanbul ignore else */ if (level === 'silent') { return } logger(level, data); const persistNew = typeof persist === 'boolean' ? persist : defaultConfig.persist; if (persistNew) { localSave(level, data, defaultConfig.storagePrefix, defaultConfig.maxMsgLength); } } export { trace, debug, log, info, warn, error, silent, getConfig, setConfig, getAvailableLogLevel, LogLevel, isLocalStorageKey, isSuppressLogLevel, isLogLevelToPrune, isTimeToPrune, setMaxMsgLength, validateMaxMsgLength, setPersist, validatePersist, setPersistTTL, validatePersistTTL, setRunLevel, validateLogLevel, setStoragePrefix, validateStoragePrefix };