miniprogram-logger-plus
Advanced tools
+3
| 'use strict' | ||
| module.exports = require('./lib/logger.js') |
| 'use strict' | ||
| const { getLevel, isLoud } = require('./level.js') | ||
| const LEVEL = Symbol('Appender#level') | ||
| const ENABLED = Symbol('Appender#enable') | ||
| const ADAPTER = Symbol('Appender#adapter') | ||
| const PREFIX = Symbol('Appender#prefix') | ||
| module.exports = class Appender { | ||
| /** | ||
| * @class | ||
| * @param {object} options | ||
| */ | ||
| constructor(options) { | ||
| // 在调用前对 options 做检测,此处无需再次检测 | ||
| this.name = options.name | ||
| this[LEVEL] = getLevel(options.level || 'DEBUG') | ||
| this[ADAPTER] = options.adapter | ||
| this[PREFIX] = options.prefix || ['now', 'duration', 'level'] | ||
| } | ||
| set level(value) { | ||
| this[LEVEL] = getLevel(value) | ||
| } | ||
| get level() { | ||
| return this[LEVEL] | ||
| } | ||
| get enabled() { | ||
| return this[ENABLED] | ||
| } | ||
| enable() { | ||
| this[ENABLED] = true | ||
| } | ||
| disable() { | ||
| this[ENABLED] = false | ||
| } | ||
| serializeContent(content) { | ||
| const rule = this[PREFIX] | ||
| const list = rule.map((item) => { | ||
| return content[item] | ||
| }) | ||
| list.push(...content.message) | ||
| return list | ||
| } | ||
| log(level, content) { | ||
| // 日志级别不低于 Apperder 的日志级别才输出 | ||
| if (isLoud(level, this[LEVEL]) && this[ENABLED]) { | ||
| const output = this.serializeContent(content) | ||
| const loggerAdapter = this[ADAPTER][level.toLowerCase()] | ||
| if (loggerAdapter && typeof loggerAdapter === 'function') { | ||
| loggerAdapter(...output) | ||
| } else { | ||
| throw new Error(`${this.name}适配器的${level.toLowerCase()}级别的日志方法不存在`) | ||
| } | ||
| } | ||
| } | ||
| } |
| 'use strict' | ||
| module.exports = { | ||
| name: 'console', | ||
| level: 'DEBUG', | ||
| adapter: console, | ||
| prefix: ['now', 'duration', 'level'], | ||
| } |
| 'use strict' | ||
| module.exports = { | ||
| name: 'realtimeLog', | ||
| level: 'INFO', | ||
| adapter: wx.getRealtimeLogManager(), | ||
| prefix: ['duration'], | ||
| } |
+30
| 'use strict' | ||
| const validLevel = ['ALL', 'DEBUG', 'INFO', 'WARN', 'ERROR', 'NONE'] | ||
| function throwError(level) { | ||
| throw new Error(`${level}不是一个有效的日志等级,有效的日志等级包含:${validLevel.toString()}`) | ||
| } | ||
| function levelGrade(level) { | ||
| for (let i = 0; i < validLevel.length; i++) { | ||
| if (level.toUpperCase() === validLevel[i]) { | ||
| return i | ||
| } | ||
| } | ||
| throwError(level) | ||
| } | ||
| function getLevel(level) { | ||
| level = level && level.toUpperCase() | ||
| if (validLevel.includes(level)) { | ||
| return level | ||
| } | ||
| throwError(level) | ||
| } | ||
| function isLoud(logLevel, apapterLevel) { | ||
| return levelGrade(logLevel) >= levelGrade(apapterLevel) | ||
| } | ||
| module.exports = { getLevel, isLoud } |
+129
| 'use strict' | ||
| const Appender = require('./appender.js') | ||
| const utils = require('./utils.js') | ||
| const { getLevel, isLoud } = require('./level.js') | ||
| const APPENDERS = Symbol('Logger#appenders') | ||
| const LEVEL = Symbol('Logger#level') | ||
| const START_TIME = Symbol('Logger#startTime') | ||
| module.exports = class Logger { | ||
| constructor(options) { | ||
| options = options || {} | ||
| /** 日志等级 */ | ||
| this[LEVEL] = getLevel(options.level || 'ALL') | ||
| /** 日志输出源 */ | ||
| this[APPENDERS] = {} | ||
| /** 启动时间,用来计算时间差 */ | ||
| this[START_TIME] = Date.now() | ||
| if (options.console !== false) { | ||
| this.add(require('./appenders/console.js')) | ||
| } | ||
| if (options.realtimeLog !== false) { | ||
| this.add(require('./appenders/realtime_log.js')) | ||
| } | ||
| } | ||
| set level(value) {} | ||
| /** | ||
| * 添加一个新的日志输出源 | ||
| */ | ||
| add(options) { | ||
| if (typeof options !== 'object' || !options.name || !options.adapter) { | ||
| throw new Error('自定义日志输出源 options 错误') | ||
| } | ||
| const name = options.name | ||
| if (this[APPENDERS][name]) { | ||
| throw new Error(name + '日志输出源已经存在,请勿重复添加!') | ||
| } | ||
| this[APPENDERS][name] = new Appender(options) | ||
| } | ||
| /** | ||
| * 移除一个日志输出源 | ||
| * @param {string} name 日志输出源名称 | ||
| */ | ||
| remove(name) { | ||
| if (this[APPENDERS][name]) { | ||
| delete this[APPENDERS][name] | ||
| } | ||
| } | ||
| /** | ||
| * 启用一个日志输出源 | ||
| * @param {string} name 日志输出源名称 | ||
| */ | ||
| enable(name) { | ||
| if (this[APPENDERS][name]) { | ||
| this[APPENDERS][name]['enable']() | ||
| } | ||
| } | ||
| /** | ||
| * 禁用一个日志输出源 | ||
| * @param {string} name 日志输出源名称 | ||
| */ | ||
| disable(name) { | ||
| if (this[APPENDERS][name]) { | ||
| this[APPENDERS][name]['disable']() | ||
| } | ||
| } | ||
| /** | ||
| * 当前时间与初始时间的时间差,会以 '3h 5m 11s 111ms' 字符串的格式输出 | ||
| */ | ||
| get duration() { | ||
| const diff = Date.now() - this[START_TIME] | ||
| return utils.formatMsString(diff) | ||
| } | ||
| /** | ||
| * 以 '2021-04-10 12:53:58.123' 的字符串格式输出当前时间 | ||
| */ | ||
| get nowTime() { | ||
| return utils.nowTimeString() | ||
| } | ||
| debug(...args) { | ||
| this.log('debug', ...args) | ||
| } | ||
| info(...args) { | ||
| this.log('info', ...args) | ||
| } | ||
| warn(...args) { | ||
| this.log('warn', args) | ||
| } | ||
| error(...args) { | ||
| this.log('error', ...args) | ||
| } | ||
| log(level, args) { | ||
| // 日志级别不低于 Logger 的日志级别才输出到日志输出源 | ||
| if (isLoud(level, this[LEVEL])) { | ||
| const now = this.nowTime | ||
| const duration = this.duration | ||
| const content = { | ||
| level: getLevel(level), | ||
| message: args, | ||
| now, | ||
| duration, | ||
| } | ||
| Object.keys(this[APPENDERS]).forEach((appender) => { | ||
| this[APPENDERS][appender]['log'](level, content) | ||
| }) | ||
| } | ||
| } | ||
| } |
+79
| 'use strict' | ||
| /** | ||
| * 对数字补零到指定位数 | ||
| * @param {number} number 被格式化的数字 | ||
| * @param {number} digit 格式化的位数 | ||
| * @returns {string} | ||
| */ | ||
| function zerofill(number, digit = 2) { | ||
| const zero = '0' | ||
| for (let i = 0; i < digit; i++) { | ||
| if (number < Math.pow(10, i + 1)) { | ||
| const str = zero.repeat(digit - i - 1) + number.toString() | ||
| return str | ||
| } | ||
| } | ||
| return number | ||
| } | ||
| /** 返回当前时间的标准格式 */ | ||
| module.exports.nowTimeString = function nowTimeString() { | ||
| const time = new Date() | ||
| const year = time.getFullYear() | ||
| const month = zerofill(time.getMonth()) | ||
| const day = zerofill(time.getDate()) | ||
| const hour = zerofill(time.getHours()) | ||
| const minute = zerofill(time.getMinutes()) | ||
| const second = zerofill(time.getSeconds()) | ||
| const millisecond = zerofill(time.getMilliseconds(), 3) | ||
| const str = `${year}-${month}-${day} ${hour}:${minute}:${second}.${millisecond}` | ||
| return str | ||
| } | ||
| /** | ||
| * 将毫秒数格式化成文本,例如:'3h 5m 11s 111ms' | ||
| * @param {number} ms 待格式化的毫秒数 | ||
| */ | ||
| module.exports.formatMsString = function formatMsString(ms) { | ||
| const s = 1000 | ||
| const m = s * 60 | ||
| const h = m * 60 | ||
| const d = h * 24 | ||
| /** 分隔符 */ | ||
| const sep = '.' | ||
| /** 最终拼接的字符串 */ | ||
| let str = '' | ||
| /** 待操作的剩余值 */ | ||
| let rest = ms | ||
| if (rest === 0) { | ||
| return '0ms' | ||
| } | ||
| if (rest >= h) { | ||
| const hour = Math.floor(rest / h) | ||
| rest -= hour * h | ||
| str = `${hour}h` | ||
| } | ||
| if (rest >= m) { | ||
| const minute = Math.floor(rest / m) | ||
| rest -= minute * m | ||
| str += str ? `${sep}${minute}m` : `${minute}m` | ||
| return str | ||
| } | ||
| if (rest >= s) { | ||
| const second = Math.floor(rest / s) | ||
| rest -= second * s | ||
| str += str ? `${sep}${second}s` : `${second}s` | ||
| return str | ||
| } | ||
| if (rest > 0) { | ||
| const millisecond = Math.floor(rest) | ||
| str += str ? `${sep}${millisecond}ms` : `${millisecond}ms` | ||
| } | ||
| return str | ||
| } |
+21
| MIT License | ||
| Copyright (c) 2021 inlym | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
| SOFTWARE. |
| # miniprogram-logger-plus | ||
| 小程序日志工具 |
+6
-3
| { | ||
| "name": "miniprogram-logger-plus", | ||
| "version": "0.0.1", | ||
| "description": "", | ||
| "version": "1.0.0", | ||
| "description": "一款高效实用且可扩展的小程序日志工具", | ||
| "main": "index.js", | ||
@@ -9,5 +9,8 @@ "scripts": { | ||
| }, | ||
| "keywords": [], | ||
| "keywords": [ | ||
| "miniprogram", | ||
| "inlym" | ||
| ], | ||
| "author": "inlym", | ||
| "license": "MIT" | ||
| } |
-50
| 'use strict' | ||
| const getLevel = require('./level.js') | ||
| const LEVEL = Symbol('Appender#level') | ||
| const ENABLED = Symbol('Appender#enable') | ||
| module.exports = class Appender { | ||
| /** | ||
| * @class | ||
| * @param {object} options | ||
| */ | ||
| constructor(options) { | ||
| options = options || {} | ||
| } | ||
| set level(value) { | ||
| if (typeof value === 'string' || typeof value === 'number') { | ||
| this[LEVEL] = getLevel(options.level) | ||
| } | ||
| } | ||
| get level() { | ||
| return this[LEVEL] | ||
| } | ||
| get enabled() { | ||
| return this[ENABLED] | ||
| } | ||
| enable() { | ||
| this[ENABLED] = true | ||
| } | ||
| disable() { | ||
| this[ENABLED] = false | ||
| } | ||
| /** | ||
| * 是否输出日志 | ||
| * @param {string} level 日志等级 | ||
| */ | ||
| isLoud(level) { | ||
| if (!this[ENABLED] || this[LEVEL] === getLevel('NONE')) { | ||
| return false | ||
| } | ||
| return this[LEVEL] <= getLevel(level) | ||
| } | ||
| log() {} | ||
| } |
| 'use strict' | ||
| const Appender = require('../appender.js') | ||
| module.exports = class ConsoleAppender extends Appender { | ||
| /** | ||
| * @class | ||
| * @param {object} options | ||
| */ | ||
| constructor(options) { | ||
| super(options) | ||
| } | ||
| log() {} | ||
| } |
-27
| 'use strict' | ||
| module.exports = function getLevel(level) { | ||
| const levels = { | ||
| ALL: 0, | ||
| DEBUG: 100, | ||
| INFO: 200, | ||
| WARN: 400, | ||
| ERROR: 800, | ||
| NONE: 1000, | ||
| } | ||
| if (typeof level === 'number') { | ||
| if (level >= 0 && level <= 1000) { | ||
| return level | ||
| } else { | ||
| throw new Error('当 level 为数字时,应在 0 至 1000 之间!') | ||
| } | ||
| } else if (typeof level === 'string') { | ||
| const num = levels[level.toUpperCase()] | ||
| if (typeof num === 'number') { | ||
| return num | ||
| } else { | ||
| throw new Error('level 不存在') | ||
| } | ||
| } | ||
| } |
| 'use strict' | ||
| module.exports = class Logger { | ||
| constructor(options) {} | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No README
QualityPackage does not have a README. This may indicate a failed publish or a low quality package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
15697
81.28%13
62.5%271
230.49%2
-33.33%1
-50%4
Infinity%1
Infinity%