2.7.0 • Published 2 years ago

@xinmier/loggers v2.7.0

Weekly downloads
-
License
-
Repository
-
Last release
2 years ago

辛米尔网页编程工具集·控制台消息机集

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.logconsole.debugconsole.warnconsole.error 四者, 但不替代其余诸如 console.infoconsole.group 等。

不妨将【消息机集】携带的 11 个【消息机】分为 3 类:

  1. 〖日志类〗,或称 log 类。共 7 个。均用于替代 console.logconsole.debug 二者。

    凡〖日志类〗【消息】,均是有【消息等级】的。仅符合【等级要求】的〖日志类〗【消息】会打印,其余会被忽略。

  2. 〖警告类〗,或称 warn 类。共 2 个。均用于替代 console.warn

    凡〖警告类〗【消息】均无【等级】。换言之,〖警告类〗【消息】一律打印,不可忽略。

  3. 〖报错类〗,或称 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
  • 运行在浏览器环境的做法:

    1. 先要在命令行环境构建出适合浏览器环境运行的代码。特别是,代码须为 JavaScript 而不是 TypeScript 。故而,请先在命令行环境中执行下方命令:

      npm  run  build-test-of-bench-mark-in-html
    2. 然后,启动一个 Http 服务程序,来伺服 ./测试集 这一文件夹。又,为便于举例,假定你配置的站点为 http://localhost:11094

      你采用 nginx 、 tomcat 、 IIS 之类的工具均可。如果你正在使用 VSCode 这款工具,那么不妨采用 VSCode 的 Expressjs 插件。 本工具之源代码库中的 VSCode 配置文件(settings.json)中已有现成的配置条目。

    3. 打开浏览器,浏览 http://localhost:11094/源/index.html 这一网址。

    4. 按键盘上的 F11 键,或按 Ctrl + Shift + i 组合键,来打开浏览器的“控制台”。在控制台中观察执行结果。

说回函数临时生成内容之细节

尽管采用函数的方法未显见裨益,但仍得以保留。以下是该设计之细节。

为求节省计算之功,本品自 v2.5.0 版始,视所有实参中“直接”给出的函数为所谓【消息内容生成器】。与本品之前的版本不同,在本品之新版中,这些【消息内容生成器】会被调用,而不是被 console.log 之类的原生函数打印出来。调用后,其【返回值】才作为【消息】内容。

所谓 “ 在实参中直接给出 ” ,如何理解?须知,凡诸【消息机】实参中的函数,可能存在于以下“位置”:

  1. 某函数(甲)自身即为【消息机】之某实参。凡此种函数,即是所谓“直接”给出的函数。【消息机】会调用它,并以其返回值作为【消息】内容。
  2. 某函数(甲)为【消息机】之某实参对象(乙)之方法函数。于此情形,【甲】视作【消息】内容的一部分。
  3. 某函数(甲)为【消息机】之某实参列表(Array)(乙)之成员。于此情形,【甲】视作【消息】内容的一部分。
  4. 某函数(甲)为某“直接”给出之函数(乙) 调用 后的【返回值】,或【返回值】的一部分。于此情形,产出的【甲】视作【消息】内容的一部分。

凡视为【消息】内容之部分的函数,【消息机】不会调用它。故而,一旦【消息】之【等级】满足要求,则 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. 调用【工厂函数】时,须给出【等级标准】,或【等级裁决函数】。
  2. 调用〖日志类〗【消息机】来尝试打印【消息】时,须给这条【消息】自身的【等级】。【等级】合规,则该【消息】确实会打印;否则,该【消息】会被忽略。
  3. 〖警告类〗和〖报错类〗【消息】没有所谓【等级】。换言之, 〖警告类〗和〖报错类〗【消息】一律打印。
  4. 凡“直接”作为实参的函数,视作【消息内容生成器】,它们均会被调用。一切产出(即返回值)视作【消息】内容。

为不同模块设计不同的【消息前缀】

当应用程序较复杂时,为了指明消息所隶属的模块,程序员往往会在各消息中设计前缀。特定的模块中的消息,采用特定的、共同的前缀。由此,不同模块打印的消息易于区别、理解。

若运用本工具集,如何做到这一点呢?很简单,分别为每一个模块调用【工厂函数】一次,每次给定不同的消息前缀。即可。见下例。

