@soinlabs/hawk
Version:
Package to better manage errors, logs, and its notifications
226 lines (206 loc) • 5.17 kB
JavaScript
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