diff --git a/src/structure/components/observers/CommandHandler.js b/src/structure/components/observers/CommandHandler.js index 5bc13f5..6d8319e 100644 --- a/src/structure/components/observers/CommandHandler.js +++ b/src/structure/components/observers/CommandHandler.js @@ -129,12 +129,15 @@ class CommandHandler extends Observer { async _executeCommand(invoker, options) { let response = null; + const now = Date.now(); try { response = await invoker.command.execute(invoker, options); + invoker.command.success(now); } catch (error) { if (error instanceof CommandError) { this._generateError(invoker, { error, type: 'command' }); } else { + invoker.command.error(now); this.logger.error(error.stack || error); this._generateError(invoker, { type: 'commandHandler' }); } diff --git a/src/structure/interfaces/commands/Command.js b/src/structure/interfaces/commands/Command.js index c3d096d..c4ee127 100644 --- a/src/structure/interfaces/commands/Command.js +++ b/src/structure/interfaces/commands/Command.js @@ -44,7 +44,9 @@ class Command extends Component { this._invokes = { success: 0, - fail: 0 + successTime: null, + fail: 0, + failTime: null }; this.options = []; @@ -79,6 +81,28 @@ class Command extends Component { throw new Error(`${this.resolveable} is missing an execute function.`); } + success(when) { + const now = Date.now(); + const execTime = now - when; + if (!this._invokes.successTime) { + this._invokes.successTime = execTime; + this._invokes.success++; + } else { // Calculate new average + this._invokes.successTime = (this._invokes.successTime * this._invokes.success + execTime) / ++this._invokes.success; + } + } + + error(when) { + const now = Date.now(); + const execTime = now - when; + if (!this._invokes.failTime) { + this._invokes.failTime = execTime; + this._invokes.fail++; + } else { // Calculate new average + this._invokes.failTime = (this._invokes.failTime * this._invokes.fail + execTime) / ++this._invokes.fail; + } + } + usageEmbed(invoker, verbose = false) { const fields = [];