From ccc86744eae035523cf3e82e4be4974a81e8acd2 Mon Sep 17 00:00:00 2001 From: noolaan Date: Tue, 14 Apr 2020 02:26:59 -0600 Subject: [PATCH] DiscordWebhook transport & storage barebones --- .gitignore | 2 +- Manager.js | 8 ++ logs/error.log | 1 - logs/what.log | 91 ------------------- middleware/logger/Logger.js | 50 +++------- .../logger/transports/DiscordWebhook.js | 55 +++++++---- storage/StorageManager.js | 27 ++++++ storage/providers/Mongodb.js | 46 ++++++---- structure/client/Logger.js | 2 +- .../components/observers/CommandHandler.js | 3 - 10 files changed, 119 insertions(+), 166 deletions(-) delete mode 100644 logs/error.log delete mode 100644 logs/what.log diff --git a/.gitignore b/.gitignore index 68fa992..5680a88 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ node_modules .vscode yarn-error.log .eslintrc.json -logs/what.log +logs/* \ No newline at end of file diff --git a/Manager.js b/Manager.js index 34b9fc9..942f45a 100644 --- a/Manager.js +++ b/Manager.js @@ -16,9 +16,17 @@ class Manager extends EventEmitter { .initialize(); this._built = false; + + this.shardManager.on('message', this._handleMessage.bind(this)); } + _handleMessage(shard, message) { + if(message._logger) return this.logger._handleMessage(shard, message); + if(message._storage) return this.storageManager._handleStorageRequest(shard, message); + if(message._webhook) return undefined; //todo + } + async build() { await this.shardManager.spawn(); diff --git a/logs/error.log b/logs/error.log deleted file mode 100644 index 8b13789..0000000 --- a/logs/error.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/logs/what.log b/logs/what.log deleted file mode 100644 index d723508..0000000 --- a/logs/what.log +++ /dev/null @@ -1,91 +0,0 @@ - -debug: [04-14-2020 12:17:25][manager] : Initializing storage providers. -debug: [04-14-2020 12:17:25][shard00] : Shard created. -info: [04-14-2020 12:17:25][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:17:25][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:17:25][shard00] : Component observer:commandHandler was loaded. -debug: [04-14-2020 12:17:25][shard01] : Shard created. -info: [04-14-2020 12:17:25][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:20:34][manager] : Initializing storage providers. -debug: [04-14-2020 12:20:34][shard00] : Shard created. -info: [04-14-2020 12:20:35][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:20:35][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:20:35][shard00] : Component observer:commandHandler was loaded. -info: [04-14-2020 12:20:35][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:23:19][manager] : Initializing storage providers. -debug: [04-14-2020 12:23:19][shard00] : Shard created. -info: [04-14-2020 12:23:20][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:23:20][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:23:20][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:23:20][shard00] : Attempted to load an invalid class. -info: [04-14-2020 12:23:20][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:23:42][manager] : Initializing storage providers. -debug: [04-14-2020 12:23:42][shard00] : Shard created. -info: [04-14-2020 12:23:42][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:23:42][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:23:43][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:23:43][shard00] : Attempted to load an invalid class. -info: [04-14-2020 12:23:43][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:24:01][manager] : Initializing storage providers. -debug: [04-14-2020 12:24:01][shard00] : Shard created. -info: [04-14-2020 12:24:02][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:24:02][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:24:02][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:24:02][shard00] : Attempted to load an invalid class. -info: [04-14-2020 12:24:02][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:24:33][manager] : Initializing storage providers. -debug: [04-14-2020 12:24:33][shard00] : Shard created. -info: [04-14-2020 12:24:34][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:24:34][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:24:34][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:24:34][shard00] : Attempted to load an invalid class. -info: [04-14-2020 12:24:34][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:24:51][manager] : Initializing storage providers. -debug: [04-14-2020 12:24:52][shard00] : Shard created. -info: [04-14-2020 12:24:52][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:24:52][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:24:52][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:24:52][shard00] : Attempted to load an invalid class. -info: [04-14-2020 12:24:52][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:25:21][manager] : Initializing storage providers. -debug: [04-14-2020 12:25:21][shard00] : Shard created. -info: [04-14-2020 12:25:22][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:25:22][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:25:22][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:25:22][shard00] : Attempted to load an invalid class: "What". -info: [04-14-2020 12:25:22][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:26:11][manager] : Initializing storage providers. -debug: [04-14-2020 12:26:12][shard00] : Shard created. -debug: [04-14-2020 12:26:23][manager] : Initializing storage providers. -debug: [04-14-2020 12:26:23][shard00] : Shard created. -info: [04-14-2020 12:26:24][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:26:24][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:26:24][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:26:24][shard00] : Attempted to load an invalid class: "What". -info: [04-14-2020 12:26:24][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:26:53][manager] : Initializing storage providers. -debug: [04-14-2020 12:26:53][shard00] : Shard created. -debug: [04-14-2020 12:26:55][manager] : Initializing storage providers. -debug: [04-14-2020 12:26:55][shard00] : Shard created. -debug: [04-14-2020 12:26:57][manager] : Initializing storage providers. -debug: [04-14-2020 12:27:35][manager] : Initializing storage providers. -debug: [04-14-2020 12:27:36][shard00] : Shard created. -info: [04-14-2020 12:27:36][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:27:36][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:27:37][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:27:37][shard00] : Attempted to load an invalid class. -info: [04-14-2020 12:27:37][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:27:37][manager] : Initializing storage providers. -debug: [04-14-2020 12:39:31][manager] : Initializing storage providers. -debug: [04-14-2020 12:39:32][shard00] : Shard created. -info: [04-14-2020 12:39:32][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:39:32][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:39:32][shard00] : Component observer:commandHandler was loaded. -warn: [04-14-2020 12:39:32][shard00] : Attempted to load an invalid class. -info: [04-14-2020 12:39:32][shard00] : Client connected to asfasf#1551 with 1 guild. -debug: [04-14-2020 12:39:51][manager] : Initializing storage providers. -debug: [04-14-2020 12:39:51][shard00] : Shard created. -info: [04-14-2020 12:39:52][shard00] : Component module:utility was loaded. -info: [04-14-2020 12:39:52][shard00] : Component command:ping was loaded. -info: [04-14-2020 12:39:52][shard00] : Component observer:commandHandler was loaded. -info: [04-14-2020 12:39:52][shard00] : Client connected to asfasf#1551 with 1 guild. diff --git a/middleware/logger/Logger.js b/middleware/logger/Logger.js index 52be859..33ff5a8 100644 --- a/middleware/logger/Logger.js +++ b/middleware/logger/Logger.js @@ -3,6 +3,8 @@ const { combine, label, printf } = format; const moment = require('moment'); const chalk = require('chalk'); +const { stripIndents } = require('common-tags'); + const { DiscordWebhook, FileExtension } = require('./transports/'); class Logger { @@ -16,19 +18,12 @@ class Logger { levels: config.npm.levels, format: ( format.cli({ - colors: { - error: 'red', - warn: 'yellow', - info: 'blue', - verbose: 'cyan', - debug: 'magenta', - silly: 'magentaBright' - } + colors: Constants.Colors }) ), transports: [ - 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 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. ] @@ -38,22 +33,6 @@ class Logger { this.shardManager .on('shardCreate', (shard) => this.write('debug', "Shard created.", shard)) - .on('message', (shard, message) => this._handleMessage(shard, message)); - - } - - //Messages coming from the shards process.send functions. - async _handleMessage(shard, message) { - if(message._ready - || message._disconnect - || message._reconnecting - || message._sFetchProp - || message._sEval - || message._sRespawnAll - || message._storage - || message._webhook) return undefined; //Properties used for discord.js internal sharding & our own structures. must filter for. - - this.write(message.type, message.message, shard); } @@ -67,6 +46,13 @@ class Logger { } + //Messages coming from the shards process.send functions. + _handleMessage(shard, message) { + + this.write(message.type, message.message, shard); + + } + _shardId(shard) { const id = shard.id; return `${id}`.length === 1 ? `0${id}` : `${id}`; @@ -89,14 +75,4 @@ const Constants = { debug: 'magenta', silly: 'magentaBright' } -}; - -// const levels = { -// error: 0, -// warn: 1, -// info: 2, -// http: 3, -// verbose: 4, -// debug: 5, -// silly: 6 -// }; \ No newline at end of file +}; \ No newline at end of file diff --git a/middleware/logger/transports/DiscordWebhook.js b/middleware/logger/transports/DiscordWebhook.js index 08a51d2..97c13c7 100644 --- a/middleware/logger/transports/DiscordWebhook.js +++ b/middleware/logger/transports/DiscordWebhook.js @@ -1,24 +1,47 @@ const Transport = require('winston-transport'); +const { WebhookClient } = require('discord.js'); +const { username } = require('os').userInfo(); +const { inspect } = require('util'); + +const options = require('../../../options.json'); + +const regex = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g class DiscordWebhook 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.). - // - } + constructor(opts) { + super(opts); - log(info, callback) { - setImmediate(() => { - this.emit('logged', info); - }); + this.webhookClient = new WebhookClient( + options.logger.webhook.id, + options.logger.webhook.token + ); + } - // Perform the writing to the remote service - callback(); - } + log(info, callback) { + setImmediate(() => { + this.emit('logged', info); + }); + + const message = info.message.replace(regex, '') + .replace(new RegExp(options.bot.token, 'g'), '') + .replace(new RegExp(username, 'g'), ''); + + const developers = ['nolan', 'navy']; + const random = developers[Math.floor(Math.random()*developers.length)]; + + const embed = { + color: 0xe88388, + timestamp: new Date(), + description: `\`\`\`${message}\`\`\``, + footer: { + text: `probably ${random}'s fault` + } + }; + + this.webhookClient.send('', { embeds: [embed] }); + + callback(); + } }; module.exports = DiscordWebhook; \ No newline at end of file diff --git a/storage/StorageManager.js b/storage/StorageManager.js index 1e5bcdd..27836b9 100644 --- a/storage/StorageManager.js +++ b/storage/StorageManager.js @@ -33,6 +33,33 @@ class StorageManager { } + async _handleStorageRequest(shard, message) { + + // vv TO BE GENERATED ON CLIENT vv + //`${shard.id}-${new Date().getTime().toString(36) + + if(!message.provider) return this._send(shard, { error: true, message: "Provider not provided" }); + if(!this.providers.has(message.provider)) return this._send(shard, { error: true, message: `Invalid provider, expected 'mongodb' or 'mariadb', got '${message.provider}'` }); + if(!message.query) return this._send(shard, { error: true, message: `Missing query.` }); + + const response = await this.providers.get(message.provider)._query(message.query); + + if(response.error) { + this.manager.logger.write('error', `Provider ${message.provider} errored: ${response.error.message}`, shard); + return this._send(shard, error); + } + + } + + _send(shard, message) { + shard.send({ + _storage: true, + id: message.id, + error: message.error, + message: message.message + }) + } + } module.exports = StorageManager; \ No newline at end of file diff --git a/storage/providers/Mongodb.js b/storage/providers/Mongodb.js index a17aae2..c69e70d 100644 --- a/storage/providers/Mongodb.js +++ b/storage/providers/Mongodb.js @@ -21,11 +21,11 @@ class MongoDBProvider extends Provider { this.manager.db = await this.client.db(this.config.database); this.db = this.manager.db; this.loaded = true; - // this.manager.logger.print('Database connected.'); + // this.manager.write('info', `Provider ${this.name} connected.`); } catch(err) { - // this.manager.logger.error('Database connection failed!\n' + err); + // this.manager.write('error', `Provider ${this.name} failed to connect.` + err); } @@ -33,23 +33,37 @@ class MongoDBProvider extends Provider { } + _query(query) { + /* + { + type: '', + collection: '', + query: '', + data: { + + } + } + */ + + if(!this[query.type]) return { error: true, message: `Invalid query type, got '${query.type}'` }; + return this[query.type](query); + + + } + /** * Find and return the first match - * - * @param {String} db The collection in which the data is to be updated - * @param {Object} query The filter that is used to find the data - * @returns {Array} An array containing the corresponding objects for the query * @memberof Database */ - find(db, query) { + find({ collection, query }) { //if(this.manager.debug) this.manager.logger.debug(`Incoming find query for ${db} with parameters ${JSON.stringify(query)}`); return new Promise((resolve, reject) => { if(!this.loaded) reject(new Error('MongoDB not connected')); - this.db.collection(db).find(query, async (error, cursor) => { + this.db.collection(collection).find(query, async (error, cursor) => { if(error) return reject(error); return resolve(await cursor.toArray()); @@ -69,14 +83,14 @@ class MongoDBProvider extends Provider { * @memberof Database */ - findOne(db, query) { + findOne({ collection, query }) { //if(this.manager.debug) this.manager.logger.debug(`Incoming findOne query for ${db} with parameters ${JSON.stringify(query)}`); return new Promise((resolve, reject) => { if(!this.loaded) reject(new Error('MongoDB not connected')); - this.db.collection(db).findOne(query, async (error, item) => { + this.db.collection(collection).findOne(query, async (error, item) => { if(error) return reject(error); return resolve(item); @@ -97,14 +111,14 @@ class MongoDBProvider extends Provider { * @returns {WriteResult} Object containing the followint counts: Matched, Upserted, Modified * @memberof Database */ - updateOne(db, query, data, upsert = false) { + updateOne({ collection, query, data, upsert = false }) { //if(this.manager.debug) this.manager.logger.debug(`Incoming updateOne query for ${db} with parameters ${JSON.stringify(filter)}`); return new Promise((resolve, reject) => { if(!this.loaded) reject(new Error('MongoDB not connected')); - this.db.collection(db).updateOne(query, { $set: data }, { upsert: upsert }, async (error, result) => { + this.db.collection(collection).updateOne(query, { $set: data }, { upsert: upsert }, async (error, result) => { if(error) return reject(error); else { @@ -128,14 +142,14 @@ class MongoDBProvider extends Provider { * @returns * @memberof Database */ - push(db, query, data, upsert = false) { + push({ collection, query, data, upsert = false }) { //if(this.manager.debug) this.manager.logger.debug(`Incoming push query for ${db}, with upsert ${upsert} and with parameters ${JSON.stringify(filter)} and data ${JSON.stringify(data)}`); return new Promise((resolve, reject) => { if(!this.loaded) reject(new Error('MongoDB not connected')); - this.db.collection(db).updateOne(query, { $push: data }, { upsert: upsert }, async (error, result) => { + this.db.collection(collection).updateOne(query, { $push: data }, { upsert: upsert }, async (error, result) => { if(error) return reject(error); else return resolve(result); @@ -155,7 +169,7 @@ class MongoDBProvider extends Provider { * @returns {object} * @memberof Database */ - random(db, query = {}, amount = 1) { + random({ collection, query = {}, amount = 1 }) { //if(this.manager.debug) this.manager.logger.debug(`Incoming random query for ${db} with parameters ${JSON.stringify(filter)} and amount ${amount}`); if(amount > 100) amount = 100; @@ -164,7 +178,7 @@ class MongoDBProvider extends Provider { if(!this.loaded) reject(new Error('MongoDB not connected')); - this.db.collection(db).aggregate([{ $match: query }, { $sample: {size: amount}}], function(err, item) { + this.db.collection(collection).aggregate([{ $match: query }, { $sample: {size: amount}}], function(err, item) { if(err) return reject(err); resolve(item); diff --git a/structure/client/Logger.js b/structure/client/Logger.js index 5885d98..5deba47 100644 --- a/structure/client/Logger.js +++ b/structure/client/Logger.js @@ -22,7 +22,7 @@ class Logger { } async transport(message = 'N/A', opts = {}) { - process.send({ message, ...opts }); + process.send({ _logger: true, message, ...opts }); } /* Quick & Dirty Functions */ diff --git a/structure/client/components/observers/CommandHandler.js b/structure/client/components/observers/CommandHandler.js index 5a6c590..9c5f4a1 100644 --- a/structure/client/components/observers/CommandHandler.js +++ b/structure/client/components/observers/CommandHandler.js @@ -135,7 +135,6 @@ class CommandHandler extends Observer { for(let i=0; i 0 && ['INTEGER', 'FLOAT'].includes(currentArgument.type)) { //15 pts - console.log("asgsaiughasiguassag") const lastItem = params[params.length-1]; const beforeError = await this._handleTypeParsing(currentArgument, lastItem); if(beforeError) { @@ -240,7 +238,6 @@ class CommandHandler extends Observer { } } } - }