Bug:Fix file validation issue
[vnfsdk/refrepo.git] / vnfmarket / src / main / webapp / vnfmarket / node_modules / log4js / lib / log4js.js
1 "use strict";
2 /*
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 /**
17  * @fileoverview log4js is a library to log in JavaScript in similar manner
18  * than in log4j for Java. The API should be nearly the same.
19  *
20  * <h3>Example:</h3>
21  * <pre>
22  *  var logging = require('log4js');
23  *  //add an appender that logs all messages to stdout.
24  *  logging.addAppender(logging.consoleAppender());
25  *  //add an appender that logs "some-category" to a file
26  *  logging.addAppender(logging.fileAppender("file.log"), "some-category");
27  *  //get a logger
28  *  var log = logging.getLogger("some-category");
29  *  log.setLevel(logging.levels.TRACE); //set the Level
30  *
31  *  ...
32  *
33  *  //call the log
34  *  log.trace("trace me" );
35  * </pre>
36  *
37  * NOTE: the authors below are the original browser-based log4js authors
38  * don't try to contact them about bugs in this version :)
39  * @version 1.0
40  * @author Stephan Strittmatter - http://jroller.com/page/stritti
41  * @author Seth Chisamore - http://www.chisamore.com
42  * @since 2005-05-20
43  * @static
44  * Website: http://log4js.berlios.de
45  */
46 var events = require('events')
47 , fs = require('fs')
48 , path = require('path')
49 , util = require('util')
50 , layouts = require('./layouts')
51 , levels = require('./levels')
52 , loggerModule = require('./logger')
53 , LoggingEvent = loggerModule.LoggingEvent
54 , Logger = loggerModule.Logger
55 , ALL_CATEGORIES = '[all]'
56 , appenders = {}
57 , loggers = {}
58 , appenderMakers = {}
59 , appenderShutdowns = {}
60 , defaultConfig =   {
61   appenders: [
62     { type: "console" }
63   ],
64   replaceConsole: false
65 };
66
67 require('./appenders/console');
68
69 function hasLogger(logger) {
70   return loggers.hasOwnProperty(logger);
71 }
72
73 levels.forName = function(levelStr, levelVal) {
74   var level;
75   if (typeof levelStr === "string" && typeof levelVal === "number") {
76     var levelUpper = levelStr.toUpperCase();
77     level = new levels.Level(levelVal, levelUpper);
78     loggerModule.addLevelMethods(level);
79   }
80   return level;
81 };
82
83 levels.getLevel = function(levelStr) {
84   var level;
85   if (typeof levelStr === "string") {
86     var levelUpper = levelStr.toUpperCase();
87     level = levels.toLevel(levelStr);
88   }
89   return level;
90 };
91
92 function getBufferedLogger(categoryName) {
93     var base_logger = getLogger(categoryName);
94     var logger = {};
95     logger.temp = [];
96     logger.target = base_logger;
97     logger.flush = function () {
98         for (var i = 0; i < logger.temp.length; i++) {
99             var log = logger.temp[i];
100             logger.target[log.level](log.message);
101             delete logger.temp[i];
102         }
103     };
104     logger.trace = function (message) { logger.temp.push({level: 'trace', message: message}); };
105     logger.debug = function (message) { logger.temp.push({level: 'debug', message: message}); };
106     logger.info = function (message) { logger.temp.push({level: 'info', message: message}); };
107     logger.warn = function (message) { logger.temp.push({level: 'warn', message: message}); };
108     logger.error = function (message) { logger.temp.push({level: 'error', message: message}); };
109     logger.fatal = function (message) { logger.temp.push({level: 'fatal', message: message}); };
110
111     return logger;
112 }
113
114 function normalizeCategory (category) {
115   return  category + '.';
116 }
117
118 function doesLevelEntryContainsLogger (levelCategory, loggerCategory) {  
119   var normalizedLevelCategory = normalizeCategory(levelCategory);
120   var normalizedLoggerCategory = normalizeCategory(loggerCategory);
121   return normalizedLoggerCategory.substring(0, normalizedLevelCategory.length) == normalizedLevelCategory; //jshint ignore:line
122 }
123
124 function doesAppenderContainsLogger (appenderCategory, loggerCategory) {
125   var normalizedAppenderCategory = normalizeCategory(appenderCategory);
126   var normalizedLoggerCategory = normalizeCategory(loggerCategory);
127   return normalizedLoggerCategory.substring(0, normalizedAppenderCategory.length) == normalizedAppenderCategory; //jshint ignore:line
128 }
129
130
131 /**
132  * Get a logger instance. Instance is cached on categoryName level.
133  * @param  {String} categoryName name of category to log to.
134  * @return {Logger} instance of logger for the category
135  * @static
136  */
137 function getLogger (loggerCategoryName) {
138
139   // Use default logger if categoryName is not specified or invalid
140   if (typeof loggerCategoryName !== "string") {
141     loggerCategoryName = Logger.DEFAULT_CATEGORY;
142   }
143
144   if (!hasLogger(loggerCategoryName)) {
145
146     var level;
147
148     /* jshint -W073 */
149     // If there's a "levels" entry in the configuration
150     if (levels.config) {
151       // Goes through the categories in the levels configuration entry,
152       // starting with the "higher" ones.
153       var keys = Object.keys(levels.config).sort();
154       for (var idx = 0; idx < keys.length; idx++) {
155         var levelCategory = keys[idx];
156         if (doesLevelEntryContainsLogger(levelCategory, loggerCategoryName)) {
157           // level for the logger
158           level = levels.config[levelCategory];
159         }
160       }
161     }
162     /* jshint +W073 */
163   
164     // Create the logger for this name if it doesn't already exist
165     loggers[loggerCategoryName] = new Logger(loggerCategoryName, level);
166
167     /* jshint -W083 */
168     var appenderList;
169     for(var appenderCategory in appenders) {
170       if (doesAppenderContainsLogger(appenderCategory, loggerCategoryName)) {
171         appenderList = appenders[appenderCategory];
172         appenderList.forEach(function(appender) {
173           loggers[loggerCategoryName].addListener("log", appender);
174         });
175       }
176     }
177     /* jshint +W083 */
178
179     if (appenders[ALL_CATEGORIES]) {
180       appenderList = appenders[ALL_CATEGORIES];
181       appenderList.forEach(function(appender) {
182         loggers[loggerCategoryName].addListener("log", appender);
183       });
184     }
185   }
186   
187   return loggers[loggerCategoryName];
188 }
189
190 /**
191  * args are appender, then zero or more categories
192  */
193 function addAppender () {
194   var args = Array.prototype.slice.call(arguments);
195   var appender = args.shift();
196   if (args.length === 0 || args[0] === undefined) {
197     args = [ ALL_CATEGORIES ];
198   }
199   //argument may already be an array
200   if (Array.isArray(args[0])) {
201     args = args[0];
202   }
203   
204   args.forEach(function(appenderCategory) {
205     addAppenderToCategory(appender, appenderCategory);
206     
207     if (appenderCategory === ALL_CATEGORIES) {
208       addAppenderToAllLoggers(appender);
209     } else {
210
211       for(var loggerCategory in loggers) {
212         if (doesAppenderContainsLogger(appenderCategory,loggerCategory)) {
213           loggers[loggerCategory].addListener("log", appender);
214         }
215       }
216       
217     }
218   });
219 }
220
221 function addAppenderToAllLoggers(appender) {
222   for (var logger in loggers) {
223     if (hasLogger(logger)) {
224       loggers[logger].addListener("log", appender);
225     }
226   }
227 }
228
229 function addAppenderToCategory(appender, category) {
230   if (!appenders[category]) {
231     appenders[category] = [];
232   }
233   appenders[category].push(appender);
234 }
235
236 function clearAppenders () {
237   appenders = {};
238   for (var logger in loggers) {
239     if (hasLogger(logger)) {
240       loggers[logger].removeAllListeners("log");
241     }
242   }
243 }
244
245 function configureAppenders(appenderList, options) {
246   clearAppenders();
247   if (appenderList) {
248     appenderList.forEach(function(appenderConfig) {
249       loadAppender(appenderConfig.type);
250       var appender;
251       appenderConfig.makers = appenderMakers;
252       try {
253         appender = appenderMakers[appenderConfig.type](appenderConfig, options);
254         addAppender(appender, appenderConfig.category);
255       } catch(e) {
256         throw new Error("log4js configuration problem for " + util.inspect(appenderConfig), e);
257       }
258     });
259   }
260 }
261
262 function configureLevels(_levels) {
263   levels.config = _levels; // Keep it so we can create loggers later using this cfg
264   if (_levels) {
265     var keys = Object.keys(levels.config).sort();
266     for (var idx in keys) {
267       var category = keys[idx];
268       if(category === ALL_CATEGORIES) {
269         setGlobalLogLevel(_levels[category]);
270       }
271       /* jshint -W073 */
272       for(var loggerCategory in loggers) {
273         if (doesLevelEntryContainsLogger(category, loggerCategory)) {
274           loggers[loggerCategory].setLevel(_levels[category]);
275         }
276       }
277       /* jshint +W073 */
278     }
279   }
280 }
281
282 function setGlobalLogLevel(level) {
283   Logger.prototype.level = levels.toLevel(level, levels.TRACE);
284 }
285
286 /**
287  * Get the default logger instance.
288  * @return {Logger} instance of default logger
289  * @static
290  */
291 function getDefaultLogger () {
292   return getLogger(Logger.DEFAULT_CATEGORY);
293 }
294
295 var configState = {};
296
297 function loadConfigurationFile(filename) {
298   if (filename) {
299     return JSON.parse(fs.readFileSync(filename, "utf8"));
300   }
301   return undefined;
302 }
303
304 function configureOnceOff(config, options) {
305   if (config) {
306     try {
307       configureLevels(config.levels);
308       configureAppenders(config.appenders, options);
309       
310       if (config.replaceConsole) {
311         replaceConsole();
312       } else {
313         restoreConsole();
314       }
315     } catch (e) {
316       throw new Error(
317         "Problem reading log4js config " + util.inspect(config) + 
318           ". Error was \"" + e.message + "\" (" + e.stack + ")"
319       );
320     }
321   }
322 }
323
324 function reloadConfiguration(options) {
325   var mtime = getMTime(configState.filename);
326   if (!mtime) return;
327   
328   if (configState.lastMTime && (mtime.getTime() > configState.lastMTime.getTime())) {
329     configureOnceOff(loadConfigurationFile(configState.filename), options);
330   }
331   configState.lastMTime = mtime;
332 }
333
334 function getMTime(filename) {
335   var mtime;
336   try {
337     mtime = fs.statSync(configState.filename).mtime;
338   } catch (e) {
339     getLogger('log4js').warn('Failed to load configuration file ' + filename);
340   }
341   return mtime;
342 }
343
344 function initReloadConfiguration(filename, options) {
345   if (configState.timerId) {
346     clearInterval(configState.timerId);
347     delete configState.timerId;
348   }
349   configState.filename = filename;
350   configState.lastMTime = getMTime(filename);
351   configState.timerId = setInterval(reloadConfiguration, options.reloadSecs*1000, options);
352 }
353
354 function configure(configurationFileOrObject, options) {
355   var config = configurationFileOrObject;
356   config = config || process.env.LOG4JS_CONFIG;
357   options = options || {};
358   
359   if (config === undefined || config === null || typeof(config) === 'string') {
360     if (options.reloadSecs) {
361       initReloadConfiguration(config, options);
362     }
363     config = loadConfigurationFile(config) || defaultConfig;
364   } else {
365     if (options.reloadSecs) {
366       getLogger('log4js').warn(
367         'Ignoring configuration reload parameter for "object" configuration.'
368       );
369     }
370   }
371   configureOnceOff(config, options);
372 }
373
374 var originalConsoleFunctions = {
375   log: console.log,
376   debug: console.debug,
377   info: console.info,
378   warn: console.warn,
379   error: console.error
380 };
381
382 function replaceConsole(logger) {
383   function replaceWith(fn) {
384     return function() {
385       fn.apply(logger, arguments);
386     };
387   }
388   logger = logger || getLogger("console");
389   ['log','debug','info','warn','error'].forEach(function (item) {
390     console[item] = replaceWith(item === 'log' ? logger.info : logger[item]);
391   });
392 }
393
394 function restoreConsole() {
395   ['log', 'debug', 'info', 'warn', 'error'].forEach(function (item) {
396     console[item] = originalConsoleFunctions[item];
397   });
398 }
399
400 /**
401  * Load an appenderModule based on the provided appender filepath. Will first
402  * check if the appender path is a subpath of the log4js "lib/appenders" directory.
403  * If not, it will attempt to load the the appender as complete path.
404  *
405  * @param {string} appender The filepath for the appender.
406  * @returns {Object|null} The required appender or null if appender could not be loaded.
407  * @private
408  */
409 function requireAppender(appender) {
410   var appenderModule;
411   try {
412     appenderModule = require('./appenders/' + appender);
413   } catch (e) {
414     appenderModule = require(appender);
415   }
416   return appenderModule;
417 }
418
419 /**
420  * Load an appender. Provided the appender path to be loaded. If appenderModule is defined,
421  * it will be used in place of requiring the appender module.
422  *
423  * @param {string} appender The path to the appender module.
424  * @param {Object|void} [appenderModule] The pre-required appender module. When provided,
425  * instead of requiring the appender by its path, this object will be used.
426  * @returns {void}
427  * @private
428  */
429 function loadAppender(appender, appenderModule) {
430   appenderModule = appenderModule || requireAppender(appender);
431
432   if (!appenderModule) {
433     throw new Error("Invalid log4js appender: " + util.inspect(appender));
434   }
435
436   module.exports.appenders[appender] = appenderModule.appender.bind(appenderModule);
437   if (appenderModule.shutdown) {
438     appenderShutdowns[appender] = appenderModule.shutdown.bind(appenderModule);
439   }
440   appenderMakers[appender] = appenderModule.configure.bind(appenderModule);
441 }
442
443 /**
444  * Shutdown all log appenders. This will first disable all writing to appenders
445  * and then call the shutdown function each appender.
446  *
447  * @params {Function} cb - The callback to be invoked once all appenders have
448  *  shutdown. If an error occurs, the callback will be given the error object
449  *  as the first argument.
450  * @returns {void}
451  */
452 function shutdown(cb) {
453   // First, disable all writing to appenders. This prevents appenders from
454   // not being able to be drained because of run-away log writes.
455   loggerModule.disableAllLogWrites();
456
457   // Call each of the shutdown functions in parallel
458   var completed = 0;
459   var error;
460   var shutdownFcts = [];
461   var complete = function(err) {
462     error = error || err;
463     completed++;
464     if (completed >= shutdownFcts.length) {
465       cb(error);
466     }
467   };
468   for (var category in appenderShutdowns) {
469     if (appenderShutdowns.hasOwnProperty(category)) {
470       shutdownFcts.push(appenderShutdowns[category]);
471     }
472   }
473   if (!shutdownFcts.length) {
474     return cb();
475   }
476   shutdownFcts.forEach(function(shutdownFct) { shutdownFct(complete); });
477 }
478
479 module.exports = {
480   getBufferedLogger: getBufferedLogger,
481   getLogger: getLogger,
482   getDefaultLogger: getDefaultLogger,
483   hasLogger: hasLogger,
484   
485   addAppender: addAppender,
486   loadAppender: loadAppender,
487   clearAppenders: clearAppenders,
488   configure: configure,
489   shutdown: shutdown,
490   
491   replaceConsole: replaceConsole,
492   restoreConsole: restoreConsole,
493   
494   levels: levels,
495   setGlobalLogLevel: setGlobalLogLevel,
496   
497   layouts: layouts,
498   appenders: {},
499   appenderMakers: appenderMakers,
500   connectLogger: require('./connect-logger').connectLogger
501 };
502
503 //set ourselves up
504 configure();