This commit is contained in:
Erik 2020-04-14 08:47:12 +03:00
commit fc3b124d98
11 changed files with 168 additions and 109 deletions

View File

@ -11,10 +11,9 @@ class Manager extends EventEmitter {
super();
this.shardManager = new ShardManager('./structure/client/DiscordClient.js', options);
this.logger = new Logger(this);
this.storageManager = new StorageManager(this, options.storage)
.initialize();
this.logger = new Logger(this);
this._built = false;

1
logs/error.log Normal file
View File

@ -0,0 +1 @@

View File

@ -1,11 +1,9 @@
const { createLogger, format, transports, config } = require('winston');
const { createLogger, format, transports: { Console }, config } = require('winston');
const { combine, label, printf } = format;
const moment = require('moment');
const chalk = require('chalk');
const { DiscordWebhook, ExtendedConsole } = require('./transports/');
const regex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g //removes chalk formatting, will be used for the log FILES.
const { DiscordWebhook, FileExtension } = require('./transports/');
class Logger {
@ -15,25 +13,32 @@ class Logger {
this.shardManager = manager.shardManager;
this.logger = createLogger({
levels: config.npm.levels,
format: (
format.simple()
format.cli({
colors: {
error: 'red',
warn: 'yellow',
info: 'blue',
verbose: 'cyan',
debug: 'magenta',
silly: 'magentaBright'
}
})
),
transports: [
new ExtendedConsole(),
//new transports.Console(),
new transports.File({ filename: `logs/what.log` }),
new transports.File({ filename: `logs/${this.date.replace(/ /g, '-')}-error.log`, level: 'error' }),
new FileExtension({ filename: `logs/what.log`, level: 'debug'}), //Will NOT log "silly" logs, could change in future.
new FileExtension({ filename: `logs/error.log` , level: 'error' }),
new Console({ level: 'silly' }), //Will log EVERYTHING.
new DiscordWebhook({ level: 'error' }) //Broadcast errors to a discord webhook.
]
});
this.shardManager
.on('shardCreate', (shard) => this.write(shard, "Shard created.", 'debug'))
.on('message', (shard, message) => this._handleMessage(shard, message));
//TODO: Add proper date-oriented filenames and add a daily rotation file (?).
//console.log("FUCK");
this.logger.log('info', "Why tf isnt this working...");
this.logger.log('error', "THERES A FUCKIN ERROR");
this.shardManager
.on('shardCreate', (shard) => this.write('debug', "Shard created.", shard))
.on('message', (shard, message) => this._handleMessage(shard, message));
}
@ -44,21 +49,21 @@ class Logger {
|| message._reconnecting
|| message._sFetchProp
|| message._sEval
|| message._sRespawnAll) return undefined; //Properties used for discord.js internal sharding, must filter for.
|| message._sRespawnAll
|| message._storage
|| message._webhook) return undefined; //Properties used for discord.js internal sharding & our own structures. must filter for.
await this.write(shard, message.message, message.type);
this.write(message.type, message.message, shard);
}
//The MAIN function for writing everything to the logger.
async write(shard, string = '', type = 'silly') {
if(!config.npm.levels[type]) return undefined;
write(type = 'silly', string = '', shard = null) {
const color = Constants.Colors[type];
const header = `[${this.date}][shard-${this._shardId(shard)}]`;//`${chalk[color](`[${this.date}][shard-${this._shardId(shard)}]`)}`;
//[04/02/2020 12:52:20][shard-00]
const header = `${chalk[color](`[${this.date}][${shard ? `shard${this._shardId(shard)}` : 'manager'}]`)}`;
this.logger.log(type, `${header} ${string}`);
this.logger.log(type, `${header} : ${string}`);
}
@ -86,13 +91,12 @@ const Constants = {
}
};
/*
const levels = {
error: 0,
warn: 1,
info: 2,
http: 3,
verbose: 4,
debug: 5,
silly: 6
};*/
// const levels = {
// error: 0,
// warn: 1,
// info: 2,
// http: 3,
// verbose: 4,
// debug: 5,
// silly: 6
// };

View File

@ -1,56 +0,0 @@
const Transport = require('winston-transport');
const moment = require('moment');
const chalk = require('chalk');
const Constants = {
Colors: {
error: 'red',
warn: 'yellow',
info: 'blue',
verbose: 'cyan',
debug: 'magenta',
silly: 'magentaBright'
}
};
class ExtendedConsole extends Transport {
constructor(opts) {
super(opts);
//
// Consume any custom options here. e.g.:
// - Connection information for databases
// - Authentication information for APIs (e.g. loggly, papertrail,
// logentries, etc.).
//
}
log(info, callback) {
setImmediate(() => {
this.emit('logged', info);
});
//console.log('Extended console:');
//console.log(info);
const hdr = info.message.match(/^(\[[0-9\-: ]{19}\](\[shard-[0-9]{2}\])?)/);
if(hdr) info.message = info.message.replace(hdr[1], '').trim();
const color = Constants.Colors[info.level];
const header = `${chalk[color](hdr ? hdr[1] : `[${this.date}]`)}`;
console.log(`${header} ${info.message}`);
if (callback) {
callback(); // eslint-disable-line callback-return
}
}
get date() {
return moment().format("MM-DD-YYYY hh:mm:ss");
}
}
module.exports = ExtendedConsole;

View File

