@@ -4,10 +4,6 @@ const logLevel = require('loglevel')
44const chalk = require ( 'chalk' )
55const prefix = require ( 'loglevel-plugin-prefix' )
66
7- const getKeyByValue = ( object , value ) => {
8- return Object . keys ( object ) . find ( key => object [ key ] === value )
9- }
10-
117const colors = Object . freeze ( {
128 TRACE : chalk . magenta ,
139 DEBUG : chalk . cyan ,
@@ -16,42 +12,91 @@ const colors = Object.freeze({
1612 ERROR : chalk . red
1713} )
1814
19- const logConfiguration = {
20- // template: '[%t] %l %n:',
21- format ( level , name , timestamp ) {
22- return `${ chalk . gray ( `[${ timestamp } ]` ) } ${ colors [ level . toUpperCase ( ) ] ( level ) } ${ chalk . green ( `${ name } :` ) } `
23- } ,
24- timestampFormatter : ( ) => {
25- const tzOffset = ( new Date ( ) ) . getTimezoneOffset ( ) * 60000 // offset in milliseconds
26- const localISOTime = ( new Date ( Date . now ( ) - tzOffset ) ) . toISOString ( ) . slice ( 0 , - 1 ) // => '2015-01-26T06:40:36.181'
27- return localISOTime
28- }
15+ const defaultTimestampFormatter = ( date ) => {
16+ const tzOffset = date . getTimezoneOffset ( ) * 60000 // offset in milliseconds
17+ const localISOTime = ( new Date ( date - tzOffset ) ) . toISOString ( ) . slice ( 0 , - 1 ) // => '2015-01-26T06:40:36.181'
18+ return localISOTime
19+ }
20+
21+ const defaultNameFormatter = ( name ) => {
22+ return chalk . green ( name )
23+ }
24+
25+ const defaultLevelFormatter = ( level ) => {
26+ return colors [ level . toUpperCase ( ) ] ( level . toUpperCase ( ) )
2927}
3028
31- module . exports . levels = logLevel . levels
29+ const defaultTemplate = '[%t] %l [%n]:'
3230
33- module . exports . monkLog = ( { name = '' , level = logLevel . levels . DEBUG , wrap = [ '[' , ']' ] } = { } ) => {
34- if ( ! Array . isArray ( wrap ) ) {
35- wrap = [ '[' , ']' ]
31+ // "Nice" default options, they make log lines like:
32+ // [2019-02-18T00:37:56.007] WARN [root]: This is a warning message
33+ // With colored log level, according to serverity.
34+ const defaultLogLevelOptions = {
35+ levelFormatter : defaultLevelFormatter ,
36+ timestampFormatter : defaultTimestampFormatter ,
37+ nameFormatter : defaultNameFormatter ,
38+ template : defaultTemplate ,
39+ }
40+
41+ const _loggersByName = { }
42+
43+ /**
44+ * Subclass of loglevel's Logger,
45+ * Preset to use loglevel-plugin-prefix with some nice default options.
46+ * Can obtain child loggers by calling .getLogger, they will inherit
47+ * parent's options.
48+ */
49+ class MonkLogger extends logLevel . constructor {
50+ constructor ( name , level , options ) {
51+ super ( name , level )
52+ this . options = { ...defaultLogLevelOptions }
53+ this . configure ( options )
3654 }
3755
38- if ( wrap . length !== 2 ) {
39- throw new Error ( `Wrong wrap params, expected 2 got ${ wrap . length } elements` )
56+ /**
57+ * Configure the logger, accepts all loglevel-plugin-prefix options
58+ * and the loglevel (`level` key).
59+ *
60+ * @param {object } options - new option values to update
61+ * @param {boolean } [reset=false] - if false (the default), it will keep
62+ * and update current options (e.g. options inherited from parents or
63+ * a previous call to configure). When true, if will first reset options
64+ * to default ones, and then update with supplied ones.
65+ * Therefore, you can use .configure({}, true) to completely reset
66+ * options to defaults.
67+ */
68+ configure ( options , reset = false ) {
69+ this . options = {
70+ ...( reset ? defaultLogLevelOptions : this . options ) ,
71+ ...options ,
72+ }
73+ prefix . apply ( this , this . options )
4074 }
4175
42- let logger
43- if ( name ) {
44- name = `${ wrap [ 0 ] } ${ name } ${ wrap [ 1 ] } `
45- logger = logLevel . getLogger ( name )
46- } else {
47- // root name is nasty
48- logger = logLevel . getLogger ( 'monk-log' )
76+ /**
77+ *
78+ * @param {string } name - child logger name
79+ * @param {string } level - only output log messages of at least this level
80+ * @param {object } options - loglevel-plugin-prefix options
81+ */
82+ getLogger ( name , level , options ) {
83+ if ( typeof name !== "string" || name === "" ) {
84+ throw new TypeError ( "You must supply a name when creating a logger." )
85+ }
86+ let logger = _loggersByName [ name ]
87+ if ( ! logger ) {
88+ logger = _loggersByName [ name ] = new MonkLogger (
89+ name , level , { ...this . options , ...options } )
90+ }
91+ return logger
4992 }
93+ }
5094
51- prefix . reg ( logLevel )
52- prefix . apply ( logger , logConfiguration )
53- logger . setLevel ( level )
54- logger . info ( `Set log level to ${ getKeyByValue ( logger . levels , level ) } ` )
95+ prefix . reg ( logLevel )
5596
56- return logger
57- }
97+ const defaultLogger = new MonkLogger ( 'root' )
98+ defaultLogger . getLoggers = ( ) => _loggersByName
99+
100+ // Export default logger. Can be used directly, or can be used
101+ // to obtain child loggers.
102+ module . exports = defaultLogger
0 commit comments