@@ -12,79 +12,93 @@ const config = require('./config');
12
12
const Logger = require ( './logger' ) ;
13
13
const debug = require ( 'diagnostics' ) ( 'winston:create-logger' ) ;
14
14
15
+ function isLevelEnabledFunctionName ( level ) {
16
+ return 'is' + level . charAt ( 0 ) . toUpperCase ( ) + level . slice ( 1 ) + 'Enabled' ;
17
+ }
18
+
15
19
/**
16
- * DerivedLogger to attach the logs level methods.
17
- * @type {DerivedLogger }
18
- * @extends {Logger }
20
+ * Create a new instance of a winston Logger. Creates a new
21
+ * prototype for each instance.
22
+ * @param {!Object } opts - Options for the created logger.
23
+ * @returns {Logger } - A newly created logger instance.
19
24
*/
20
- class DerivedLogger extends Logger {
25
+ module . exports = function ( opts = { } ) {
26
+ //
27
+ // Default levels: npm
28
+ //
29
+ opts . levels = opts . levels || config . npm . levels ;
30
+
21
31
/**
22
- * Create a new class derived logger for which the levels can be attached to
23
- * the prototype of. This is a V8 optimization that is well know to increase
24
- * performance of prototype functions.
25
- * @param {!Object } options - Options for the created logger.
32
+ * DerivedLogger to attach the logs level methods.
33
+ * @type {DerivedLogger }
34
+ * @extends {Logger }
26
35
*/
27
- constructor ( options ) {
28
- super ( options ) ;
29
- this . _setupLevels ( ) ;
36
+ class DerivedLogger extends Logger {
37
+ /**
38
+ * Create a new class derived logger for which the levels can be attached to
39
+ * the prototype of. This is a V8 optimization that is well know to increase
40
+ * performance of prototype functions.
41
+ * @param {!Object } options - Options for the created logger.
42
+ */
43
+ constructor ( options ) {
44
+ super ( options ) ;
45
+ }
30
46
}
31
47
32
- /**
33
- * Create the log level methods for the derived logger.
34
- * @returns {undefined }
35
- * @private
36
- */
37
- _setupLevels ( ) {
38
- Object . keys ( this . levels ) . forEach ( level => {
39
- debug ( 'Define prototype method for "%s"' , level ) ;
40
- if ( level === 'log' ) {
41
- // eslint-disable-next-line no-console
42
- console . warn ( 'Level "log" not defined: conflicts with the method "log". Use a different level name.' ) ;
43
- return ;
44
- }
48
+ const logger = new DerivedLogger ( opts ) ;
49
+
50
+ //
51
+ // Create the log level methods for the derived logger.
52
+ //
53
+ Object . keys ( opts . levels ) . forEach ( function ( level ) {
54
+ debug ( 'Define prototype method for "%s"' , level ) ;
55
+ if ( level === 'log' ) {
56
+ // eslint-disable-next-line no-console
57
+ console . warn ( 'Level "log" not defined: conflicts with the method "log". Use a different level name.' ) ;
58
+ return ;
59
+ }
45
60
46
- // Define prototype methods for each log level
47
- // e.g. logger.log('info', msg) <––> logger.info(msg) & logger.isInfoEnabled()
48
- // this is not an arrow function so it'll always be called on the instance instead of a fixed place in the prototype chain.
49
- this [ level ] = function ( ... args ) {
50
- // Optimize the hot-path which is the single object.
51
- if ( args . length === 1 ) {
52
- const [ msg ] = args ;
53
- const info = msg && msg . message && msg || { message : msg } ;
54
- info . level = info [ LEVEL ] = level ;
55
- this . _addDefaultMeta ( info ) ;
56
- this . write ( info ) ;
57
- return this ;
58
- }
61
+ //
62
+ // Define prototype methods for each log level e.g.:
63
+ // logger.log('info', msg) implies these methods are defined:
64
+ // - logger.info(msg)
65
+ // - logger.isInfoEnabled()
66
+ //
67
+ // Remark: to support logger.child this **MUST** be a function
68
+ // so it'll always be called on the instance instead of a fixed
69
+ // place in the prototype chain.
70
+ //
71
+ DerivedLogger . prototype [ level ] = function ( ... args ) {
72
+ // Prefer any instance scope, but default to "root" logger
73
+ const self = this || logger ;
59
74
60
- // When provided nothing assume the empty string
61
- if ( args . length === 0 ) {
62
- this . log ( level , '' ) ;
63
- return this ;
64
- }
75
+ // Optimize the hot-path which is the single object.
76
+ if ( args . length === 1 ) {
77
+ const [ msg ] = args ;
78
+ const info = msg && msg . message && msg || { message : msg } ;
79
+ info . level = info [ LEVEL ] = level ;
80
+ self . _addDefaultMeta ( info ) ;
81
+ self . write ( info ) ;
82
+ return ( this || logger ) ;
83
+ }
65
84
66
- // Otherwise build argument list which could potentially conform to
67
- // either:
68
- // . v3 API: log(obj)
69
- // 2. v1/v2 API: log(level, msg, ... [string interpolate], [{metadata}], [callback])
70
- return this . log ( level , ...args ) ;
71
- } ;
85
+ // When provided nothing assume the empty string
86
+ if ( args . length === 0 ) {
87
+ self . log ( level , '' ) ;
88
+ return self ;
89
+ }
72
90
73
- this [ isLevelEnabledFunctionName ( level ) ] = ( ) => this . isLevelEnabled ( level ) ;
74
- } ) ;
75
- }
76
- }
91
+ // Otherwise build argument list which could potentially conform to
92
+ // either:
93
+ // . v3 API: log(obj)
94
+ // 2. v1/v2 API: log(level, msg, ... [string interpolate], [{metadata}], [callback])
95
+ return self . log ( level , ...args ) ;
96
+ } ;
77
97
78
- function isLevelEnabledFunctionName ( level ) {
79
- return 'is' + level . charAt ( 0 ) . toUpperCase ( ) + level . slice ( 1 ) + 'Enabled' ;
80
- }
98
+ DerivedLogger . prototype [ isLevelEnabledFunctionName ( level ) ] = function ( ) {
99
+ return ( this || logger ) . isLevelEnabled ( level ) ;
100
+ } ;
101
+ } ) ;
81
102
82
- /**
83
- * Create a new instance of a winston Logger. Creates a new
84
- * prototype for each instance.
85
- * @param {!Object } opts - Options for the created logger.
86
- * @returns {Logger } - A newly created logger instance.
87
- */
88
- module . exports = ( opts = { levels : config . npm . levels } ) => (
89
- new DerivedLogger ( opts )
90
- ) ;
103
+ return logger ;
104
+ } ;
0 commit comments