/** * @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 deepClone = require('rfdc')({ proto: true }); 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'); const recordingModule = require('./appenders/recording'); 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) { debug(`Loading configuration from ${filename}`); try { return JSON.parse(fs.readFileSync(filename, 'utf8')); } catch (e) { throw new Error( `Problem reading config from file "${filename}". Error was ${e.message}`, e ); } } function configure(configurationFileOrObject) { if (enabled) { // eslint-disable-next-line no-use-before-define shutdown(); } let configObject = configurationFileOrObject; if (typeof configObject === 'string') { configObject = loadConfigurationFile(configurationFileOrObject); } debug(`Configuration is ${configObject}`); configuration.configure(deepClone(configObject)); clustering.onMessage(sendLogEventToAppender); enabled = true; // eslint-disable-next-line no-use-before-define return log4js; } function recording() { return recordingModule; } /** * 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; // Clone out to maintain a reference const appendersToCheck = Array.from(appenders.values()); // Reset immediately to prevent leaks appenders.init(); categories.init(); // Call each of the shutdown functions in parallel const shutdownFunctions = appendersToCheck.reduceRight( (accum, next) => (next.shutdown ? accum + 1 : accum), 0 ); if (shutdownFunctions === 0) { debug('No appenders with shutdown functions found.'); return cb !== undefined && cb(); } 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.'); if (cb) { cb(error); } } } 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, recording, }; module.exports = log4js;