const { createLogger, format, transports: { Console }, config } = require('winston'); const moment = require('moment'); const chalk = require('chalk'); const { DiscordWebhook, FileExtension } = require('./transports/'); const Constants = { Colors: { error: 'red', warn: 'yellow', info: 'blue', verbose: 'cyan', debug: 'magenta', silly: 'magentaBright' } }; class Logger { constructor(manager) { this.manager = manager; this.shardManager = manager.shardManager; this.logger = createLogger({ levels: config.npm.levels, format: format.cli({ colors: Constants.Colors }), transports: [ new FileExtension({ filename: `logs/${this.date.split(' ')[0]}.log`, level: 'debug' }), //Will NOT log "silly" logs, could change in future. new FileExtension({ filename: `logs/errors/${this.date.split(' ')[0]}-error.log`, level: 'error' }), new Console({ level: 'silly' }), //Will log EVERYTHING. new DiscordWebhook({ level: 'error' }) //Broadcast errors to a discord webhook. ] }); //TODO: Add proper date-oriented filenames and add a daily rotation file (?). this.shardManager .on('shardCreate', (shard) => this.write('info', "Shard created.", shard)); process.on("unhandledRejection", (error) => { this.write('error', `Unhandled promise rejection:\n${error.stack}`); //eslint-disable-line no-console }); } write(type = 'silly', string = '', shard = null, api = false) { const color = Constants.Colors[type]; const header = `${chalk[color](`[${this.date}][${shard ? `${api ? 'api-' : ''}shard${this._shardId(shard)}` : `${api ? 'api-' : ''}manager`}]`)}`; this.logger.log(type, `${header} : ${string}`); } //Messages coming from the shards process.send functions. _handleMessage(shard, message) { this.write(message.type, message.message, shard, message._api); } _shardId(shard) { const { id } = shard; return `${id}`.length === 1 ? `0${id}` : `${id}`; } get date() { return moment().format("YYYY-MM-DD hh:mm:ss"); } } module.exports = Logger;