@creejs/commons-logging
Version:
Common Utils About Logging
1,457 lines (1,310 loc) • 40.9 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.CommonsLang = {}));
})(this, (function (exports) { 'use strict';
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();
exports.ConsoleProvider = provider;
exports.Log4jsProvider = log4jsProvider;
exports.LogFactory = LogFactory;
exports.LogLevel = LogLevel;
exports.Logger = Logger;
exports.Provider = Provider;
exports.ProviderType = ProviderType;
exports.add = addProvider;
exports.addProvider = addProvider;
exports.clearProviders = clearProviders;
exports.configure = configureProvider;
exports.configureProvider = configureProvider;
exports.configureThenUse = configureThenUseProvider;
exports.configureThenUseProvider = configureThenUseProvider;
exports.current = currentProvider;
exports.currentProvider = currentProvider;
exports.default = index;
exports.getLogger = getLogger;
exports.remove = removeProvider;
exports.removeProvider = removeProvider;
exports.setLevel = setLevel;
exports.use = useProvider;
exports.useProvider = useProvider;
Object.defineProperty(exports, '__esModule', { value: true });
}));
//# sourceMappingURL=index.dev.js.map