@creejs/commons-logging
Version:
Common Utils About Logging
1,425 lines (1,281 loc) • 37.5 kB
JavaScript
var u={isFunction:c,isNumber:m,isNil:y,isString:N};function c(t){return "function"==typeof t}function y(t){return null==t}function m(t){return null!=t&&"number"==typeof t}function N(t){return null!=t&&"string"==typeof t}var C={assertNotNil:V,assertString:M};function M(t,r){if(!N(t))throw new Error(`${r?'"'+r+'" ':""}Not String: type=${typeof t} value=${Z(t)}`)}function V(t,r){if(y(t))throw new Error((r?'"'+r+'" ':"")+"Should Not Nil")}function Z(t){if(null===t)return "null";if(void 0===t)return "undefined";let r;try{r=JSON.stringify(t);}catch(e){r=t.toString();}return r}new TextDecoder;new TextEncoder;
const { isNumber, isString } = u;
/**
* @namespace LogLevel
* @description Defines the logging levels and provides utilities for working with them.
*/
// module vars
const TRACE = 'TRACE';
const DEBUG = 'DEBUG';
const INFO = 'INFO';
const WARN = 'WARN';
const ERROR = 'ERROR';
const FATAL = 'FATAL';
const OFF = 'OFF';
const ALL = 'ALL';
const Names = new Set([TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF, ALL]);
/**
* The logging level numbers, where OFF=-1, FATAL=0, ERROR=1, WARN=2, INFO=3, DEBUG=4, TRACE=5, ALL=6
* @enum {number}
* @memberof LogLevel
* @static
*/
const Level$1 = {
OFF: -1,
FATAL: 0,
ERROR: 1,
WARN: 2,
INFO: 3,
DEBUG: 4,
TRACE: 5,
ALL: 6
};
/**
* Standard logging level names
* @enum {string}
* @memberof LogLevel
* @static
* @constant
*/
const Name = {
TRACE,
DEBUG,
INFO,
WARN,
ERROR,
FATAL,
OFF
};
/**
* Internal map for quick lookup of level names by their numeric values
* @type {Map<number, string>}
* @private
*/
const Value2Name = new Map();
for (const [name, value] of Object.entries(Level$1)) {
Value2Name.set(value, name);
}
/**
* The default logging level (ERROR)
* @type {number}
* @memberof LogLevel
* @static
*/
const DefaultLevel$1 = Level$1.ERROR;
/**
* Converts a numeric logging level value to its corresponding name.
* @param {number} value - The numeric logging level value to convert.
* @returns {string|undefined} The name associated with the given logging level value, from {@link LogLevel.Name}.
* @memberof LogLevel
* @static
*/
function value2Name (value) {
if (!isNumber(value)) {
return undefined
}
return Value2Name.get(value)
}
/**
* Converts a logging level name to its corresponding numeric value.
* @param {string} name - The name of the logging level.
* @returns {number|undefined} The numeric value of the logging level from {@link LogLevel.Level}, or undefined if name is not supported.
* @memberof LogLevel
* @static
*/
function name2Value (name) {
if (!isString(name)) {
return undefined
}
// @ts-ignore
return Level$1[name.toUpperCase()]
}
/**
* Checks if the given level is a valid log level.
* @param {number} level - The log level to check.
* @returns {boolean} True if the level is valid, false otherwise.
* @memberof LogLevel
* @static
*/
function hasLevel (level) {
return Value2Name.has(level)
}
/**
* Checks if the given level name exists in the Name enum/object.
* @param {string} levelName - The name of the log level to check.
* @returns {boolean} True if the level name exists, false otherwise.
* @memberof LogLevel
* @static
*/
function hasName (levelName) {
if (!isString(levelName)) {
return false
}
return Names.has(levelName.toUpperCase())
}
/**
* Validates that a given level is a number and falls within the valid range.
* @param {*} level - The log level to validate
* @throws {Error} If level is not a number or outside valid range (Level.OFF to Level.ALL)
* @memberof LogLevel
* @static
*/
function assertLevel$1 (level) {
if (!isNumber(level)) {
throw new Error(`Level Not Number: type=${typeof level} value=${level}`)
}
if (level < Level$1.OFF || level > Level$1.ALL) {
throw new Error(`Not Valid Level: ${level}, Expect between ${Level$1.OFF} and ${Level$1.ALL}`)
}
}
const LogLevel = {
Name,
Level: Level$1,
DefaultLevel: DefaultLevel$1,
hasLevel,
hasName,
assertLevel: assertLevel$1,
/**
* Same with [Name]{@link LogLevel.Name}
* @type {Object}
* @memberof LogLevel
* @static
*/
LevelName: Name,
/**
* Same with [Level]{@link LogLevel.Level}
* @type {Object}
* @memberof LogLevel
* @static
*/
LevelValue: Level$1,
value2Name,
name2Value
};
// internal
const { Level, DefaultLevel, assertLevel } = LogLevel;
const { assertString: assertString$3 } = C;
/**
* Abstract Logger Class of All Logger
* @abstract
*/
class Logger {
/**
* Creates a new Logger instance.
* @constructor
* @param {string} name - The name identifier for the logger
* @param {*} [nativeLogger]
* @param {number} [level] - The logging level, default is Level.ERROR=1
*/
constructor (name, nativeLogger, level = DefaultLevel) {
assertString$3(name);
assertLevel(level);
this._name = name;
this._nativeLogger = nativeLogger;
this._level = level;
}
get nativeLogger () {
return this._nativeLogger
}
get level () {
return this._level
}
/**
* Gets the name of the logger instance.
* @returns {string} The name of the logger.
*/
get name () {
return this._name
}
/**
* Checks if FATAL level logging is enabled for this logger.
* @returns {boolean} True if FATAL level logging is enabled, false otherwise.
*/
get fatalEnabled () {
return this.level >= Level.FATAL
}
/**
* Checks if ERROR level logging is enabled for this logger.
* @returns {boolean} True if ERROR level logging is enabled, false otherwise.
*/
get errorEnabled () {
return this.level >= Level.ERROR
}
/**
* Checks if WARN level logging is enabled for this logger.
* @returns {boolean} True if WARN level logging is enabled, false otherwise.
*/
get warnEnabled () {
return this.level >= Level.WARN
}
/**
* Checks if DEBUG level logging is enabled for this logger.
* @returns {boolean} True if DEBUG level logging is enabled, false otherwise.
*/
get debugEnabled () {
return this.level >= Level.DEBUG
}
/**
* Checks if INFO level logging is enabled for this logger.
* @returns {boolean} True if INFO level logging is enabled, false otherwise.
*/
get infoEnabled () {
return this.level >= Level.INFO
}
/**
* Checks if TRACE level logging is enabled for this logger.
* @returns {boolean} True if TRACE level logging is enabled, false otherwise.
*/
get traceEnabled () {
return this.level >= Level.TRACE
}
/**
* change log level for current logger instance.
* @param {number} level - new log level to set
* @throws {Error} Currently throws an error as this method is Not Impled Yet.
* @abstract
*/
setLevel (level) {
LogLevel.assertLevel(level);
this._setLevel(level);
this._level = level;
}
/**
* Logs a fatal error message with timestamp and logger name.
* Only outputs if fatal logging is enabled for this logger instance.
* @param {...any} args - Arguments to log (will be space-separated)
*/
fatal (...args) {
if (this.fatalEnabled) {
this._fatal(...args);
}
}
/**
* Logs an error message to the console with timestamp and logger name.
* Only logs if error logging is enabled for this logger instance.
* @param {...any} args - Arguments to be logged as error message
*/
error (...args) {
if (this.errorEnabled) {
this._error(...args);
}
}
/**
* Logs a warning message to the console if warn logging is enabled.
* @param {...any} args - The arguments to log as a warning message.
*/
warn (...args) {
if (this.warnEnabled) {
this._warn(...args);
}
}
/**
* Logs debug messages to console if debug mode is enabled.
* @param {...any} args - The data to be logged
*/
debug (...args) {
if (this.debugEnabled) {
this._debug(...args);
}
}
/**
* Logs an info message to the console with timestamp and logger name.
* @param {...any} args - The data to be logged. Accepts multiple arguments.
*/
info (...args) {
if (this.infoEnabled) {
this._info(...args);
}
}
/**
* Logs a trace message with timestamp and logger name if trace logging is enabled.
* @param {...any} args - Data to be logged as trace message.
*/
trace (...args) {
if (this.traceEnabled) {
this._trace(...args);
}
}
/**
* Checks if FATAL level logging is enabled for this logger.
* @returns {boolean} True if FATAL level logging is enabled, false otherwise.
*/
isFatalEnabled () {
return this.fatalEnabled
}
/**
* Checks if ERROR level logging is enabled for this logger.
* @returns {boolean} True if ERROR level logging is enabled, false otherwise.
*/
isErrorEnabled () {
return this.errorEnabled
}
/**
* Checks if WARN level logging is enabled for this logger.
* @returns {boolean} True if WARN level logging is enabled, false otherwise.
*/
isWarnEnabled () {
return this.warnEnabled
}
/**
* Checks if DEBUG level logging is enabled for this logger.
* @returns {boolean} True if DEBUG level logging is enabled, false otherwise.
*/
isDebugEnabled () {
return this.debugEnabled
}
/**
* Checks if INFO level logging is enabled for this logger.
* @returns {boolean} True if INFO level logging is enabled, false otherwise.
*/
isInfoEnabled () {
return this.infoEnabled
}
/**
* Checks if TRACE level logging is enabled for this logger.
* @returns {boolean} True if TRACE level logging is enabled, false otherwise.
*/
isTraceEnabled () {
return this.traceEnabled
}
/**
* Sets the logging level
* @param {number} level
* @throws {Error} Always throws "Not Impled Yet Yet" error.
* @protected
* @abstract
*/
_setLevel (level) {
throw new Error('Not Impled Yet')
}
/**
* Override this method to implement fatal logging.
* @protected
* @param {...*} args - Variable arguments
* @throws {Error} Always throws "Not Impled Yet Yet" error
*/
_fatal (...args) {
throw new Error('Not Impled Yet')
}
/**
* Override this method to implement error logging.
* @protected
* @param {...*} args - Variable arguments
* @throws {Error} Always throws "Not Impled Yet Yet" error
*/
_error (...args) {
throw new Error('Not Impled Yet')
}
/**
* Override this method to implement warn logging.
* @protected
* @param {...*} args - Variable arguments
* @throws {Error} Always throws "Not Impled Yet Yet" error
*/
_warn (...args) {
throw new Error('Not Impled Yet')
}
/**
* Override this method to implement debug logging.
* @protected
* @param {...*} args - Variable arguments
* @throws {Error} Always throws "Not Impled Yet Yet" error
*/
_debug (...args) {
throw new Error('Not Impled Yet')
}
/**
* Override this method to implement info logging.
* @protected
* @param {...*} args - Variable arguments
* @throws {Error} Always throws "Not Impled Yet Yet" error
*/
_info (...args) {
throw new Error('Not Impled Yet')
}
/**
* Override this method to implement trace logging.
* @protected
* @param {...*} args - Variable arguments
* @throws {Error} Always throws "Not Impled Yet Yet" error
*/
_trace (...args) {
throw new Error('Not Impled Yet')
}
}
// owned
// eslint-disable-next-line no-unused-vars
/**
* @abstract
*/
class LogFactory {
/**
* Checks if a value resembles a LogFactory by verifying it has required methods.
* @param {*} value - The value to check
* @returns {boolean}
*/
static isLogFactoryLike (value) {
if (value == null) {
return false
}
return typeof value === 'object' && typeof value.createLogger === 'function' && typeof value.setLevel === 'function'
}
/**
* Asserts that the given value is a valid LogFactory-Like object.
* @throws {Error} Throws an error if the value is not LogFactory-Like
* @param {*} value - The value to check.
*/
static assertLogFactoryLike (value) {
if (!this.isLogFactoryLike(value)) {
throw new Error('Not LogFactory')
}
}
/**
* Creates a new logging provider instance.
* @param {{}} libraryModule - the library module
* @param {{}} setting - Configuration settings for the provider
*/
constructor (libraryModule, setting) {
this._libraryModule = libraryModule;
this._setting = setting;
}
get libraryModule () {
return this._libraryModule
}
get setting () {
return this._setting
}
/**
* Initializes the logging provider.
* 1. Do nothing in the default implementation.
* 2. Override this method to initialize the provider.
* @returns {Promise<void>|void}
*/
init () {
// do nothing
}
/**
* Update factory's Log Level
* 1. Only Provider knows how to update
* * update level in "setting", so the new created Logger will use the new level
* 2. called when users want to change global log level via CommonsLogging.setLevel()
* @param {number} level - The log level to set, see {@link LogLevel.Level}
* @returns {void}
* @throws {Error} Throws an error as this method is Not Impled Yet.
* @abstract
*/
setLevel (level) {
throw new Error('Not Impled Yet')
}
/**
* Creates a new logger named with the "loggerName"
* @param {string} loggerName - The name to associate with the logger instance.
* @throws {Error} Throws an error indicating the method is Not Impled Yet yet.
* @returns {Logger} A new logger intance
* @abstract
*/
createLogger (loggerName) {
throw new Error('Not Impled Yet')
}
}
/**
* @type {string}
* @memberof ProviderType
*/
const Log4js = 'LOG4JS';
/**
* @type {string}
* @memberof ProviderType
*/
const Console = 'CONSOLE';
/**
* @namespace ProviderType
* @description Define the static types
*/
var ProviderType = {
Log4js,
Console
};
// owned
// eslint-disable-next-line no-unused-vars
/**
* A interface that All Provider module must export
* @interface
*/
class Provider {
/**
* Checks if a value resembles a logging provider by verifying it has required methods.
* @param {*} value - The value to check
* @returns {boolean}
*/
static isProviderLike (value) {
if (value == null) {
return false
}
return typeof value === 'object' && typeof value.createLogFactory === 'function' && typeof value.getType === 'function'
}
/**
* Asserts that the given value is a valid provider-like object.
* @throws {Error} Throws an error if the value is not provider-like.
* @param {*} value - The value to check.
*/
static assertProviderLike (value) {
if (!this.isProviderLike(value)) {
throw new Error('Not LogProvider')
}
}
/**
* The Type Name of current Provider
* @return {String} The type of the provider.
*/
getType () {
throw new Error('Not Impled Yet')
}
/**
* Create a new LogFactory instance
* @param {*} [nativeLib] - The native library to use for logging.
* @param {*} [setting] - Configuration settings for the logging provider.
* @returns {LogFactory} A new instance of LogFactory.
*/
createLogFactory (nativeLib, setting) {
throw new Error('Not Impled Yet')
}
}
// internal
const { assertString: assertString$2 } = C;
/**
* @module LogConfig
* @description Provide Impl of Log Configuration
* @private
*/
/**
* type name of current provider
* @type {string}
* @public
*/
// @ts-ignore
// eslint-disable-next-line prefer-const
let currentProvider$1 = null;
/**
* Global logging level
* @type {number}
* @public
*/
// @ts-ignore
// eslint-disable-next-line prefer-const
let currentLevel = DefaultLevel$1;
/**
* The map of registered logging libraries
* @type {Map<string,Provider>}
* @private
*/
const type2Provider = new Map();
/**
* Adds a logging provider for the specified type.
* @param {string} typeName - The type identifier for the provider.
* @param {Provider} provider - The logging provider implementation.
* @returns {void}
* @alias module:LogConfig.addProvider
*/
function addProvider$1 (typeName, provider) {
assertString$2(typeName);
Provider.assertProviderLike(provider);
type2Provider.set(typeName.toUpperCase(), provider);
}
/**
* Gets the logging provider for the specified type name.
* @param {string} typeName - The type name to look up in the provider map.
* @returns {Provider|undefined} The logging provider instance if found, otherwise undefined.
*/
function getProvider (typeName) {
assertString$2(typeName);
return type2Provider.get(typeName.toUpperCase())
}
/**
* Removes a logging provider of the specified type.
* @param {string} typeName - The type name of the provider to remove.
* @returns {boolean}
*/
function removeProvider$1 (typeName) {
assertString$2(typeName);
return type2Provider.delete(typeName.toUpperCase())
}
function clearProviders$1 () {
type2Provider.clear();
}
/**
* Returns an array of all registered factory types and intances.
* 1. Each entry is a [type, factory] pair
* @returns {Array<{0:string, 1:Provider}>} An array of factory entries.
*/
function listProviders () {
return [...type2Provider.entries()]
}
/**
* Created LogFactories Index with type name
* @type {Map<string, LogFactory>}
* @public
*/
const type2Factory = new Map();
/**
* Registers a log factory for a given type name.
* @param {string} typeName - The name of the log type to register.
* @param {LogFactory} logFactory - Factory function that creates a logger for the specified type.
*/
function addFactory (typeName, logFactory) {
assertString$2(typeName);
LogFactory.assertLogFactoryLike(logFactory);
type2Factory.set(typeName.toUpperCase(), logFactory);
}
/**
* Removes a factory of the given type from the type-to-factory mapping.
* @param {string} typeName - The name of the type whose factory should be removed.
* @returns {boolean}
*/
function removeFactory (typeName) {
assertString$2(typeName);
return type2Factory.delete(typeName.toUpperCase())
}
/**
* Gets the factory function associated with the given type name.
* @param {string} typeName - The name of the type to look up.
* @returns {LogFactory|undefined} The factory function for the specified type.
*/
function getFactory (typeName) {
assertString$2(typeName);
return type2Factory.get(typeName.toUpperCase())
}
/**
* Clears all registered factories from the type2Factory instance.
* This is typically used to reset the factory state during testing or teardown.
*/
function clearFactories () {
type2Factory.clear();
}
/**
* Returns an array of all registered factory types and intances.
* 1. Each entry is a [type, factory] pair
* @returns {Array<{0:string, 1:LogFactory}>} An array of factory entries.
*/
function listFactories () {
return [...type2Factory.entries()]
}
function clear () {
clearProviders$1();
clearFactories();
}
var LogConfig = {
currentProvider: currentProvider$1,
currentLevel,
type2Provider,
type2Factory,
addProvider: addProvider$1,
getProvider,
removeProvider: removeProvider$1,
clearProviders: clearProviders$1,
listProviders,
addFactory,
getFactory,
removeFactory,
clearFactories,
listFactories,
clear
};
// 3rd
// internal
// owned
// module vars
/**
* A Simple Implementation of the Logger interface that logs to the console.
*/
class ConsoleLogger extends Logger {
/**
* Creates a ConsoleLogger instance.
* @constructor
* @param {string} name - The logger name.
* @param {*} nativeLogger - The native console object to use for logging.
* @param {number} level - The initial log level.
*/
constructor (name, nativeLogger, level) {
super(name, nativeLogger, level);
/**
* @type {{error:function, warn:function, debug:function, log:function, info:function, trace:function}}
*/
this.console = nativeLogger;
}
/**
* For ConsoleLogger, Nothing to do
* @param {number} level
* @override
* @protectd
*/
_setLevel (level) {
// do nothing
}
/**
* Logs a fatal error message with timestamp and logger name.
* Only outputs if fatal logging is enabled for this logger instance.
* @param {...any} args
*/
_fatal (...args) {
this.console.error(new Date().toISOString(), this.name, '[Fatal]', ...args);
}
/**
* Logs an error message to the console with timestamp and logger name.
* Only logs if error logging is enabled for this logger instance.
* @param {...any} args
*/
_error (...args) {
this.console.error(new Date().toISOString(), this.name, '[Error]', ...args);
}
/**
* Logs a warning message to the console if warn logging is enabled.
* @param {...any} args
*/
_warn (...args) {
this.console.warn(new Date().toISOString(), this.name, '[Warn]', ...args);
}
/**
* Logs debug messages to console if debug mode is enabled.
* @param {...any} args
*/
_debug (...args) {
this.console.debug(new Date().toISOString(), this.name, '[Debug]', ...args);
}
/**
* Logs an info message to the console with timestamp and logger name.
* @param {...any} args
*/
_info (...args) {
this.console.log(new Date().toISOString(), this.name, '[Info]', ...args);
}
/**
* Logs a trace message with timestamp and logger name if trace logging is enabled.
* @param {...any} args
*/
_trace (...args) {
this.console.log(new Date().toISOString(), this.name, '[Trace]', ...args);
}
}
// owned
// eslint-disable-next-line no-unused-vars
/**
* Use Console as the native library
*/
class ConsoleLogFactory extends LogFactory {
/**
* the underlying "Console" Object.
* @returns {{}}
*/
get console () {
return this._libraryModule // it's the embedded "console" object
}
/**
* Gets the current logging settings
* @returns {{level:number}} The logging settings object containing the current log level.
*/
get setting () {
if (this._setting == null) {
this._setting = {
level: LogConfig.currentLevel
};
}
// @ts-ignore
return this._setting
}
/**
* Update factory's Log Level
* 1. Only Provider knows how to update
* @param {number} level - The log level to set, see {@link LogLevel.Level}
* @returns {void}
* @throws {Error} Throws an error as this method is Not Impled Yet.
* @abstract
*/
setLevel (level) {
assertLevel$1(level);
if (level !== this.setting.level) {
this.setting.level = level;
}
// init again
this.init();
}
/**
* Initializes the log4js provider by configuring it with the provided settings.
* @async
* @override
* @returns {Promise<void>|void}
*/
init () {
// do nothing
}
/**
* Creates a new logger instance with the specified name and log level.
* @param {string} loggerName - The name of the logger to create.
* @returns {Logger} A new logger instance configured with the given name and level.
* @override
*/
createLogger (loggerName) {
return new ConsoleLogger(loggerName, this.console, this.setting.level)
}
}
// owned
class ConsoleProvider extends Provider {
/**
* Gets the provider type (Console).
* @returns {string} "CONSOLE"
* @override
*/
getType () {
return ProviderType.Console
}
/**
* Creates a new Provider instance.
* @param {Object} libraryModule - The library module to be used.
* @param {Object} setting - Configuration settings for the provider.
* @returns {ConsoleLogFactory} A new instance of ConsoleProvider.
* @override
*/
createLogFactory (libraryModule, setting) {
return new ConsoleLogFactory(libraryModule, setting)
}
}
// internal
// module vars
const provider = new ConsoleProvider();
// 3rd
// internal
// owned
// module vars
class Log4jsLogger extends Logger {
/**
* Creates a new ConsoleLogger instance.
* @constructor
* @param {string} name - The name of the logger.
* @param {*} nativeLogger - Log4js library
*/
constructor (name, nativeLogger) {
super(name, nativeLogger);
// @ts-ignore
this._level = undefined; // MUST NOT accept level from outside
this._logger = nativeLogger;
}
/**
* 1. log4js may have many categories(loggerName) with diffirent level
* 2. return the underlying log4js native logger's level
* @returns {number} The current log level.
*/
get level () {
if (this._level == null) {
const levelName = this._logger.level.levelStr;
if (levelName == null) {
return Level$1.OFF
}
const level = name2Value(levelName);
if (level == null) {
throw new Error(`Unknown level name: ${levelName}`)
}
return level
}
return this._level
}
/**
* set log4js native logger's level
* @param {number} level
* @override
* @protectd
*/
_setLevel (level) {
assertLevel$1(level);
const levelName = value2Name(level);
if (levelName == null) {
throw new Error(`Invalid log level: ${level}`)
}
// log4js use string level, eg. 'error, trace'
this._logger.level = levelName.toLowerCase();
}
/**
* Logs a fatal error message with timestamp and logger name.
* Only outputs if fatal logging is enabled for this logger instance.
* @param {...any} args - Arguments to log (will be space-separated)
*/
_fatal (...args) {
this._logger.fatal(...args);
}
/**
* Logs an error message to the console with timestamp and logger name.
* Only logs if error logging is enabled for this logger instance.
* @param {...any} args - Arguments to be logged as error message
*/
_error (...args) {
this._logger.error(...args);
}
/**
* Logs a warning message to the console if warn logging is enabled.
* @param {...any} args - The arguments to log as a warning message.
*/
_warn (...args) {
this._logger.warn(...args);
}
/**
* Logs debug messages to console if debug mode is enabled.
* @param {...any} args - The data to be logged
*/
_debug (...args) {
this._logger.debug(...args);
}
/**
* Logs an info message to the console with timestamp and logger name.
* @param {...any} args - The data to be logged. Accepts multiple arguments.
*/
_info (...args) {
this._logger.info(...args);
}
/**
* Logs a trace message with timestamp and logger name if trace logging is enabled.
* @param {...any} args - Data to be logged as trace message.
*/
_trace (...args) {
this._logger.trace(...args);
}
}
const DefaultConfig = { // 6x fromat
appenders: {
out: { type: 'console' }
},
categories: {
default: { appenders: ['out'], level: 'error' }
}
};
// internal
const { assertString: assertString$1 } = C;
/**
* Use log4js as the logging provider.
*/
class Log4jsFactory extends LogFactory {
/**
* the log4js module instance.
* @returns {{}} The log4js module instance.
*/
get log4js () {
return this._libraryModule
}
get setting () {
if (this._setting == null) {
this._setting = cloneDefaultConfig();
}
return this._setting
}
/**
* Initializes the log4js provider by configuring it with the provided settings.
* @override
*/
init () {
// @ts-ignore
this.log4js.configure(this.setting);
}
/**
* Update factory's Log Level
* 1. Only Provider knows how to update
* @param {number} level - The log level to set, see {@link LogLevel.Level}
* @returns {void}
* @throws {Error} Throws an error as this method is Not Impled Yet.
* @abstract
*/
setLevel (level) {
let levelName = value2Name(level);
if (levelName == null) {
throw new Error(`Invalid log level: ${level}`)
}
levelName = levelName.toLowerCase();
let updated = false;
// @ts-ignore
const { categories } = this.setting;
for (const categoryKey in categories) {
const category = categories[categoryKey];
const { level: categoryLevel } = category;
if (categoryLevel !== levelName) {
category.level = levelName.toLowerCase();
updated = true;
}
}
// init log4js again
updated && this.init();
}
/**
* Creates a new logger instance with the specified name and log level.
* @param {string} loggerName - The name of the logger to create.
* @returns {Logger} A new logger instance configured with the given name and level.
* @override
*/
createLogger (loggerName) {
assertString$1(loggerName);
// @ts-ignore
const nativeLogger = this.log4js.getLogger(loggerName);
const logger = new Log4jsLogger(loggerName, nativeLogger);
return logger
}
}
function cloneDefaultConfig () {
return JSON.parse(JSON.stringify(DefaultConfig))
}
// internal
const { assertNotNil: assertNotNil$1 } = C;
class Log4jsProvider extends Provider {
/**
* Gets the provider type (Log4js).
* @returns {string} "LOG4JS"
* @override
*/
getType () {
return ProviderType.Log4js
}
/**
* Creates a new Provider instance.
* @param {*} libraryModule - The library module to be used.
* @param {*} setting - Configuration settings for the provider.
* @returns {Log4jsFactory} A new instance of Log4jsFactory.
* @override
*/
createLogFactory (libraryModule, setting) {
assertNotNil$1(libraryModule);
const factory = new Log4jsFactory(libraryModule, setting);
factory.init();
return factory
}
}
// internal
// module vars
const log4jsProvider = new Log4jsProvider();
/**
* @module CommonsLogging
* @description Common logging library
*
* Follow the sequence to init log system: addProvider() -> use() -> configure() -> getLogger()
* 1. Add ability to handle the type of library
* * eg. after adding Log4jsProvider, we can use Log4js library
* 2. But we MAY NOT use it now.
* * call useProvider(typeName) to select which kind of LogProvider Implementation to use.
* * call configure(typeName, nativeLib, setting) to LogProvider Implementation
*/
// 3rd
// internal
const { assertNotNil, assertString } = C;
const { isFunction, isNil } = u;
/**
* "default" export to support "import CommonsLogging from '@creejs/commons-logging'"
*/
var index = {
Provider,
LogFactory,
Logger,
LogLevel,
ProviderType,
getLogger,
setLevel,
useProvider,
/**
* alias for {@link CommonsLogging.useProvider}
* @see {@link CommonsLogging.useProvider}
* @function
* @alias module:CommonsLogging.use
*/
use: useProvider,
configureProvider,
/**
* @function
* @alias module:CommonsLogging.confiure
*/
configure: configureProvider,
configureThenUseProvider,
/**
* @function
* @alias module:CommonsLogging.configureThenUseProvider
*/
configureThenUse: configureThenUseProvider,
addProvider,
add: addProvider,
clearProviders,
currentProvider,
/**
* @function
* @alias module:CommonsLogging.current
*/
current: currentProvider,
removeProvider,
/**
* @function
* @alias module:CommonsLogging.remove
*/
remove: removeProvider,
/**
* @alias module:CommonsLogging.ConsoleProvider
*/
ConsoleProvider: provider,
/**
* @alias module:CommonsLogging.Log4jsProvider
*/
Log4jsProvider: log4jsProvider
};
// module vars
/**
* Store Created Loggers, indexed with Names
* @type {Map<string, Logger>}
* @private
*/
const name2Logger = new Map();
/**
* set Global logging level
* @param {'TRACE'|'DEBUG'|'INFO'|'WARN'|'ERROR'|'FATAL'|'OFF'|'trace'|'debug'|'info'|'warn'|'error'|'fatal'|'off'} level - The log level
*/
function setLevel (level) {
assertString(level);
const upperLevel = level.toUpperCase();
const levelNumber = LogLevel.name2Value(upperLevel);
if (levelNumber == null) {
throw new Error(`Invalid log level: ${level}`)
}
if (levelNumber === LogConfig.currentLevel) {
return // no change
}
LogConfig.currentLevel = levelNumber;
// refresh existed factories
// @ts-ignore
// eslint-disable-next-line no-unused-vars
for (const [typeName, factory] of LogConfig.listFactories()) {
factory.setLevel(levelNumber);
}
// refresh existed Loggers
for (const logger of name2Logger.values()) {
if (logger.level !== levelNumber) {
logger.setLevel(levelNumber);
}
}
}
function currentProvider () {
return LogConfig.currentProvider
}
/**
* Set the provider using currently
* @param {string} typeName - The type name of the logging provider to use.
* @returns {void}
* @throws {Error} If the provider name is unknown.
*/
function useProvider (typeName) {
assertString(typeName);
typeName = typeName.toUpperCase();
const provider = LogConfig.getProvider(typeName);
if (provider == null) {
throw new Error(`No Provider Named with: ${typeName}`)
}
LogConfig.currentProvider = typeName;
}
/**
* Removes and returns the provider associated with the given type name.
* If no provider exists for the type name, the function returns undefined.
*
* @param {string} typeName - The type name of the provider to remove.
* @returns {boolean} The removed provider, or undefined if not found.
*/
function removeProvider (typeName) {
if (typeName == null) {
return false
}
assertString(typeName);
typeName = typeName.toUpperCase();
return LogConfig.removeProvider(typeName)
}
/**
* Add a type of Provider
*
* More:
* 1. A Provider is a Module
* 2. The module must include the following functions:
* 1. getType() - Returns the type name of the provider.
* 2. createLogFactory() - Creates a new LogFactory instance.
* @param {Provider} provider - Logging Library Module
* @returns {void}
*/
function addProvider (provider) {
assertNotNil(provider);
const { getType, createLogFactory } = provider;
if (!isFunction(getType) || !isFunction(createLogFactory)) {
throw new Error('Invalid Provider Module, missing getType(), createLogFactory() functions')
}
let typeName = provider.getType();
assertString(typeName);
typeName = typeName.toUpperCase();
LogConfig.addProvider(typeName, provider);
// set current provider if not set yet
if (isNil(currentProvider())) {
useProvider(typeName);
}
}
function clearProviders () {
name2Logger.clear();
LogConfig.clear();
}
/**
* configure provider to initialize its LogFactory
* 1. find the LogProvider Implementation of "typeName"
* * if type is not supported, throw error
* 2. use the nativeLib and setting to initialize the LogProvider
* 3. create a LogFactory via teh LogProvider
* @param {string} typeName - The type of logging provider to configure.
* @param {*} [nativeLib] - The native library to use for logging.
* @param {*} [setting] - Configuration settings for the logging provider.
* @throws {Error} If the typeName is not recognized.
*/
function configureProvider (typeName, nativeLib, setting) {
assertString(typeName);
typeName = typeName.toUpperCase();
const provider = LogConfig.getProvider(typeName);
if (provider == null) {
throw new Error(`No Provider: ${typeName}`)
}
const factory = provider.createLogFactory(nativeLib, setting);
LogConfig.addFactory(typeName, factory);
}
/**
* Configures and immediately uses a logging provider with the given settings.
* @param {string} typeName - The type/name identifier for the provider.
* @param {*} nativeLib - The native library implementation to configure.
* @param {*} setting - Configuration settings for the provider.
*/
function configureThenUseProvider (typeName, nativeLib, setting) {
configureProvider(typeName, nativeLib, setting);
useProvider(typeName);
}
/**
* Gets a logger instance for the specified logger name using the current provider.
* @param {string} loggerName - The name of the logger to retrieve.
* @returns {Logger} The logger instance.
* @throws {Error} If no default provider is set or if the current provider is not initialized.
*/
function getLogger (loggerName) {
// if logger already exists, return it
let logger = name2Logger.get(loggerName);
if (logger != null) {
return logger
}
// create a new logger via the current provider's LogFactory
const currentTypeName = currentProvider();
if (currentTypeName == null) {
throw new Error('No Default LogProvider, call useProvider(typeName)')
}
const factory = LogConfig.getFactory(currentTypeName);
if (factory == null) {
throw new Error('configureProvider(typeName, nativeLib, settting) before getting logger via Provider')
}
logger = factory.createLogger(loggerName);
name2Logger.set(loggerName, logger);
return logger
}
function initLogSystem () {
addProvider(log4jsProvider);
// ConsoleProvider as default impl
addProvider(provider);
configureProvider(ProviderType.Console, console);
useProvider(ProviderType.Console); // Use ConsoleLogger as default
}
initLogSystem();
export { provider as ConsoleProvider, log4jsProvider as Log4jsProvider, LogFactory, LogLevel, Logger, Provider, ProviderType, addProvider as add, addProvider, clearProviders, configureProvider as configure, configureProvider, configureThenUseProvider as configureThenUse, configureThenUseProvider, currentProvider as current, currentProvider, index as default, getLogger, removeProvider as remove, removeProvider, setLevel, useProvider as use, useProvider };
//# sourceMappingURL=index-dev.js.map