// 源文件-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 诸接口详解
  1. 主要的【根导出项】为工厂函数 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 枚。

    【乙】的属性(亦即【丙】和【丁】)如下:

    1. 名为 log 的函数,暂称【丙1】。它符合 T_XmeLogger_LogFunction 接口。
    2. 名为 logLevel1 的函数,暂称【丙2】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    3. 名为 logLevel2 的函数,暂称【丙3】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    4. 名为 logLevel3 的函数,暂称【丙4】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    5. 名为 logLevel4 的函数,暂称【丙5】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    6. 名为 logLevel5 的函数,暂称【丙6】。它符合 T_XmeLogger_LogFunction_OfSpecificLevel 接口。
    7. 名为 logGroup 的函数,暂称【丙7】。它符合 T_XmeLogger_LogFunction_MultipleLines 接口。
    8. 名为 warn 的函数,暂称【丙8】。它符合 T_XmeLogger_WarningOrErrorReportingFunction 接口。
    9. 名为 warnGroup 的函数,暂称【丙9】。它符合 T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines 接口。
    10. 名为 error 的函数,暂称【丙10】。它符合 T_XmeLogger_WarningOrErrorReportingFunction 接口。
    11. 名为 errorGroup 的函数,暂称【丙11】。它符合 T_XmeLogger_WarningOrErrorReportingFunction_MultipleLines 接口。
    12. 名为 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)。

        1. 若取函数,则该函数称所谓【等级裁决函数】。在每个〖日志类〗【消息机】的每次调用时,【等级裁决函数】该【消息机】收到的【消息】之【等级】,并决定是否打印该【消息】。具体而言,任何【消息】,凡【等级裁决函数】处理其【等级】后返回 true 者,该【消息】会被打印;反之,若【等级裁决函数】处理其【等级】后返回 false ,则该【消息】会被忽略。
        2. 若取数字,则须在 05 之间,含 0 ,含 5。若取 0 ,代表不打印任何消息;若取值 15 变化,则在控制的可能打印出的消息逐渐增多;反之。特别指出,若取 5 代表打印一切消息。
        3. 若取数字,但不在 05 之间,或取值根本是不数字,也不是函数,则本软件启用幕后预定的所谓“默认值”,即 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;
      }
  1. 工厂函数产出的、符合 T_XmeLogger_CreatedLoggers 接口的对象

    工厂函数产出一个对象,它是所谓【消息机集】。它包含 11 个属性(或者说字段)。这些属性的值全部都是函数。这些函数均称所谓【消息机】。这些【消息机】均可用以代替 console.logconsole.debugconsole.warnconsole.error 四者, 但不替代其余诸如 console.infoconsole.group 等。

  2. 工厂函数产出的对象中的 log 函数

    它是未预设【消息等级】的所谓【通用消息机】。恰因它未预设【消息等级】,调用它时,须在第 1 个参数给出【消息等级】。又,它用于取代 console.logconsole.debug 二者。

    log 函数的调用参数表(依次)

    • 第 1 参数 logLevelOfThisMessage: T_XmeLogLevel 。用以控制本次调用是否真执行 console.logconsole.debug 之一。

      若本参数 小于等于 工厂函数中收到的 allowedLogMaxLevel_Or_LogLevelsTriage ,则本次调用会执行 console.logconsole.debug ;否则,不会调用它们,故不会在控制台有所输出。

      又,若 logLevelOfThisMessage 小于 4 (不等于 4)时,采用 console.log ;否则,采用 console.debug

    • 除第 1 参数之外的一切参数,将原封不动的传递给 console.logconsole.debug

    返回值,无。

  3. 工厂函数产出的对象中的 logLevel1 ~ logLevel5 函数

    它们都是【已预设了消息等级的消息机】。

    它们之任一均可替代 console.logconsole.debug 二者。

    调用参数表(依次)

    • 一切参数均将原封不动的传递给 console.logconsole.debug

    返回值,无。

  1. 工厂函数产出的对象中的 logGroup 函数

    它是【多行消息机】。它用于取代 console.logconsole.debug 二者。

    该函数用以打印多行消息。每行消息的首部可以有相同的缩进。默认的缩进是连续 4 个空格。

    为了实现一次调用打印多行消息,且为了免去本工具的使用者(即是程序员们)反复添加或拼接换行符('\n'), 【多行消息机】要求一切【消息】均存放在列表(Array)中,每行【消息】一个列表,多行【消息】多个列表。 具体而言,【多行消息机】对给出的每个列表都调用一次 console.logconsole.debug ,多个列表则调用多次。 于某个列表,其一切成员将原封不动的传递给对应的 console.logconsole.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 应该是【真】,假不了。' ]
    )
  2. 工厂函数产出的对象中的 warn 函数

    它是所谓〖警告类〗的【通用消息机】。它用于取代 console.warn

    warn 函数的调用参数表(依次)

    -   一切参数均将原封不动的传递给 `console.warn` 。

    返回值,无。

  1. 工厂函数产出的对象中的 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 函数的调用参数表(依次)

    • 从略。参阅上文。

    返回值,无。

  1. 工厂函数产出的对象中的 error 函数

    它是所谓〖报错类〗的【通用消息机】。它用于取代 console.error

    error 函数的调用参数表(依次)

    -   一切参数均将原封不动的传递给 `console.error` 。

    返回值,无。

  1. 工厂函数产出的对象中的 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 函数的调用参数表(依次)

    • 从略。参阅上文。

    返回值,无。

  2. 工厂函数产出的对象中的 shouldLogLevel 函数

    它是所谓〖日志类〗【消息】的【等级裁决函数】。形制如下:

    type T_XmeLogger_LogLevelTriageFunction = (logLevelOfSomeMessage: T_XmeLogLevel) => boolean;

    shouldLogLevel 函数的调用参数表(依次)

    1. logLevelToCheck: T_XmeLogLevel

    返回值,boolean

用法(面向本工具的设计者和维护者)

暂无。

2.7.0

2 years ago

2.6.4

2 years ago

2.6.3

2 years ago

2.6.2

2 years ago

2.6.1

2 years ago

2.6.0

2 years ago

2.5.1

2 years ago

2.5.0

2 years ago

2.0.1

2 years ago

2.0.0

2 years ago

1.1.0

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago

0.3.2

2 years ago

0.3.1

2 years ago

0.3.0

2 years ago

0.2.0

2 years ago