@@ -104,22 +104,27 @@ Logger.prototype.configure = function (options) {
104
104
// Core logging method exposed to Winston. Metadata is optional.
105
105
//
106
106
Logger . prototype . log = function ( level ) {
107
- var self = this ,
108
- args = Array . prototype . slice . call ( arguments , 1 ) ;
107
+ var args = Array . prototype . slice . call ( arguments , 1 ) ,
108
+ self = this ,
109
+ transports ;
109
110
110
- while ( args [ args . length - 1 ] === null ) {
111
+ while ( args [ args . length - 1 ] === null ) {
111
112
args . pop ( ) ;
112
113
}
113
114
115
+ //
116
+ // Determining what is `meta` and what are arguments for string interpolation
117
+ // turns out to be VERY tricky. e.g. in the cases like this:
118
+ //
119
+ // logger.info('No interpolation symbols', 'ok', 'why', { meta: 'is-this' });
120
+ //
114
121
var callback = typeof args [ args . length - 1 ] === 'function' ? args . pop ( ) : null ,
115
122
meta = typeof args [ args . length - 1 ] === 'object' && Object . prototype . toString . call ( args [ args . length - 1 ] ) !== '[object RegExp]' ? args . pop ( ) : { } ,
116
123
msg = util . format . apply ( null , args ) ;
117
124
118
- // If we should pad for levels, do so
119
- if ( this . padLevels ) {
120
- msg = new Array ( this . levelLength - level . length + 1 ) . join ( ' ' ) + msg ;
121
- }
122
-
125
+ //
126
+ // Handle errors appropriately.
127
+ //
123
128
function onError ( err ) {
124
129
if ( callback ) {
125
130
callback ( err ) ;
@@ -129,13 +134,49 @@ Logger.prototype.log = function (level) {
129
134
}
130
135
}
131
136
132
- if ( Object . keys ( this . transports ) . length === 0 ) {
137
+ if ( this . _names . length === 0 ) {
133
138
return onError ( new Error ( 'Cannot log with no transports.' ) ) ;
134
139
}
135
140
else if ( typeof self . levels [ level ] === 'undefined' ) {
136
141
return onError ( new Error ( 'Unknown log level: ' + level ) ) ;
137
142
}
138
143
144
+ //
145
+ // If there are no transports that match the level
146
+ // then be eager and return. This could potentially be calculated
147
+ // during `setLevels` for more performance gains.
148
+ //
149
+ var targets = this . _names . filter ( function ( name ) {
150
+ var transport = self . transports [ name ] ;
151
+ return ( transport . level && self . levels [ transport . level ] >= self . levels [ level ] )
152
+ || ( ! transport . level && self . levels [ self . level ] >= self . levels [ level ] ) ;
153
+ } ) ;
154
+
155
+ if ( ! targets . length ) {
156
+ if ( callback ) { callback ( ) ; }
157
+ return ;
158
+ }
159
+
160
+ //
161
+ // Respond to the callback.
162
+ //
163
+ function finish ( err ) {
164
+ if ( callback ) {
165
+ if ( err ) return callback ( err ) ;
166
+ callback ( null , level , msg , meta ) ;
167
+ }
168
+
169
+ callback = null ;
170
+ if ( ! err ) {
171
+ self . emit ( 'logged' , level , msg , meta ) ;
172
+ }
173
+ }
174
+
175
+ // If we should pad for levels, do so
176
+ if ( this . padLevels ) {
177
+ msg = new Array ( this . levelLength - level . length + 1 ) . join ( ' ' ) + msg ;
178
+ }
179
+
139
180
this . rewriters . forEach ( function ( rewriter ) {
140
181
meta = rewriter ( level , msg , meta , self ) ;
141
182
} ) ;
@@ -165,39 +206,21 @@ Logger.prototype.log = function (level) {
165
206
//
166
207
// Log for each transport and emit 'logging' event
167
208
//
168
- function emit ( name , next ) {
209
+ function transportLog ( name , next ) {
169
210
var transport = self . transports [ name ] ;
170
- if ( ( transport . level && self . levels [ transport . level ] >= self . levels [ level ] )
171
- || ( ! transport . level && self . levels [ self . level ] >= self . levels [ level ] ) ) {
172
- transport . log ( level , msg , meta , function ( err ) {
173
- if ( err ) {
174
- err . transport = transport ;
175
- cb ( err ) ;
176
- return next ( ) ;
177
- }
178
- self . emit ( 'logging' , transport , level , msg , meta ) ;
179
- next ( ) ;
180
- } ) ;
181
- } else {
182
- next ( ) ;
183
- }
184
- }
211
+ transport . log ( level , msg , meta , function ( err ) {
212
+ if ( err ) {
213
+ err . transport = transport ;
214
+ finish ( err ) ;
215
+ return next ( ) ;
216
+ }
185
217
186
- //
187
- // Respond to the callback
188
- //
189
- function cb ( err ) {
190
- if ( callback ) {
191
- if ( err ) return callback ( err ) ;
192
- callback ( null , level , msg , meta ) ;
193
- }
194
- callback = null ;
195
- if ( ! err ) {
196
- self . emit ( 'logged' , level , msg , meta ) ;
197
- }
218
+ self . emit ( 'logging' , transport , level , msg , meta ) ;
219
+ next ( ) ;
220
+ } ) ;
198
221
}
199
222
200
- async . forEach ( this . _names , emit , cb ) ;
223
+ async . forEach ( targets , transportLog , finish ) ;
201
224
return this ;
202
225
} ;
203
226
0 commit comments