@@ -4,10 +4,6 @@ const logLevel = require('loglevel')
4
4
const chalk = require ( 'chalk' )
5
5
const prefix = require ( 'loglevel-plugin-prefix' )
6
6
7
- const getKeyByValue = ( object , value ) => {
8
- return Object . keys ( object ) . find ( key => object [ key ] === value )
9
- }
10
-
11
7
const colors = Object . freeze ( {
12
8
TRACE : chalk . magenta ,
13
9
DEBUG : chalk . cyan ,
@@ -16,42 +12,91 @@ const colors = Object.freeze({
16
12
ERROR : chalk . red
17
13
} )
18
14
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 ( ) )
29
27
}
30
28
31
- module . exports . levels = logLevel . levels
29
+ const defaultTemplate = '[%t] %l [%n]:'
32
30
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 )
36
54
}
37
55
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 )
40
74
}
41
75
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
49
92
}
93
+ }
50
94
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 )
55
96
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