'use strict'; /** * @fileoverview log4js is a library to log in JavaScript in similar manner * than in log4j for Java (but not really). * *

Example:

*
 *  const logging = require('log4js');
 *  const log = logging.getLogger('some-category');
 *
 *  //call the log
 *  log.trace('trace me' );
 * 
* * NOTE: the authors below are the original browser-based log4js authors * don't try to contact them about bugs in this version :) * @author Stephan Strittmatter - http://jroller.com/page/stritti * @author Seth Chisamore - http://www.chisamore.com * @since 2005-05-20 * Website: http://log4js.berlios.de */ const debug = require('debug')('log4js:main'); const fs = require('fs'); const CircularJSON = require('circular-json'); const configuration = require('./configuration'); const layouts = require('./layouts'); const levels = require('./levels'); const appenders = require('./appenders'); const categories = require('./categories'); const Logger = require('./logger'); const clustering = require('./clustering'); const connectLogger = require('./connect-logger'); let enabled = false; function sendLogEventToAppender(logEvent) { if (!enabled) return; debug('Received log event ', logEvent); const categoryAppenders = categories.appendersForCategory(logEvent.categoryName); categoryAppenders.forEach((appender) => { appender(logEvent); }); } function loadConfigurationFile(filename) { if (filename) { debug(`Loading configuration from ${filename}`); return JSON.parse(fs.readFileSync(filename, 'utf8')); } return filename; } function configure(configurationFileOrObject) { let configObject = configurationFileOrObject; if (typeof configObject === 'string') { configObject = loadConfigurationFile(configurationFileOrObject); } debug(`Configuration is ${configObject}`); // Fix for #743 - clone the config to avoid that is not writable in appenders // When the node-config module is used, config object becomes immutable. const clonedConfigObject = CircularJSON.parse(CircularJSON.stringify(configObject)); configuration.configure(clonedConfigObject); clustering.onMessage(sendLogEventToAppender); enabled = true; return log4js; } /** * Shutdown all log appenders. This will first disable all writing to appenders * and then call the shutdown function each appender. * * @params {Function} cb - The callback to be invoked once all appenders have * shutdown. If an error occurs, the callback will be given the error object * as the first argument. */ function shutdown(cb) { debug('Shutdown called. Disabling all log writing.'); // First, disable all writing to appenders. This prevents appenders from // not being able to be drained because of run-away log writes. enabled = false; // Call each of the shutdown functions in parallel const appendersToCheck = Array.from(appenders.values()); const shutdownFunctions = appendersToCheck.reduceRight((accum, next) => (next.shutdown ? accum + 1 : accum), 0); let completed = 0; let error; debug(`Found ${shutdownFunctions} appenders with shutdown functions.`); function complete(err) { error = error || err; completed += 1; debug(`Appender shutdowns complete: ${completed} / ${shutdownFunctions}`); if (completed >= shutdownFunctions) { debug('All shutdown functions completed.'); cb(error); } } if (shutdownFunctions === 0) { debug('No appenders with shutdown functions found.'); return cb(); } appendersToCheck.filter(a => a.shutdown).forEach(a => a.shutdown(complete)); return null; } /** * Get a logger instance. * @static * @param loggerCategoryName * @return {Logger} instance of logger for the category */ function getLogger(category) { if (!enabled) { configure(process.env.LOG4JS_CONFIG || { appenders: { out: { type: 'stdout' } }, categories: { default: { appenders: ['out'], level: 'OFF' } } }); } return new Logger(category || 'default'); } /** * @name log4js * @namespace Log4js * @property getLogger * @property configure * @property shutdown */ const log4js = { getLogger, configure, shutdown, connectLogger, levels, addLayout: layouts.addLayout }; module.exports = log4js;