6.0.0-alpha.6 • Published 5 months ago

@guanghechen/chalk-logger v6.0.0-alpha.6

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

chalk-logger is a colorful logger tool based on chalk (so you can use a lot of colors), and can be easily integrated into commander.js (so you can use command line parameters to customized the logger's behavior).

Install

  • npm

    npm install --save @guanghechen/chalk-logger
  • yarn

    yarn add @guanghechen/chalk-logger

Usage

Options

NameTypeRequiredDefaultDesc
basenamestring | nullfalsenullsee below
mode'normal' | 'loose'falsenormalsee below
placeholderRegexRegExpfalse/(?<!\\)\{\}/gstring formatter placeholder regex
namestringfalse-name of logger
levelLevelfalseLevel.INFOverbosity level of the logging output
flightsSee belowfalse-feature flights
write(text: string) => voidfalseprocess.stdoutsee below

Option Details

  • basename: Base of the logger name, when you change logger name according setName function, the basename will be prefixed of the logger name.

  • mode

    • normal: Print log only
    • loose: Print a newline before and after the log
  • flights

    interface ILoggerFlights {
      date?: boolean
      title?: boolean
      inline?: boolean
      colorful?: boolean
    }
    FlightTypeRequiredDefaultDesc
    datebooleanfalsefalsewhether to print the date
    titlebooleanfalsetruewhether to print the title
    inlinebooleanfalsefalsewhether to print each log on one line
    colorfulbooleanfalsetruewhether to print log surrounded with color
  • write: If filepath is specified, the log is output to filepath by default, otherwise to the process.stdout. You can specify your own write function to customize the output behavior of the log.

Cli Options

  • --log-level <debug|verbose|info|warn|error|fatal>: specify global logger level.

  • --log-name <new logger name>: specify global logger name.

  • --log-mode <'normal' | 'loose'>: specify global logger mode.

  • --log-flight <[no-](date|title|inline|colorful)>: the prefix no- represent negation.

    • date: whether to print date. default value is false
    • title: whether to print title. default value is true
    • inline: each log record output in one line. default value is false.
    • colorful: whether to print with colors. default value is true.

Test

Use @guanghechen/helper-jest to spy logger.

import { ChalkLogger, Level } from '@guanghechen/chalk-logger'
import {
  composeStringDesensitizers,
  createFilepathDesensitizer,
  createJsonDesensitizer,
  createLoggerMock,
} from '@guanghechen/helper-jest'

const workspaceRootDir = path.resolve(__dirname, '..')
const desensitize = createJsonDesensitizer({
  string: composeStringDesensitizers(
    createFilepathDesensitizer(workspaceRootDir, '<$WORKSPACE$>'),
    text => text.replace(/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/, '<$Date$>'),
  ),
})

const logger = new ChalkLogger({ name: 'demo', level: Level.DEBUG, flights: { date: true } })
const loggerMock = createLoggerMock({ logger, desensitize })

// collect data
loggerMock.getIndiscriminateAll()

// reset mock
loggerMock.reset()

// restore mock
loggerMock.restore()

Examples

  • Basic:

    // demo/demo1.ts
    import { ChalkLogger, Level } from '@guanghechen/chalk-logger'
    
    const logger = new ChalkLogger(
      {
        name: 'demo1',
        level: Level.ERROR, // the default value is INFO
        flights: {
          date: false, // the default value is false.
          colorful: true, // the default value is true.
        },
      },
      process.argv,
    )
    
    logger.debug('A', 'B', 'C')
    logger.verbose('A', 'B', 'C')
    logger.info('a', 'b', 'c')
    logger.warn('X', 'Y', 'Z', { a: 1, b: 2 })
    logger.error('x', 'y', 'z', { c: { a: 'hello' }, b: { d: 'world' } })
    logger.fatal('1', '2', '3')

    demo1.1.png

  • Custom output format:

    // demo/demo2.ts
    import { ChalkLogger, Level } from '@guanghechen/chalk-logger'
    
    const logger = new ChalkLogger(
      {
        name: 'demo2',
        level: Level.ERROR, // the default value is INFO
        flights: {
          date: false, // the default value is false.
          colorful: true, // the default value is true.
        },
      },
      process.argv,
    )
    
    logger.formatHeader = function formatHeader(level: Level, date: Date): string {
      const dateText: string = this.flights.date
        ? this.formatContent(level, date.toLocaleTimeString())
        : ''
    
      const levelStyle = this.levelStyleMap[level]
      let levelText = levelStyle.title
      if (this.flights.colorful) {
        levelText = levelStyle.labelChalk.fg(levelText)
        if (levelStyle.labelChalk.bg != null) levelText = levelStyle.labelChalk.bg(levelText)
      }
    
      const titleText: string = this.flights.title
        ? this.formatContent(level, '<' + this.name + '>')
        : ''
    
      let result = ''
      if (dateText) result += dateText + ' '
      result += levelText
      if (titleText) result += ' ' + titleText
      return result
    }
    
    logger.debug('A', 'B', 'C')
    logger.verbose('A', 'B', 'C')
    logger.info('a', 'b', 'c')
    logger.warn('X', 'Y', 'Z', { a: 1, b: 2 })
    logger.error('x', 'y', 'z', { c: { a: 'hello' }, b: { d: 'world' } })
    logger.fatal('1', '2', '3')

    demo2.1.png

  • Custom colors with chalk:

    // demo/demo3.ts
    import { ChalkLogger, Level } from '@guanghechen/chalk-logger'
    
    const logger = new ChalkLogger(
      {
        name: 'demo3',
        level: Level.ERROR, // the default value is INFO
        flights: {
          date: false, // the default value is false.
          colorful: true, // the default value is true.
        },
      },
      process.argv,
    )
    
    logger.debug('A', 'B', 'C')
    logger.verbose('A', 'B', 'C')
    logger.info('a', 'b', 'c')
    logger.warn('X', 'Y', 'Z', { a: 1, b: 2 })
    logger.error('x', 'y', 'z', { c: { a: 'hello' }, b: { d: 'world' } })
    logger.fatal('1', '2', '3')

    demo3.1.png

  • Output to file

    // demo/demo4.ts
    import { ChalkLogger, Level } from '@guanghechen/chalk-logger'
    import fs from 'node:fs'
    import path from 'node:path'
    import url from 'node:url'
    
    const __dirname = path.dirname(url.fileURLToPath(import.meta.url))
    
    const logFilepath = path.resolve(__dirname, 'orz.log')
    const logger = new ChalkLogger(
      {
        name: 'demo4',
        level: Level.DEBUG, // the default value is DEBUG
        flights: {
          date: true, // the default value is false.
          inline: true,
          colorful: false, // the default value is true.
        },
        write: text => fs.appendFileSync(logFilepath, text, 'utf-8'),
      },
      process.argv,
    )
    
    logger.debug('A', 'B', 'C')
    logger.verbose('A', 'B', 'C')
    logger.info('a', 'b', 'c')
    logger.warn('X', 'Y', 'Z', { a: 1, b: 2 })
    logger.error('x', 'y', 'z', { c: { a: 'hello' }, b: { d: 'world' } })
    logger.fatal('1', '2', '3')

    demo4.1.png

  • With commander.js:

    // demo/demo5.ts
    import { ChalkLogger, Level, registerCommanderOptions } from '@guanghechen/chalk-logger'
    import { Command } from 'commander'
    
    const logger = new ChalkLogger(
      {
        name: 'demo5',
        level: Level.ERROR, // the default value is INFO
        flights: {
          date: false, // the default value is false.
          colorful: true, // the default value is true.
        },
      },
      process.argv,
    )
    
    const command = new Command()
    command.version('v1.0.0').arguments('[orz]')
    
    // register logger option to commander
    registerCommanderOptions(command)
    
    command.option('-e, --encoding <encoding>', "specified <filepath>'s encoding").parse(process.argv)
    
    logger.debug('A', 'B', 'C')
    logger.verbose('A', 'B', 'C')
    logger.info('a', 'b', 'c')
    logger.warn('X', 'Y', 'Z', { a: 1, b: 2 })
    logger.error('x', 'y', 'z', { c: { a: 'hello' }, b: { d: 'world' } })
    logger.fatal('1', '2', '3')

    demo5.1.png

  • String format:

    // demo/demo6.ts
    import { ChalkLogger, Level } from '@guanghechen/chalk-logger'
    
    const logger = new ChalkLogger(
      {
        name: 'demo6',
        level: Level.DEBUG,
        flights: {
          date: true,
          colorful: true,
          inline: true,
        },
      },
      process.argv,
    )
    
    logger.verbose('user({})', {
      username: 'lemon-clown',
      avatar:
        'https://avatars0.githubusercontent.com/u/42513619?s=400&u=d878f4532bb5749979e18f3696b8985b90e9f78b&v=4',
    })
    logger.error('bad argument ({}). error({})', { username: 123 }, new Error('username is invalid'))
    
    const logger2 = new ChalkLogger(
      {
        name: 'demo6',
        level: Level.DEBUG,
        flights: {
          date: true,
          colorful: true,
          inline: true,
        },
        placeholderRegex: /(?<!\\)<>/g, // change placeholder of string format
      },
      process.argv,
    )
    
    logger2.verbose('user(<>)', {
      username: 'lemon-clown',
      avatar:
        'https://avatars0.githubusercontent.com/u/42513619?s=400&u=d878f4532bb5749979e18f3696b8985b90e9f78b&v=4',
    })
    logger2.error('bad argument (<>). error({})', { username: 123 }, new Error('username is invalid'))

    demo6.1.png

  • No title:

    // demo/demo7.ts
    import { ChalkLogger, Level } from '@guanghechen/chalk-logger'
    
    const logger = new ChalkLogger(
      {
        name: 'demo7',
        level: Level.DEBUG,
        flights: {
          date: true,
          title: false,
          colorful: true,
          inline: true,
        },
      },
      process.argv,
    )
    
    logger.debug('A', 'B', 'C')
    logger.verbose('A', 'B', 'C')
    logger.info('a', 'b', 'c')
    logger.warn('X', 'Y', 'Z', { a: 1, b: 2 })
    logger.error('x', 'y', 'z', { c: { a: 'hello' }, b: { d: 'world' } })
    logger.fatal('1', '2', '3')
    
    const logger2 = new ChalkLogger(
      {
        name: 'demo7',
        level: Level.DEBUG,
        flights: {
          date: false,
          title: false,
          colorful: true,
          inline: true,
        },
        placeholderRegex: /(?<!\\)<>/g, // change placeholder of string format
      },
      process.argv,
    )
    
    logger2.debug('A', 'B', 'C')
    logger2.verbose('A', 'B', 'C')
    logger2.info('a', 'b', 'c')
    logger2.warn('X', 'Y', 'Z', { a: 1, b: 2 })
    logger2.error('x', 'y', 'z', { c: { a: 'hello' }, b: { d: 'world' } })
    logger2.fatal('1', '2', '3')

    demo7.1.png

6.0.0-alpha.6

5 months ago

6.0.0-alpha.5

5 months ago

6.0.0-alpha.3

6 months ago

6.0.0-alpha.4

5 months ago

6.0.0-alpha.0

6 months ago

6.0.0-alpha.1

6 months ago

6.0.0-alpha.2

6 months ago

5.0.9

7 months ago

5.0.8

7 months ago

5.0.7

8 months ago

5.0.6

9 months ago

5.0.5

9 months ago

5.0.4

9 months ago

5.0.3

10 months ago

5.0.2

10 months ago

5.0.0-alpha.3

1 year ago

5.0.0-alpha.2

1 year ago

5.0.1

12 months ago

5.0.0

12 months ago

4.7.2

1 year ago

4.7.1

1 year ago

4.7.4

1 year ago

4.7.3

1 year ago

5.0.0-alpha.1

1 year ago

5.0.0-alpha.0

1 year ago

4.0.0-alpha.7

1 year ago

4.0.0-alpha.8

1 year ago

4.0.0-alpha.5

1 year ago

4.0.0-alpha.6

1 year ago

4.0.0-alpha.3

1 year ago

4.0.0-alpha.4

1 year ago

4.0.0-alpha.1

1 year ago

4.0.0-alpha.2

1 year ago

4.0.0-alpha.0

1 year ago

4.4.1

1 year ago

4.4.0

1 year ago

4.2.2

1 year ago

4.6.1

1 year ago

4.4.3

1 year ago

4.6.0

1 year ago

4.4.2

1 year ago

4.0.0

1 year ago

4.2.1

1 year ago

4.2.0

1 year ago

4.6.3

1 year ago

4.6.2

1 year ago

4.6.5

1 year ago

4.6.4

1 year ago

4.5.0

1 year ago

4.1.3

1 year ago

4.7.0

1 year ago

4.1.0

1 year ago

4.3.0

1 year ago

4.1.2

1 year ago

4.1.1

1 year ago

3.0.0-alpha.1

1 year ago

3.0.0-alpha.0

1 year ago

3.0.0-alpha.3

1 year ago

3.0.0-alpha.2

1 year ago

3.0.0-alpha.5

1 year ago

3.0.0-alpha.4

1 year ago

3.0.2

1 year ago

3.0.1

1 year ago

3.0.0

1 year ago

2.1.2

2 years ago

2.1.1

2 years ago

2.1.4

2 years ago

2.1.3

2 years ago

2.0.0-alpha.3

2 years ago

2.0.0-alpha.2

2 years ago

2.1.0

2 years ago

2.0.0

2 years ago

2.0.0-alpha.0

2 years ago

2.0.0-alpha.1

2 years ago

1.9.8

2 years ago

1.9.7

2 years ago

1.9.6

2 years ago

1.9.5

2 years ago

1.9.0-alpha.0

2 years ago

1.9.1

2 years ago

1.9.0

2 years ago

1.8.6

2 years ago

1.9.4

2 years ago

1.9.3

2 years ago

1.9.2

2 years ago

1.8.5

2 years ago

1.8.4

3 years ago

1.8.3

3 years ago

1.8.2

3 years ago

1.8.1

3 years ago

1.8.0

3 years ago

1.7.1

3 years ago

1.7.0

3 years ago

1.7.0-alpha.3

3 years ago

1.7.0-alpha.2

3 years ago

1.7.0-alpha.1

3 years ago

1.7.0-alpha.0

3 years ago