@xinmier/loggers
v2.7.0
Published
辛米尔网页编程工具集·控制台消息机集。
Downloads
19
Readme
辛米尔网页编程工具集·控制台消息机集
npm 包
npm 包之名称
@xinmier/loggers
。
npm 包之主页
https://www.npmjs.com/package/@xinmier/loggers。
概述
总述
@xinmier/loggers
是一个 npm 包,称“控制台消息机集”。下称【本软件】。
本软件是一种编程元件,面向网页开发人员或 Nodejs 程序员,而非最终用户。
开发人员在网页控制台(或令 Nodejs 程序在系统终端)中打印【消息】时,常有如下需求:
需为【消息】添加固定的【前缀】。且不同模块,其【消息】之【前缀】亦不相同。
需将一切【消息】划分出若干【等级】。又另设【等级控制量】,以求仅打印符合【等级要求】的【消息】。具体而言,若调高【等级控制量】,则在控制台打印的【消息】可能增多;反之。
采用本软件,即可实现上述需要。
又,本品将消息分 1 ~ 5 五等。等级【高】者是“繁冗”、“啰嗦”或“旁枝末节”、“细致入微”的【消息】,等级【低】者是所谓“重要”的【消息】。
注:【消息等级】参数共有 6 种可能的值。其中包含 1 ~ 5 个【消息等级】,加上 0 值(代表不打印任何消息)。
【工厂函数】、【消息机集】与【消息机】
本品对外给出一个所谓【工厂函数】。调用【工厂函数】 1 次,产出 1 个【消息机集】;调用多次,产出多个互相独立的【消息机集】。
产生的每一个所谓【消息机集】,携带若干(目前是 11 个)所谓【消息机】。凡【消息机】,大同小异。【消息机】均可用以代替 console.log
、console.debug
、 console.warn
及 console.error
四者, 但不替代其余诸如 console.info
、 console.group
等。
不妨将【消息机集】携带的 11 个【消息机】分为 3 类:
〖日志类〗,或称
log
类。共 7 个。均用于替代console.log
和console.debug
二者。凡〖日志类〗【消息】,均是有【消息等级】的。仅符合【等级要求】的〖日志类〗【消息】会打印,其余会被忽略。
〖警告类〗,或称
warn
类。共 2 个。均用于替代console.warn
。凡〖警告类〗【消息】均无【等级】。换言之,〖警告类〗【消息】一律打印,不可忽略。
〖报错类〗,或称
error
类。共 2 个。均用于替代console.error
。凡〖报错类〗【消息】均无【等级】。换言之,〖报错类〗【消息】一律打印,不可忽略。
以下是【工厂函数】、【消息机集】与【消息机】之间的派生关系(或者说粗略的看作包含关系),以辅助理解:
【工厂函数】 1 次制造 1 个【消息机集】。
1 个【消息机集】 包含 11 个【消息机】,以及 1 个【等级裁决函数】。
可调用任意【消息机】以处理【消息】。
注:
所谓“处理”某【消息】,即指要么打印该【消息】,要么忽略该【消息】。
故,调用任何【消息机】时,应将 1 则或若干则【消息】交付给它,供其“处理”。
该【消息机】会依照在调用【工厂函数】时预设好的【等级标准】要求而动作,要么打印这些【消息】,要么略过这些【消息】。
可调用【等级裁决函数】,以获悉该组【消息机集】是否会打印特定【等级】的【消息】。
故而有以下假想的“等级”树:
此处“等级树”一词并不准确、达意。诸君领会精神即可。望能辅助理解、记忆。
- 工厂函数
- 【消息机集】(目前含 11 枚消息机,以及一枚【等级裁决函数】)
- 【等级裁决函数】,返回一个布尔值。
- 外界调用该【等级裁决函数】,可获悉该组【消息机集】是否会打印特定【等级】的【消息】。
- 【消息机 1】 (其属性名为 `log` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 或 console.debug 1 次。
- 【消息机 2】 (其属性名为 `logLevel1` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 1 次。
- 【消息机 3】 (其属性名为 `logLevel2` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 1 次。
- 【消息机 4】 (其属性名为 `logLevel3` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 1 次。
- 【消息机 5】 (其属性名为 `logLevel4` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.debug 1 次。
- 【消息机 6】 (其属性名为 `logLevel5` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.debug 1 次。
- 【消息机 7】 (其属性名为 `logGroup` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.log 或 console.debug 若干次。
注:在调用时给出的参数表中,每个数组代表一行,每行调用一次 console.log 或 console.debug 。
- 【消息机 8】 (其属性名为 `warn` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.warn 1 次。
- 【消息机 9】 (其属性名为 `warnGroup` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.warn 若干次。
注:在调用时给出的参数表中,每个数组代表一行,每行调用一次 console.warn 。
- 【消息机 10】 (其属性名为 `error` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.error 1 次。
- 【消息机 11】 (其属性名为 `errorGroup` )
- 外界调用该【消息机】 1 次,以按需打印【消息】。恰如调用 console.error 若干次。
注:在调用时给出的参数表中,每个数组代表一行,每行调用一次 console.error 。
消息【等级】系统的运作机制
如本文《总述》中所述,本软件将一切〖日志类〗【消息】划分出若干【等级】。又另设【等级控制量】,以仅打印符合【等级要求】的【消息】。
具体而言,若调高【等级控制量】,则在控制台打印的【消息】可能增多;反之。故而,在构建本软件的【消息机集】时,须给出所谓【允许打印的等级标准】,该标准不妨简称【等级标准】或【等级要求】。又,此所谓【等级标准】即为前述所谓【等级控制量】。凡构建出的【消息机】,其〖日志类〗方法函数处理〖日志类〗【消息】时,一律遵照该【等级标准】;但其〖警告类〗和〖报错类〗方法函数,则不受【等级标准】之影响。
调用某〖日志类〗【消息机】时,自当给出【消息】以供其处理(即打印该【消息】或略去该【消息】)。不难理解,此时须同时指明该【消息】之【等级】。
又,默认的规则是,若【消息】之【等级】小于或等于【允许打印的等级标准】,则该【消息】被打印出来,否则该【消息】被略去。
又,程序员亦可给出所谓【等级裁决函数】,而非给出【允许打印的等级标准】。若给出了【等级裁决函数】,则任何〖日志类〗【消息机】是否打印【消息】,取决于该【等级裁决函数】的【返回值】。具体而言,于任何〖日志类〗【消息】,凡【等级裁决函数】处理其【等级】后返回 true
者,该【消息】会被打印;反之,若【等级裁决函数】处理其【等级】后返回 false
,则该【消息】会被略去。
针对【消息】内容构建之性能优化举措
初期之考虑
某些【消息】之内容颇为繁复。
例如,程序员可能按需打印某非常复杂之【对象】,或巨大的【列表(Array)】,以检视其程序运转之细节。然而,此类消息可能因不满足【等级要求】而被略过。
于此情形,若不采取任何特别措施,则即使该【消息】之【等级】确不满足【等级要求】,或确被【等级裁决函数】裁定为“应略去”,但用以构建该繁复【消息】内容的代码早已运转完毕。换言之,用以构建这些【消息】内容的计算功,会因相关【消息】被裁定为“应略去”而白白浪费掉。此种浪费积少成多,或颇为可观。故,应省则省。
实践证明当下举措未显见裨益
然而,本工具之源代码库中随附了一个简陋的所谓“性能对比.ts”,其运行结果显示,采用函数按需构建须打印的内容,并不比看似“提前”构建须打印内容的方式耗时明显更短,偶然反而耗时更长。也许因为 JavaScript 语言解释器解释函数体本身耗费的时间已然不菲,且超过打印动作之耗时。亦可能因为该简陋的测试代码中的打印任务过轻,不足以体现采用函数方式的真正优势。
尽管上述简陋的性能测试工具令“可以采用函数来临时生成须打印内容”的设计显得多此一举,我也不打算取消该设计。毕竟采用该设计时,并没有负面影响。
总之,上文假想的“或颇为可观”并不成立。改用函数临时按需生成须打印之内容,未显见裨益。
附:该《性能对比.ts》即可以运行在 Nodejs 命令行环境,亦可运行在浏览器环境。
运行在 Nodejs 命令行环境的做法:
npm run bench-mark-in-nodejs
运行在浏览器环境的做法:
先要在命令行环境构建出适合浏览器环境运行的代码。特别是,代码须为 JavaScript 而不是 TypeScript 。故而,请先在命令行环境中执行下方命令:
npm run build-test-of-bench-mark-in-html
然后,启动一个 Http 服务程序,来伺服
./测试集
这一文件夹。又,为便于举例,假定你配置的站点为http://localhost:11094
。你采用 nginx 、 tomcat 、 IIS 之类的工具均可。如果你正在使用 VSCode 这款工具,那么不妨采用 VSCode 的 Expressjs 插件。 本工具之源代码库中的 VSCode 配置文件(
settings.json
)中已有现成的配置条目。打开浏览器,浏览
http://localhost:11094/源/index.html
这一网址。按键盘上的 F11 键,或按 Ctrl + Shift + i 组合键,来打开浏览器的“控制台”。在控制台中观察执行结果。
说回函数临时生成内容之细节
尽管采用函数的方法未显见裨益,但仍得以保留。以下是该设计之细节。
为求节省计算之功,本品自 v2.5.0
版始,视所有实参中“直接”给出的函数为所谓【消息内容生成器】。与本品之前的版本不同,在本品之新版中,这些【消息内容生成器】会被调用,而不是被 console.log
之类的原生函数打印出来。调用后,其【返回值】才作为【消息】内容。
所谓 “ 在实参中直接给出 ” ,如何理解?须知,凡诸【消息机】实参中的函数,可能存在于以下“位置”:
- 某函数(甲)自身即为【消息机】之某实参。凡此种函数,即是所谓“直接”给出的函数。【消息机】会调用它,并以其返回值作为【消息】内容。
- 某函数(甲)为【消息机】之某实参对象(乙)之方法函数。于此情形,【甲】视作【消息】内容的一部分。
- 某函数(甲)为【消息机】之某实参列表(Array)(乙)之成员。于此情形,【甲】视作【消息】内容的一部分。
- 某函数(甲)为某“直接”给出之函数(乙) 调用 后的【返回值】,或【返回值】的一部分。于此情形,产出的【甲】视作【消息】内容的一部分。
凡视为【消息】内容之部分的函数,【消息机】不会调用它。故而,一旦【消息】之【等级】满足要求,则 console.log
之类的原生函数会将前述函数(作为【消息】的一部分)打印出来。
又,已知〖警告类〗和〖报错类〗【消息】一律打印,不可略过,因此理论上不必为这类【消息机】设计【消息内容生成器】的逻辑。但,为求令一切【消息机】之行为相仿,遂令〖警告类〗和〖报错类〗【消息机】也可接受所谓“直接”给出的函数,作为【消息内容生成器】。
又见下例。
import { createXmeLoggers } from '@xinmier/loggers'
const xmeLoggers1 = createXmeLoggers({
messagePrefix: '某某模块之名称',
})
xmeLoggers1.logLevel2(() => [ '某函数产出的消息内容' ])
xmeLoggers1.logGroup(2, () => [
[ createMessageToPrintOfLevel(1) ],
[ createMessageToPrintOfLevel(2) ],
[ createMessageToPrintOfLevel(3) ],
[ createMessageToPrintOfLevel(4) ],
[ createMessageToPrintOfLevel(5) ],
], [
{
我乃复杂的对象: 1,
我有不少属性: true,
有些属性还挺复杂: {
中华英雄谱: [
'霍去病',
'岳飞',
'彭大元帅',
'钱学森',
'81192 王伟',
],
},
消息内容: [
'我的“母对象”视作一则【消息】的一部分。',
'首先,它是一个对象。',
'又,它位于列表中而非由函数产生。故而它会过早构造。',
'一旦本次打印被整个略过,则用以产生该对象的计算将是无用功,形成浪费。',
].join(''),
我还有方法函数: () => Math.random().toFixed(8).slice(2),
'须知,方法函数是视作【消息】内容的一部分的。它将被原封不动地打印常量,而不是被【消息机】调用。' () {
// 今有雉兔同笼,上有三十五头,下有九十四足,问雉兔各几何?
const 鸡兔共有头 = 35 // eslint-disable-line
const 鸡兔共有脚 = 94 // eslint-disable-line
return {
鸡: 23,
兔: 12,
}
},
}
])
综上,简言之,有以下两点:
- 调用【工厂函数】时,须给出【等级标准】,或【等级裁决函数】。
- 调用〖日志类〗【消息机】来尝试打印【消息】时,须给这条【消息】自身的【等级】。【等级】合规,则该【消息】确实会打印;否则,该【消息】会被忽略。
- 〖警告类〗和〖报错类〗【消息】没有所谓【等级】。换言之, 〖警告类〗和〖报错类〗【消息】一律打印。
- 凡“直接”作为实参的函数,视作【消息内容生成器】,它们均会被调用。一切产出(即返回值)视作【消息】内容。
为不同模块设计不同的【消息前缀】
当应用程序较复杂时,为了指明消息所隶属的模块,程序员往往会在各消息中设计前缀。特定的模块中的消息,采用特定的、共同的前缀。由此,不同模块打印的消息易于区别、理解。
若运用本工具集,如何做到这一点呢?很简单,分别为每一个模块调用【工厂函数】一次,每次给定不同的消息前缀。即可。见下例。
// 源文件-1.js
import { createXmeLoggers } from '@xinmier/loggers'
const xmeLoggersOfModule1 = createXmeLoggers({
// * * * * * * * * * * * * * * * * * * * *
messagePrefix: '模块-1', // 本例之重点在此。
// * * * * * * * * * * * * * * * * * * * *
/**
* 于本套【消息机集】,
* 凡允许打印的【消息】,其【等级】不得高于 4 ,但可以等于 4 。
*/
allowedLogMaxLevel_Or_LogLevelsTriage: 4,
})
console.log(xmeLoggersOfModule1.shouldLogLevel(3)) // 该语句打印出 true 。
// 源文件-2.js
import { createXmeLoggers } from '@xinmier/loggers'
const xmeLoggersOfModule2 = createXmeLoggers({
// * * * * * * * * * * * * * * * * * * * *
messagePrefix: '模块-2', // 本例之重点在此。
// * * * * * * * * * * * * * * * * * * * *
/**
* 于本套【消息机集】,
* 凡允许打印的【消息】,其【等级】须为 1 。
*/
allowedLogMaxLevel_Or_LogLevelsTriage: 1,
})
console.log(xmeLoggersOfModule2.shouldLogLevel(3)) // 该语句打印出 false 。
用法(面向网页开发人员)
安装
在命令行环境中,cd
进入你的网页开发项目的文件夹,并执行以下命令:
npm i @xinmier/loggers
在代码中使用本工具集
本工具集面向网页开发人员。程序员在编写其代码时,可以采用本工具集。故下方所谓用法均系介绍在编程活动中如何采用本工具集。因此,所谓“用法”亦称“写法”。
简单示例
import {
createXmeLoggers,
} from '@xinmier/loggers'
const xmeLoggersOfMyAppCoreModule = createXmeLoggers({
/**
* 假设有某某程序,其包含一个名为“核心模块”的模块。
* 则,为该所谓“核心模块”专门设计的【消息机集】,
* 其任何【消息】不妨配有如下【消息前缀】。
*/
messagePrefix: '核心模块',
/**
* 于本套【消息机集】,
* 凡允许打印的【消息】,其等级不得高于 3 ,但可以等于 3 。
*/
allowedLogMaxLevel_Or_LogLevelsTriage: 3,
})
/**
* 下方 `core` 即为设想的“某某程序的”所谓“核心模块”。
* 假设该模块具备两个【方法函数】: `method1` 和 `method2` 。
* 假设上述两个方法函数内若干处,须按需打印一些消息。
*/
export const core = {
method1 (): void {
xmeLoggersOfMyAppCoreModule.log(4, '该消息不会被打印', ',因为其等级为', 4, '超出了要求的 3 等级。')
xmeLoggersOfMyAppCoreModule.logLevel5('该消息不会被打印', ',因为其等级为', 5, '超出了要求的 3 等级。')
},
method2 (): void {
xmeLoggersOfMyAppCoreModule.log(2, '该消息会被打印,因为其等级为 2 。并未超出要求的 3 等级。')
xmeLoggersOfMyAppCoreModule.logLevel1('该消息会被打印,因为其等级为 1 。并未超出要求的 3 等级。')
const someEventDetails = { 肇: '老吴' }
if (xmeLoggersOfMyAppCoreModule.shouldLogLevel(4)) {
xmeLoggersOfMyAppCoreModule.log(4, '重大事件。细节如下:', { ...someEventDetails })
} else {
xmeLoggersOfMyAppCoreModule.log(1, '重大事件。')
}
},
}
完整的测试集
下方的代码主体等同于本软件配套的测试集的代码全文。仅删去了少了无关紧要的代码。
又,测试集文件为 ./测试集/index.ts
。
import {
T_XmeLogLevel,
createXmeLoggers,
} from '../yuan/index.js'
function createMessageToPrintOfLevel (level: T_XmeLogLevel) { return `应出现该句。此句【消息】之【等级】为 ${level} 。` }
const MESSAGE_TO_HIDE = '!!!!!!!! 不应出现该句!'
const messageOfWarning = '故意警告一次!换言之,此警告并不意味着该测试用例结果不合预期。'
const messageOfError = '故意报错一次!换言之,此报错并不意味着该测试用例结果不合预期。'
function createMessageLinesToPrint (category: '日志' | '警告' | '报错'): Array<Array<any>> {
const heading = category === '日志' ? '应该出现的多行〖日志〗'
: category === '警告' ? '多行〖警告〗'
: '多行〖报错〗'
return [
[ `${heading}:`, '这是第', 1, '行。' ],
[ `${heading}:`, '这是第', 2, '行。' ],
[ `${heading}:`, '这是第(3)行。' ],
[ `${heading}:`, '这是第四行。' ],
[ `${heading}:`, '^ ^ ^ ^ ^ ^ ^ ^' ],
]
}
const MESSAGE_LINES_TO_HIDE: Array<Array<any>> = [
[ '不应出现该多行消息!', '这是第', 1, '行。' ],
[ '不应出现该多行消息!', '这是第', 2, '行。' ],
[ '不应出现该多行消息!', '这是第(3)行。' ],
[ '不应出现该多行消息!', '这是第四行。' ],
[ '不应出现该多行消息!', '^ ^ ^ ^ ^ ^ ^ ^' ],
]
/* eslint-disable no-constant-condition */
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const xmeLoggers = createXmeLoggers({
messagePrefix: '功能块甲',
allowedLogMaxLevel_Or_LogLevelsTriage: 3,
})
xmeLoggers.log(0, MESSAGE_TO_HIDE)
xmeLoggers.log(1, createMessageToPrintOfLevel(1))
xmeLoggers.log(2, createMessageToPrintOfLevel(2))
xmeLoggers.log(3, createMessageToPrintOfLevel(3))
xmeLoggers.log(4, MESSAGE_TO_HIDE)
xmeLoggers.log(5, MESSAGE_TO_HIDE)
xmeLoggers.logLevel1(createMessageToPrintOfLevel(1))
xmeLoggers.logLevel2(createMessageToPrintOfLevel(2))
xmeLoggers.logLevel3(createMessageToPrintOfLevel(3))
xmeLoggers.logLevel4(MESSAGE_TO_HIDE)
xmeLoggers.logLevel5(MESSAGE_TO_HIDE)
/**
* 【消息】是有【等级】的。
* 下方第 1 个参数并不是数字。因此该组【多行消息】的【等级】为默认的 2 。
* 下方第 2 个参数也不是数字。因此每行依照默认配置,缩进 4 个空格。
*/
xmeLoggers.logGroup( ...createMessageLinesToPrint('日志'))
/**
* 【消息】是有【等级】的。
* 下方第 1 个参数 3 即代表该组【多行消息】的【等级】为 3 。
* 下方第 2 个参数并不是数字。因此每行依照默认配置,缩进 4 个空格。
*/
xmeLoggers.logGroup(3, ...createMessageLinesToPrint('日志'))
/**
* 【消息】是有【等级】的。
* 下方第 1 个参数 3 即代表该组【多行消息】的【等级】为 3 。
* 下方第 2 个参数 3 代表每行缩进 3 个空格。
*/
console.log('注意:下面一组信息,将缩进明确配置为 3 个空格。')
xmeLoggers.logGroup(3, 3, ...createMessageLinesToPrint('日志'))
/**
* 【消息】是有【等级】的。
* 下方第 1 个参数 4 即代表该组【多行消息】的【等级】为 4 。
* 特定于本例,该组【多行消息】并不会打印。因为等级 4 不满足条件。
*/
xmeLoggers.logGroup(4, ...MESSAGE_LINES_TO_HIDE)
/** 【警告】是没有所谓【等级】的。【警告】一律打印。 */
xmeLoggers.warn(messageOfWarning)
/** 【警告】是没有所谓【等级】的。【警告】一律打印。 */
xmeLoggers.warnGroup(...createMessageLinesToPrint('警告'))
/** 【报错】是没有所谓【等级】的。【报错】一律打印。 */
xmeLoggers.error(messageOfError)
/** 【报错】是没有所谓【等级】的。【报错】一律打印。 */
xmeLoggers.errorGroup(...createMessageLinesToPrint('报错'))
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const xmeLoggers = createXmeLoggers({
messagePrefix: '功能块乙',
allowedLogMaxLevel_Or_LogLevelsTriage: l => l === 4 || l === 1,
})
xmeLoggers.log(0, MESSAGE_TO_HIDE)
xmeLoggers.log(1, createMessageToPrintOfLevel(1))
xmeLoggers.log(2, MESSAGE_TO_HIDE)
xmeLoggers.log(3, MESSAGE_TO_HIDE)
xmeLoggers.log(4, createMessageToPrintOfLevel(4))
xmeLoggers.log(5, MESSAGE_TO_HIDE)
xmeLoggers.warn(messageOfWarning)
xmeLoggers.warnGroup( ...createMessageLinesToPrint('警告'))
xmeLoggers.error(messageOfError)
xmeLoggers.errorGroup(...createMessageLinesToPrint('报错'))
if (xmeLoggers.shouldLogLevel(3)) {
console.log('该行【消息】根本不会打印。')
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const xmeLoggers = createXmeLoggers({
messagePrefix: '功能块丙(这个功能块的名字很长,故本工具会在其名字后面自动折行)',
/**
* 注意,下方给出的值是一个我所谓【等级裁决函数】。
* 不难理解,其含义是仅允许【等级】大于 3 的【消息】打印出来。
*/
allowedLogMaxLevel_Or_LogLevelsTriage: l => l > 3,
})
xmeLoggers.log(0, MESSAGE_TO_HIDE)
xmeLoggers.log(1, MESSAGE_TO_HIDE)
xmeLoggers.log(2, MESSAGE_TO_HIDE)
xmeLoggers.log(3, MESSAGE_TO_HIDE)
xmeLoggers.log(4, createMessageToPrintOfLevel(4))
xmeLoggers.log(5, createMessageToPrintOfLevel(5))
/**
* 【消息】是有【等级】的。
* 下方第 1 个参数 4 即代表该组【多行消息】的【等级】为 4 。
* 下方第 2 个参数 3 代表每行缩进 3 个空格。 */
console.log('注意:下面一组信息,将缩进明确配置为 3 个空格。')
xmeLoggers.logGroup(4, 3, ...createMessageLinesToPrint('日志'))
xmeLoggers.warn(messageOfWarning)
/**
* 【警告】是没有所谓【等级】的。【警告】一律打印。
* 故下方函数的调用不存在给出 2 个数字的参数形式。
* 又,下方第 1 个参数不是数字。因此每行依照默认配置,缩进 4 个空格。 */
xmeLoggers.warnGroup( ...createMessageLinesToPrint('警告'))
xmeLoggers.warn(messageOfError)
/**
* 【报错】是没有所谓【等级】的。【报错】一律打印。
* 故下方函数的调用不存在给出 2 个数字的参数形式。
* 又,下方的数字 4 代表每行报错的行首缩进 4 个空格。 */
xmeLoggers.errorGroup(4, ...createMessageLinesToPrint('报错'))
编程接口
根级别导出项
根级别导出项有 6 个,为:
工厂函数
createXmeLoggers
。用以构建符合T_XmeLogger_CreatedLoggers
接口的对象,即所谓【消息机集】。详见下文《TypeScript 诸接口详解 · 根导出项
createXmeLoggers
》。常量
xmeLogLine_Short
,类型为string
,值为连续 51 个'-'
字符组成的字符串。常量
xmeLogLine_Long
,类型为string
,值为连续 130 个'-'
字符组成的字符串。常量
XmeLoggers_MessagePrefix_Default
,类型为string
,值为'未具名模块'
。常量
XmeLoggers_MessagePrefix_DecoAtStart
,类型为string
,值为'['
。常量
XmeLoggers_MessagePrefix_DecoAtEnd
,类型为string
,值为']:'
。
TypeScript 接口总览
// 其中 `0` 代表对应的消息永不打印。
export type T_XmeLogLevel = 0 | 1 | 2 | 3 | 4 | 5;
/**
* 此为一种函数。
*
* 此种函数用以裁决一条【消息】打印与否。
*
* 此种函数须返回一个 boolean 值。
* 于给定的某条【消息】和给定的此种函数,
* 若此种函数返回 `true` ,则该【消息】打印;
* 若此种函数返回 `false` ,则该【消息】忽略。
*
* 又,此种函数由用户(即使用本软件的程序员们)自行设计并给出。
*/
export type T_XmeLogger_LogLevelTriageFunction = (logLevelOfSomeMessage: T_XmeLogLevel) => boolean;
export type T_XmeLogger_LogLevel_OrLogLevelTriage = T_XmeLogLevel | T_XmeLogger_LogLevelTriageFunction;
/** 表征单个【通用的消息机】,【消息等级】须临时由其第一个参数给出。 */
export type T_XmeLogger_LogFunction = (requiredLogLevel: T_XmeLogLevel, ...messageParts: Array<any>) => void;
/** 表征单个【已预设了消息等级的消息机】。 */
export type T_XmeLogger_LogFunction_OfSpecificLevel = (...messageParts: Array<any>) => void;
/**
* 表征单个【带缩进功能的多行消息机】,适用于〖日志类〗的【多行消息】。
* 又,可见该【消息机】有 3 种变体。
*/
export interface T_XmeLogger_LogFunction_MultipleLines {
(requiredLogLevel: T_XmeLogLevel, /* | */ indentation: string | number, /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
(requiredLogLevel: T_XmeLogLevel, /* | */ /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
( /* | */ /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
}
/** 下方类型表征〖警告类〗或〖报错类〗的单个【消息机】。 */
export type T_XmeLogger_WarningOrErrorReportingFunction = (...messageParts: Array<any>) => void;
/**
* 表征单个【带缩进功能的多行消息机】,通用于〖警告类〗或〖报错类〗的【多行消息】。
* 又,可见该【消息机】有 2 种变体。
*/
export interface T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines {
(indentation: string | number, /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
( /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void;
}
/**
* 下方接口类型表征【工厂函数】的产出(即【工厂函数】的返回值)。
* 可见,每次调用【工厂函数】,会构建出一套 11 个【消息机】。它们大同小异。
*/
export interface T_XmeLogger_CreatedLoggers {
log: T_XmeLogger_LogFunction;
logGroup: T_XmeLogger_LogFunction_MultipleLines;
logLevel1: T_XmeLogger_LogFunction_OfSpecificLevel;
logLevel2: T_XmeLogger_LogFunction_OfSpecificLevel;
logLevel3: T_XmeLogger_LogFunction_OfSpecificLevel;
logLevel4: T_XmeLogger_LogFunction_OfSpecificLevel;
logLevel5: T_XmeLogger_LogFunction_OfSpecificLevel;
shouldLogLevel: T_XmeLogger_LogLevelTriageFunction;
warn: T_XmeLogger_WarningOrErrorReportingFunction;
warnGroup: T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines;
error: T_XmeLogger_WarningOrErrorReportingFunction;
errorGroup: T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines;
}
TypeScript 诸接口详解
主要的【根导出项】为工厂函数
createXmeLoggers
export function createXmeLoggers (options?: { /** 该项不言自明。 */ messagePrefix?: string; /** * 〖日志类〗【消息】均有【等级】。 * 本参数的值用以裁定哪些【等级】的【消息】应打印,其余【消息】则忽略。 * 本参数的值可以是一个函数。若确实给出了函数,则该函数不妨称【等级裁决函数】。 * 该函数应返回一个 boolean 值。 * 于某一条具体的【消息】,若该函数若返回值为 true ,则该【消息】被裁定为“应打印”; * 否则,该【消息】被裁定为“应忽略”。 */ allowedLogMaxLevel_Or_LogLevelsTriage?: T_XmeLogger_LogLevel_OrLogLevelTriage; /** * 当使用产出的【消息机】打印【多行消息】时, * 本参数设置【多行消息】中每行行首缩进空格数的默认值。 */ indentation?: string | number; }): T_XmeLogger_CreatedLoggers;
这是一个工厂函数(暂称【甲】),用以构建一个对象(暂称【乙】)。
【乙】携带一套所谓【消息机】(均暂称【丙】),以及 1 枚【等级裁决函数】(暂称【丁】)。
目前,【丙】共有 11 枚,大同小异,分别针对不同的运用要求。如前所述,【丁】仅有 1 枚。
【乙】的属性(亦即【丙】和【丁】)如下:
- 名为
log
的函数,暂称【丙1】。它符合T_XmeLogger_LogFunction
接口。 - 名为
logLevel1
的函数,暂称【丙2】。它符合T_XmeLogger_LogFunction_OfSpecificLevel
接口。 - 名为
logLevel2
的函数,暂称【丙3】。它符合T_XmeLogger_LogFunction_OfSpecificLevel
接口。 - 名为
logLevel3
的函数,暂称【丙4】。它符合T_XmeLogger_LogFunction_OfSpecificLevel
接口。 - 名为
logLevel4
的函数,暂称【丙5】。它符合T_XmeLogger_LogFunction_OfSpecificLevel
接口。 - 名为
logLevel5
的函数,暂称【丙6】。它符合T_XmeLogger_LogFunction_OfSpecificLevel
接口。 - 名为
logGroup
的函数,暂称【丙7】。它符合T_XmeLogger_LogFunction_MultipleLines
接口。 - 名为
warn
的函数,暂称【丙8】。它符合T_XmeLogger_WarningOrErrorReportingFunction
接口。 - 名为
warnGroup
的函数,暂称【丙9】。它符合T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines
接口。 - 名为
error
的函数,暂称【丙10】。它符合T_XmeLogger_WarningOrErrorReportingFunction
接口。 - 名为
errorGroup
的函数,暂称【丙11】。它符合T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines
接口。 - 名为
shouldLogLevel
的函数,暂称【丁】。它符合T_XmeLogger_LogLevelTriageFunction
接口。
简言之,【甲】构建出一系列【乙】(携带着【丙】和【丁】)。日常,开发者频繁使用【丙】和【丁】,而非【甲】。
【工厂函数】的调用参数(唯壹壹个)
工厂函数仅有一个调用参数,且可省略。其类型定义如下:
options?: { messagePrefix?: string; allowedLogMaxLevel_Or_LogLevelsTriage?: T_XmeLogger_LogLevel_OrLogLevelTriage; indentation?: string | number; }
其中:
options.messagePrefix?: string
该值可省略。默认值为
'未具名模块'
。该组【消息机】每次打印任何消息时公用的所谓【前缀文字】。若该前缀文字过长,大于 16 个字符(即大于等于 17 个字符),则该前缀后面会自动换行。
options.allowedLogMaxLevel_Or_LogLevelsTriage?: T_XmeLogger_LogLevel_OrLogLevelTriage
该值可省略。默认值为
2
。该值用以控制在控制台(Console)中打印消息的详尽程度。可取数字(
T_XmeLogLevel
)或一个函数(T_XmeLogger_LogLevelTriageFunction
)。- 若取函数,则该函数称所谓【等级裁决函数】。在每个〖日志类〗【消息机】的每次调用时,【等级裁决函数】该【消息机】收到的【消息】之【等级】,并决定是否打印该【消息】。具体而言,任何【消息】,凡【等级裁决函数】处理其【等级】后返回 true 者,该【消息】会被打印;反之,若【等级裁决函数】处理其【等级】后返回 false ,则该【消息】会被忽略。
- 若取数字,则须在
0
到5
之间,含0
,含5
。若取0
,代表不打印任何消息;若取值1
到5
变化,则在控制的可能打印出的消息逐渐增多;反之。特别指出,若取5
代表打印一切消息。 - 若取数字,但不在
0
到5
之间,或取值根本是不数字,也不是函数,则本软件启用幕后预定的所谓“默认值”,即2
。
options.indentation?: string | number
专门用以控制【带缩进功能的多行消息机】在控制台(Console)中打印信息时,每行起始部位的缩进内容。一般的,人们喜欢用若干空格作为缩进内容,但亦不妨故意配置成任意文本。
若该值取文本值(string),则原封不动沿用之;若该值取数字值,则代表每行首部应打印的连续空格的个数,以此形成所谓“缩进”。
又,若该值取数字,则等效整数值(取 Math.ceil)不可小于 3 ,可以等于 3 。
该值可省略。默认值为
4
,即连续 4 个空格。
【工厂函数】的返回值。
下方接口类型表征【工厂函数】的产出(即【工厂函数】的返回值)。可见, 每次调用【工厂函数】,会构建出一套 11 个【消息机】 。它们大同小异。
export interface T_XmeLogger_CreatedLoggers { log: T_XmeLogger_LogFunction; logGroup: T_XmeLogger_LogFunction_MultipleLines; logLevel1: T_XmeLogger_LogFunction_OfSpecificLevel; logLevel2: T_XmeLogger_LogFunction_OfSpecificLevel; logLevel3: T_XmeLogger_LogFunction_OfSpecificLevel; logLevel4: T_XmeLogger_LogFunction_OfSpecificLevel; logLevel5: T_XmeLogger_LogFunction_OfSpecificLevel; shouldLogLevel: T_XmeLogger_LogLevelTriageFunction; warn: T_XmeLogger_WarningOrErrorReportingFunction; warnGroup: T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines; error: T_XmeLogger_WarningOrErrorReportingFunction; errorGroup: T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines; }
- 名为
工厂函数产出的、符合
T_XmeLogger_CreatedLoggers
接口的对象工厂函数产出一个对象,它是所谓【消息机集】。它包含 11 个属性(或者说字段)。这些属性的值全部都是函数。这些函数均称所谓【消息机】。这些【消息机】均可用以代替
console.log
、console.debug
、console.warn
及console.error
四者, 但不替代其余诸如console.info
、console.group
等。工厂函数产出的对象中的
log
函数它是未预设【消息等级】的所谓【通用消息机】。恰因它未预设【消息等级】,调用它时,须在第 1 个参数给出【消息等级】。又,它用于取代
console.log
和console.debug
二者。log
函数的调用参数表(依次)第 1 参数
logLevelOfThisMessage: T_XmeLogLevel
。用以控制本次调用是否真执行console.log
或console.debug
之一。若本参数 小于等于 工厂函数中收到的
allowedLogMaxLevel_Or_LogLevelsTriage
,则本次调用会执行console.log
或console.debug
;否则,不会调用它们,故不会在控制台有所输出。又,若
logLevelOfThisMessage
小于4
(不等于4
)时,采用console.log
;否则,采用console.debug
。除第 1 参数之外的一切参数,将原封不动的传递给
console.log
或console.debug
。
返回值,无。
工厂函数产出的对象中的
logLevel1
~logLevel5
函数它们都是【已预设了消息等级的消息机】。
它们之任一均可替代
console.log
和console.debug
二者。调用参数表(依次)
- 一切参数均将原封不动的传递给
console.log
或console.debug
。
返回值,无。
- 一切参数均将原封不动的传递给
工厂函数产出的对象中的
logGroup
函数它是【多行消息机】。它用于取代
console.log
和console.debug
二者。该函数用以打印多行消息。每行消息的首部可以有相同的缩进。默认的缩进是连续 4 个空格。
为了实现一次调用打印多行消息,且为了免去本工具的使用者(即是程序员们)反复添加或拼接换行符(
'\n'
), 【多行消息机】要求一切【消息】均存放在列表(Array)中,每行【消息】一个列表,多行【消息】多个列表。 具体而言,【多行消息机】对给出的每个列表都调用一次console.log
或console.debug
,多个列表则调用多次。 于某个列表,其一切成员将原封不动的传递给对应的console.log
或console.debug
。又,为了控制消息的等级,也为了控制每行消息首部的缩进,【多行消息机】的消息机允许在参数表首部设计 1 个或 2 个特别的参数。这 1 个或 2 个参数必须出现在参数表的起始位置,即必须是第 1 和第 2 参数。它们之后的一切参数均代表逐行消息,故均须为列表(Array)。
第 1 个参数,若不是列表(Array),则必须是数字,用以表征该组多行消息的【等级】。
在第 1 个参数确是数字的前提下, 如果第 2 个参数不是列表(Array),则它必须是文字(string)或数字,用以表征该组多行消息逐行首部的缩进配置。又,若该值是文字值,则沿用;若该值是数字,且等效整数值(取 Math.ceil)大于等于 3 ,则代表逐行首部的缩进是有如数连续空格组成。若该值确是数字,但等效整数值小于等于 2 ,则本工具故意在控制台中给出警告,且逐行缩进配置采用默认值(应为连续 4 个空格)。
还应注意到,不允许利用第 1 个参数表征逐行缩进配置。即不允许在给出【消息逐行缩进】配置时,却省略了【消息等级】指示。因为,若接口那般设计,须知【消息等级】和【消息逐行缩进】都是可以采用数字值的,于是使用者(应为程序员们)容易搞混、搞错。
综上所述,【多行消息机】的接口描述略显复杂。实际使用反而显得较为简单。若以 Typescript 描述其接口,如下:
function logGroup (logLevelOfTheseMessages: T_XmeLogLevel , /* | */ indentation: string | number , /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void; function logGroup (logLevelOfTheseMessages: T_XmeLogLevel , /* | */ /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void; function logGroup ( /* | */ /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void; function logGroup ( firstArg: T_XmeLogLevel | Array<any> | (() => Array<Array<any>>), /* | */ secondArg: string | number | Array<any> | (() => Array<Array<any>>), /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void { /* 实现细节从略。 */ }
调用参数表(依次)
- 从略。参阅上文。
返回值,无。
示例若干:
import { createXmeLoggers, } from '@xinmier/loggers' const xmeLoggers = createXmeLoggers('核心模块', 3) const value = true /** * 第 1 个参数是数字(本例为 5),代表本次打印的消息等级为该数字。 */ xmeLoggers.logWithIndetation(5, [ '第', 1, '行', '的', '内容', '。' ], [ '第 2 行的完整内容。' ], [ '第三行', 'value =', value, ',value 应该是【真】,假不了。' ] ) /** * 第 1 个参数是数字(本例为 2),代表本次打印的消息等级为该数字。 * 第 2 个参数是文本(本例为 '\t\t'),代表本次打印的消息(应有 3 行),每行首部均有 2 个 “制表符(tab)” 。 */ xmeLoggers.logWithIndetation(2, '\t\t', [ '第', 1, '行', '的', '内容', '。' ], [ '第 2 行的完整内容。' ], [ '第三行', 'value =', value, ',value 应该是【真】,假不了。' ] ) /** * 省略了表征【消息等级】的数字, * 也省略了表征【消息逐行缩进】的文字配置, * * 故, * - 本例的消息等级取默认值 3 。 * - 本例的逐行首部缩进取默认值 4 ,即连续 4 个空格。 */ xmeLoggers.logWithIndetation( [ '第', 1, '行', '的', '内容', '。' ], [ '第 2 行的完整内容。' ], [ '第三行', 'value =', value, ',value 应该是【真】,假不了。' ] )
工厂函数产出的对象中的
warn
函数它是所谓〖警告类〗的【通用消息机】。它用于取代
console.warn
。warn
函数的调用参数表(依次)- 一切参数均将原封不动的传递给 `console.warn` 。
返回值,无。
工厂函数产出的对象中的
warnGroup
函数它是所谓〖警告类〗的【多行消息机】。它用于取代
console.warn
。为了实现一次调用打印多行消息,且为了免去本工具的使用者(即是程序员们)反复添加或拼接换行符(
'\n'
), 【多行消息机】要求一切【消息】均存放在列表(Array)中,每行【消息】一个列表,多行【消息】多个列表。 具体而言,【多行消息机】对给出的每个列表都调用一次console.warn
,多个列表则调用多次。 于某个列表,其一切成员将原封不动的传递给对应的console.warn
。若以 Typescript 描述其接口,如下:
function warnGroup (indentation: string | number , /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void; function warnGroup ( /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void; function warnGroup ( firstArg: string | number | Array<any> | (() => Array<Array<any>>), /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void { /* 实现细节从略。 /* }
warnGroup
函数的调用参数表(依次)- 从略。参阅上文。
返回值,无。
工厂函数产出的对象中的
error
函数它是所谓〖报错类〗的【通用消息机】。它用于取代
console.error
。error
函数的调用参数表(依次)- 一切参数均将原封不动的传递给 `console.error` 。
返回值,无。
工厂函数产出的对象中的
errorGroup
函数它是所谓〖报错类〗的【多行消息机】。它用于取代
console.error
。为了实现一次调用打印多行消息,且为了免去本工具的使用者(即是程序员们)反复添加或拼接换行符(
'\n'
), 【多行消息机】要求一切【消息】均存放在列表(Array)中,每行【消息】一个列表,多行【消息】多个列表。 具体而言,【多行消息机】对给出的每个列表都调用一次console.error
,多个列表则调用多次。 于某个列表,其一切成员将原封不动的传递给对应的console.error
。function errorGroup (indentation: string | number , /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void; function errorGroup ( /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void; function errorGroup ( firstArg: string | number | Array<any> | (() => Array<Array<any>>), /* | */ ...messageLines_Or_MessageLinesGenerators: Array<Array<any> | (() => Array<Array<any>>)>): void { /* 实现细节从略。 */ }
errorGroup
函数的调用参数表(依次)- 从略。参阅上文。
返回值,无。
工厂函数产出的对象中的
shouldLogLevel
函数它是所谓〖日志类〗【消息】的【等级裁决函数】。形制如下:
type T_XmeLogger_LogLevelTriageFunction = (logLevelOfSomeMessage: T_XmeLogLevel) => boolean;
shouldLogLevel
函数的调用参数表(依次)logLevelToCheck: T_XmeLogLevel
返回值,
boolean
。
用法(面向本工具的设计者和维护者)
暂无。