@guanghechen/chalk-logger
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
Name | Type | Required | Default | Desc |
---|---|---|---|---|
basename |
string | null
|
false |
null |
see below |
mode |
'normal' | 'loose'
|
false |
normal |
see below |
placeholderRegex |
RegExp | false |
/(?<!\\)\{\}/g |
string formatter placeholder regex |
name |
string | false |
- | name of logger |
level |
Level | false |
Level.INFO |
verbosity level of the logging output |
flights |
See below | false |
- | feature flights |
write |
(text: string) => void | false |
process.stdout |
see below |
Option Details
-
basename
: Base of the logger name, when you change logger name accordingsetName
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 }
Flight Type Required Default Desc date
boolean false
false
whether to print the date title
boolean false
true
whether to print the title inline
boolean false
false
whether to print each log on one line colorful
boolean false
true
whether to print log surrounded with color -
write
: Iffilepath
is specified, the log is output tofilepath
by default, otherwise to theprocess.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 prefixno-
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')
-
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')
-
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')
-
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')
-
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')
-
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'))
-
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')