console_logger.js

const chalk = require('chalk')
const SysLogger = require('ain2')

/**
 * Interface some coloured terminal logging and syslog on Linux.
 *
 * Provides four types of logs:
 * <ul>
 *     <li><b>info (blue)</b>       - operational messages that require no action</li>
 *     <li><b>log (yellow)</b>      - useful information (in terms of debugging for instance)</li>
 *     <li><b>warn (magenta)</b>    - do not stops the execution but have the potential to</li>
 *     <li><b>error (red)</b>       - errors that are stopping some operational flow</li>
 * </ul>
 *
 * Provides an option to use <a href="https://en.wikipedia.org/wiki/Syslog">syslog</a> - print to systems log.
 * This was tested on <code>Ubuntu 16.04</code>.
 * To enable this, open <code>/etc/rsyslog.conf</code> and enable <i>UDP</i> on port <i>514</i>.
 * This is usually just commented and needs uncommenting:
 * <pre>
 *     # provides UDP syslog reception
 *     module(load="imudp")
 *     input(type="imudp" port="514")
 * </pre>
 * ... and restart the service with <code>./etc/init.d/rsyslog restart</code>.
 * The logs should appear in <code>/var/log/syslog</code>.
 *
 * To control the logging, use environmental variables:
 * <ul>
 *     <li><code>DBTRC_SYSLOG_F</code> set to <code>OK</code> to enable syslog logging
 *     <pre>
 *         DBTRC_SYSLOG_F=OK node ...
 *     </pre>
 *     </li>
 *     <li><code>DBTRC_TERM_F</code> set to <code>OK</code> to enable terminal logging
 *     <pre>
 *         DBTRC_TERM_F=OK node ...
 *     </pre>
 *     </li>
 * </ul>
 */
class ConsoleLogger {
  /**
   * @param {string} moduleName  the name of the module - something to represent the instance
   */
  constructor (moduleName) {
    this._module_name = moduleName.toString() || ''
    this._sysLogger = null
    this._terminalWriteEnabled = (
      Object.prototype.hasOwnProperty.call(process.env, 'DBTRC_TERM_F') &&
      process.env.DBTRC_TERM_F === 'OK'
    )

    if (
      Object.prototype.hasOwnProperty.call(process.env, 'DBTRC_SYSLOG_F') &&
      process.env.DBTRC_SYSLOG_F === 'OK'
    ) {
      this._sysLogger = new SysLogger()
    }
  }

  /**
   * Do the actual logging.
   * @param {string} loggerType
   * @param {string} message
   * @private
   */
  _thisLogger (loggerType, message) {
    if (this._sysLogger) {
      this._sysLogger[loggerType]('[' + this._module_name + '] ' + message.toString())
    }

    if (!this._terminalWriteEnabled) {
      return
    }

    let typeChalk = 'blue'
    switch (loggerType.toLowerCase()) {
      case 'error':
        typeChalk = 'red'
        break
      case 'warn':
        typeChalk = 'magenta'
        break
      case 'log':
        typeChalk = 'yellow'
        break
      default:
        break
    }

    console.log(chalk.bold[typeChalk]('[' + this._module_name + '] ') + message.toString())
  }

  /**
   * Produce an error message.
   * @param {string} logMessage
   */
  error (logMessage) {
    this._thisLogger('error', logMessage)
  }

  /**
   * Produce a info message.
   * @param {string} logMessage
   */
  info (logMessage) {
    this._thisLogger('info', logMessage)
  }

  /**
   * Produce a warning message.
   * @param {string} logMessage
   */
  warn (logMessage) {
    this._thisLogger('warn', logMessage)
  }

  /**
   * Produce a log message.
   * @param {string} logMessage
   */
  log (logMessage) {
    this._thisLogger('log', logMessage)
  }
}

module.exports = ConsoleLogger