UNPKG

@soinlabs/hawk

Version:

Package to better manage errors, logs, and its notifications

226 lines (206 loc) 5.17 kB
const FileWriter = require('./FileWriter.js') const { IncomingWebhook } = require('@slack/webhook') const os = require('os') const axios = require('axios') /** * Class Logger to log messages in files */ class Logger { static ERROR = 'error' static WARN = 'warn' static INFO = 'info' static HTTP = 'http' static VERBOSE = 'verbose' static DEBUG = 'debug' static SILLY = 'silly' /** * Class constructor * @param {JSON object} options - Json with path and slackToken property */ constructor(options) { if (options) { this.path = null this.setReferenceCode(options.referenceCode) this.setPath(options.path) this.slackToken = options.slackToken !== undefined ? options.slackToken : null if (options.maxsize) this.setMaxSize(options.maxsize) if (options.maxfiles) this.setMaxFiles(options.maxfiles) if (options.datepattern) this.setDatePattern(options.datepattern) } this.fileWriter = new FileWriter( this.referenceCode, this.path, this.maxsize, this.maxfiles, this.datepattern ) } /** * Set path value * @param {String} path */ setPath(path) { if (this.isTestEnvironment()) { // console.warn("You are using Hawk in test environment mode"); this.path = os.tmpdir() } else if (path !== null && path !== undefined) { this.path = path } } /** * Cheks if app is running on test mode * @param {String} env environment */ isTestEnvironment() { const env = process.env.HAWK_ENV_MODE || process.env.ENV_VARS || process.env.NODE_ENV return ( env !== undefined && env !== null && (env === 'test' || env === 'testing' || env.match(/^(testing)(.)*/i)) ) } /** * Set slackToken value * @param {String} slackToken */ setSlackToken(slackToken) { this.slackToken = slackToken } /** * Set maxsize value * @param {String} maxsize */ setMaxSize(maxsize) { this.maxsize = maxsize } /** * Set maxfiles value * @param {String} maxfiles */ setMaxFiles(maxfiles) { this.maxfiles = maxfiles } /** * Set datepattern value * @param {String} datepattern */ setDatePattern(datepattern) { this.datepattern = datepattern } /** * Set referenceCode value * @param {String} referenceCode */ setReferenceCode(referenceCode) { this.referenceCode = referenceCode } /** * Decide the operation to do with log * @param {JSON object} log * @param {String} level */ log(log, level) { this._validate(log.message) let info = this._setValues(level, log) const cleanLog = this._clearLog(log) if (info.toLog === true || info.toElastic === true) { this._writeLog(info.logLevel, cleanLog, info.toElastic) } if (info.toSlack === true) { this._sendSlackMessage(`${this.referenceCode}: ${log.message}`) } if (info.toEmail === true) { this._sendEmail(`${this.referenceCode}: ${log.message}`) } } /** * Calls fileWriter to write the log in file * @param {string} level * @param {JSON Object} log * @param {boolean} toElastic */ _writeLog(level, log, toElastic) { log.level = level if (toElastic === false) log.type = 'LOG' this.fileWriter.write(log) } /** * Send Slack message * @param {string} message */ async _sendSlackMessage(message) { const url = this.slackToken const webhook = new IncomingWebhook(url) await webhook.send({ text: message, }) } async _sendEmail(options) { const bodyMailData = { sendTo: options.to, data: { subject: options.subject, body: options.message, }, type: 'email', } if (options.isText) { bodyMailData.data.type = 'text' } else { bodyMailData.data.type = 'html' } const requestOptions = { method: 'POST', uri: options.url, headers: { 'application-token': options.token, originurl: options.originurl, }, body: bodyMailData, } await axios(requestOptions) } /** * remove properties that don't need to be logged * @param {JSON Object} log * @returns - log */ _clearLog(log) { delete log.toLog delete log.toElastic delete log.toSlack return log } /** * Set default values if the property doesnt exist * in log * @param {String} level * @param {JSON Object} log * @returns */ _setValues(level, log) { let info = {} info.toLog = log.toLog || true info.toSlack = log.toSlack || false info.toElastic = log.toElastic || false info.logLevel = level || 'info' info.toEmail = log.toEmail || false info.emailOptions = log.emailOptions || {} return info } /** * Validate if path and message were provided * @param {String} message */ _validate(message) { if (this.path === undefined || this.path === null) { throw new Error('path was not defined') } if (message === undefined || !message) { throw new Error('message was not defined') } } } module.exports = Logger