@ -0,0 +1,118 @@
const { transports: { File }} = require('winston');
const debug = require('diagnostics')('winston:file');
const { MESSAGE } = require('triple-beam');
const moment = require('moment');
const chalk = require('chalk');
const regex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g
class FileExtension extends File {
constructor(opts) {
super(opts);
}
log(info, callback = () => {}) {
// Remark: (jcrugzz) What is necessary about this callback(null, true) now
// when thinking about 3.x? Should silent be handled in the base
// TransportStream _write method?
if (this.silent) {
callback();
return true;
}
// Output stream buffer is full and has asked us to wait for the drain event
if (this._drain) {
this._stream.once('drain', () => {
this._drain = false;
this.log(info, callback);
});
return;
}
if (this._rotate) {
this._stream.once('rotate', () => {
this._rotate = false;
this.log(info, callback);
});
return;
}
// Grab the raw string and append the expected EOL.
const output = `${info[MESSAGE]}${this.eol}`.replace(regex, '')
const bytes = Buffer.byteLength(output);
// After we have written to the PassThrough check to see if we need
// to rotate to the next file.
//
// Remark: This gets called too early and does not depict when data
// has been actually flushed to disk.
function logged() {
this._size += bytes;
this._pendingSize -= bytes;
debug('logged %s %s', this._size, output);
this.emit('logged', info);
// Do not attempt to rotate files while opening
if (this._opening) {
return;
}
// Check to see if we need to end the stream and create a new one.
if (!this._needsNewFile()) {
return;
}
// End the current stream, ensure it flushes and create a new one.
// This could potentially be optimized to not run a stat call but its
// the safest way since we are supporting `maxFiles`.
this._rotate = true;
this._endStream(() => this._rotateFile());
}
// Keep track of the pending bytes being written while files are opening
// in order to properly rotate the PassThrough this._stream when the file
// eventually does open.
this._pendingSize += bytes;
if (this._opening
&& !this.rotatedWhileOpening
&& this._needsNewFile(this._size + this._pendingSize)) {
this.rotatedWhileOpening = true;
}
const written = this._stream.write(output, logged.bind(this));
if (!written) {
this._drain = true;
this._stream.once('drain', () => {
this._drain = false;
callback();
});
} else {
callback(); // eslint-disable-line callback-return
}
debug('written', written, this._drain);
this.finishIfEnding();
return written;
}
get date() {
return moment().format("MM-DD-YYYY hh:mm:ss");
}
}
module.exports = FileExtension;
const Constants = {
Colors: {
error: 'red',
warn: 'yellow',
info: 'blue',
verbose: 'cyan',
debug: 'magenta',
silly: 'magentaBright'
}
};

View File

@ -1,5 +1,5 @@
/* eslint-disable linebreak-style */
module.exports = {
DiscordWebhook: require('./DiscordWebhook.js'),
ExtendedConsole: require('./ExtendedConsole.js')
FileExtension: require('./FileExtension.js')
};

View File

@ -6,15 +6,17 @@ class StorageManager {
constructor(manager, options = {}) {
this.providers = new Collection();
this.manager = manager;
this.providers = new Collection();
this.options = options;
}
async initialize() {
console.log('Initiating storage providers');
this.manager.logger.write('debug', "Initializing storage providers.");
let _providers = path.join(process.cwd(), 'storage', 'providers');
let providers = fs.readdirSync(_providers);

View File

@ -32,8 +32,6 @@ class DiscordClient extends Client {
if(this._built) return undefined;
console.log('Building Discord client');
await super.login(this._options.bot.token);
await this.registry.loadComponents('components/commands/', Command);
@ -43,12 +41,6 @@ class DiscordClient extends Client {
this._built = true;
this.on('ready', () => {
console.log('Client websocket is ready.');
});
console.log('Client built');
}

View File

@ -7,7 +7,8 @@ class Logger {
this.client = client;
this.client.eventHooker.hook('ready', () => {
this.info(`Client connected to ${chalk.bold(this.client.user.tag)} with ${chalk.bold(`${this.client.guilds.size} guild${this.client.guilds.size === 1 ? '' : 's'}`)}.`);
const guilds = this.client.guilds.cache.size;
this.info(`Client connected to ${chalk.bold(this.client.user.tag)} with ${chalk.bold(`${guilds} guild${guilds === 1 ? '' : 's'}`)}.`);
});
this.client.eventHooker.hook('componentUpdate', ({ component, type }) => {

View File

@ -23,13 +23,13 @@ class Registry {
for(const path of files) {
const func = require(path);
if(typeof func !== 'function') {
//this.client.logger.error("Attempted to index an invalid function as a component.");
this.client.logger.warn("Attempted to index an invalid function as a component.");
continue;
}
const component = new func(this.client); //Instantiates the component class.
if(classToHandle && !(component instanceof classToHandle)) {
//this.client.logger.error("Attempted to load an invalid class.");
this.client.logger.warn("Attempted to load an invalid class.");
continue;
}
@ -44,12 +44,12 @@ class Registry {
async loadComponent(component, directory) {
if(!(component instanceof Component)) {
//this.client.logger.error("Attempted to load an invalid component.");
this.client.logger.warn("Attempted to load an invalid component.");
return null;
}
if(this.components.has(component.resolveable)) {
//this.client.logger.error("Attempted to reload an existing component.");
this.client.logger.warn("Attempted to reload an existing component.");
return null;
}

View File

@ -95,8 +95,6 @@ class CommandHandler extends Observer {
const parsedArguments = await this._parseArguments(message, args);
}
async _handleInhibitors(message) {