# @creejs/commons-logging
A Common Logging Library:

- **light-weight, No 3rd Dependencies**

  Obey style of commons-logging, Output logs to Console

- **Log4js supported**

  Work with log4js smoothly, No Changes to existed codes

- **use Property to check LogLevel**

  - properties like: logger.errorEnabled, logger.traceEnabled, ...
  - Also Support: logger.isErrorEnabled(), logger.isTraceEnabled(), ...

- **Extensible via Provider mechanism**

  Easy to support more Logging Libraries via adding new Providers



## Install

```shell
npm intall @creejs/commons-logging
```



## Usage

The short examples demostrate some basic usages:

- ##### Embbed Console-Logging

```javascript
const { getLogger } = require('@creejs/commons-logging')

// get or create Logger instance with default level: error
const logger = getLogger('logger1')

// logging, use property to check level
logger.errorEnabled && logger.error('This a', 'test string')
// 2025-07-14T09:28:30.442Z logger1 [Debug] This a test string

// logging, use method to check level
logger.isErrorEnabled() && logger.error('This a', 'test string')
// 2025-07-14T09:28:30.445Z logger1 [Debug] This a test string
```

- ##### Work with Log4js

````javascript
const { ProviderType, configureThenUse, getLogger } = require('@creejs/commons-logging')
const Log4js = require('log4js')

// inject Log4js with default setting: log to Console with Error level
configureThenUse(ProviderType.Log4js, Log4js)

// get or create Logger instance
const logger = getLogger('logger1')

// logging
logger.errorEnabled && logger.error('This a', 'test string')
// 2025-07-14T09:43:21.508Z logger1 [Error] This a test string

logger.isFatalEnabled() && logger.fatal('Another', 'message')
// 2025-07-14T09:43:21.511Z logger1 [Fatal] Another message
````

#### Work with Log4js, use customized settings

```javascript
const { ProviderType, configure, use, getLogger } = require('@creejs/commons-logging')
const Log4js = require('log4js')

const setting = { // log4js 6.x syntax
  appenders: {
    out: { type: 'console' }
  },
  categories: {
    default: { appenders: ['out'], level: 'info' }
  }
}
// inject Log4js with default setting: log to Console with Error level
configure(ProviderType.Log4js, Log4js, setting)
// use log4js as Current Log Provider
use(ProviderType.Log4js)

// get or create Logger instance
const logger = getLogger('logger1')

// logging
logger.errorEnabled && logger.error('log4js error string')
// [2025-07-14T19:37:45.308] [ERROR] logger1 - log4js error string

logger.isInfoEnabled() && logger.info('log4js info string')
// [2025-07-14T19:37:45.312] [INFO] logger1 - log4js info string
```



## Add New Provider

See the Example under **/examples/new-provider**

Add a new Provider to support new Logging Libraries,  the limited  steps should be following:

- Implement the **Provider** Interface
- Implement the **LogFactory** abstract class
- Implement the **Logger** abstract class
- Export a Provider Instance
- Add Provider
- Configure Provider
- Use Provider

##### Implement the **Provider** Interface

The Provider Class:

```javascript
class Provider {
  /**
   * @return {String} The type of the provider.
   */
  getType () {
    throw new Error('Not Impled Yet')
  }

  /**
   * Create a new LogFactory instance 
   * @param {*} [nativeLib] - eg. log4js
   * @param {*} [setting] - eg. log4js' Setting JSON
   * @returns {LogFactory} A new instance of LogFactory.
   */
  createLogFactory (nativeLib, setting) {
    throw new Error('Not Impled Yet')
  }
}
```



##### Implement the **LogFactory** abstract class

```javascript
class LogFactory {
  /**
   * 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}
   * @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')
  }
}
```



##### Implement the Logger abstract class

```javascript
class Logger {
  /**
   * 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')
  }
}
```



##### Export a Provider Instance

Put your Provider, LogFactory, Logger inside one Folder, and export the **new Provider()** inside index.js

```javascript
'user strict'
const YourProvider = require('./provider')

module.exports = new YourProvider()
```

##### Add->Configure->Use Provider

```javascript
const { add, configure, use, getLogger } = require('@creejs/commons-logging')

const newProvider = require('YourProviderModule')

// add your Provider
add(newProvider)
// configure your Provider
configure(newProvider.getType(), ThirdPartLib, yourSetting)
// set your Provider as Default
use(newProvider.getType())
```

