forked from Galactic/galactic-bot
203 lines
7.2 KiB
JavaScript
203 lines
7.2 KiB
JavaScript
const { Command } = require('../../../../interfaces/');
|
|
const os = require('os');
|
|
|
|
class StatsCommand extends Command {
|
|
|
|
constructor(client) {
|
|
|
|
super(client, {
|
|
name: 'stats',
|
|
module: 'developer',
|
|
aliases: [
|
|
],
|
|
usage: '',
|
|
restricted: true,
|
|
arguments: [
|
|
{
|
|
name: 'log',
|
|
type: 'BOOLEAN',
|
|
types: ['FLAG'],
|
|
description: 'Logs the output in the console.'
|
|
}
|
|
],
|
|
showUsage: false,
|
|
archivable: false
|
|
});
|
|
|
|
}
|
|
|
|
async execute(message) {
|
|
|
|
// TODO:
|
|
// Add some stuff that only shows when a dev runs the command, for instance amount of cached messages etc
|
|
|
|
const { guild, author } = message;
|
|
const { shard } = this.client;
|
|
|
|
//Shards eval
|
|
const evalFunc = (thisArg) => {
|
|
return {
|
|
users: thisArg.users.cache.size,
|
|
guilds: thisArg.guilds.cache.size,
|
|
channels: thisArg.channels.cache.size,
|
|
memory: Math.floor(process.memoryUsage().heapUsed / 1024 / 1024),
|
|
uptime: thisArg.uptime
|
|
};
|
|
};
|
|
|
|
//Manager eval
|
|
const mEvalFunc = (thisArg) => {
|
|
return {
|
|
memory: Math.floor(process.memoryUsage().heapUsed / 1024 / 1024),
|
|
uptime: Date.now() - thisArg.readyAt
|
|
};
|
|
};
|
|
|
|
const shardResults = await shard.broadcastEval(evalFunc).catch((error) => this.client.logger.error(error));
|
|
const managerResult = await this.client.managerEval(`(${mEvalFunc})(this)`).catch((error) => this.client.logger.error(error));
|
|
|
|
//Current shard
|
|
const mainValues = {
|
|
uptime: this.client.resolver.timeAgo(Math.floor(managerResult.uptime / 1000), true, true, true),
|
|
memory: managerResult.memory,
|
|
shards: shard.count,
|
|
library: require('discord.js').version
|
|
};
|
|
|
|
//All shards combined
|
|
const shardValues = {
|
|
cachedUsers: this.client.users.cache.size,
|
|
guilds: this.client.guilds.cache.size,
|
|
channels: this.client.channels.cache.size,
|
|
uptime: this.client.resolver.timeAgo(Math.floor(this.client.uptime / 1000), true, true, true),
|
|
memory: Math.floor(process.memoryUsage().heapUsed / 1024 / 1024)
|
|
};
|
|
|
|
//Compile shard data
|
|
const totalValues = shardResults.reduce((acc, curr) => {
|
|
Object.entries(curr).forEach(([key, val]) => {
|
|
if (!acc[key]) acc[key] = 0;
|
|
acc[key] += val;
|
|
});
|
|
return acc;
|
|
}, {});
|
|
totalValues.uptime = this.client.resolver.timeAgo(Math.floor(totalValues.uptime / 1000), true, true, true);
|
|
|
|
//System information
|
|
const CPU = os.cpus();
|
|
const memoryFree = (os.freemem() / 1024 / 1024 / 1024).toFixed(1);
|
|
const memoryTotal = (os.totalmem() / 1024 / 1024 / 1024).toFixed(1);
|
|
|
|
const sysInfo = {
|
|
devs: await this.client.resolveUsers(this.client._options.bot.owners).then((owners) => {
|
|
return owners.map((o) => o.tag).join(', ');
|
|
}),
|
|
cpu: CPU[0].model,
|
|
cores: CPU.length,
|
|
memoryUsed: memoryTotal - memoryFree,
|
|
memoryTotal,
|
|
osType: os.type(),
|
|
uptime: this.client.resolver.timeAgo(os.uptime(), true, true, true),
|
|
hostname: os.hostname()
|
|
};
|
|
|
|
//Command statistics - probably expand this further
|
|
const commands = this.client.registry.components.filter((comp) => comp.type === 'command');
|
|
|
|
const commandValues = {
|
|
invokes: commands.reduce((acc, cmd) => acc + cmd._invokes.success + cmd._invokes.fail, 0),
|
|
success: commands.reduce((acc, cmd) => acc + cmd._invokes.success, 0),
|
|
fail: commands.reduce((acc, cmd) => acc + cmd._invokes.fail, 0)
|
|
};
|
|
|
|
const embed = {
|
|
title: message.format('C_STATS_TITLE', {
|
|
client: this.client.user.tag,
|
|
version: require('../../../../../package.json').version
|
|
}),
|
|
description: message.format('C_STATS_SYSTEM_VALUE', sysInfo),
|
|
fields: [
|
|
{
|
|
name: message.format('C_STATS_MAIN'),
|
|
value: message.format('C_STATS_MAIN_VALUE', mainValues),
|
|
inline: true
|
|
},
|
|
{
|
|
name: message.format('C_STATS_CURRENT_SHARD', { shard: guild.shardID }),
|
|
value: message.format('C_STATS_CURRENT_SHARDS_VALUE', shardValues),
|
|
inline: true
|
|
},
|
|
{
|
|
name: message.format('C_STATS_TOTAL'),
|
|
value: message.format('C_STATS_TOTAL_VALUE', totalValues),
|
|
inline: true
|
|
},
|
|
{
|
|
name: message.format('C_STATS_COMMANDS'),
|
|
value: message.format('C_STATS_COMMANDS_VALUE', commandValues),
|
|
inline: true
|
|
}
|
|
]
|
|
};
|
|
|
|
if (author.developer) {
|
|
|
|
//Mongo DB
|
|
const stats = await this.client.storage.mongodb.stats();
|
|
const dbStats = {
|
|
db: stats.db,
|
|
collections: stats.collections,
|
|
objects: stats.objects,
|
|
avgObjSize: (stats.avgObjSize / 1024 / 1024).toFixed(1),
|
|
totalSize: (stats.dataSize / 1024 / 1024 / 1024).toFixed(2)
|
|
};
|
|
|
|
embed.fields.push({
|
|
name: message.format('C_STATS_MONGODB'),
|
|
value: message.format('C_STATS_MONGODB_VALUE', dbStats),
|
|
inline: true
|
|
});
|
|
|
|
//Other
|
|
const evalFunc2 = () => {
|
|
let msg = 0,
|
|
mem = 0;
|
|
// eslint-disable-next-line no-return-assign
|
|
this.channels.cache.forEach((c) => {
|
|
msg += c.messages?.cache.size || 0
|
|
});
|
|
this.guilds.cache.forEach((g) => {
|
|
mem += g.members.cache.size
|
|
})
|
|
return {
|
|
cachedMessages: msg,
|
|
cachedMembers: mem
|
|
};
|
|
};
|
|
const result = await shard.broadcastEval(evalFunc2).catch((error) => this.client.logger.error(error.stack));
|
|
console.log(result);
|
|
const other = result.reduce((acc, curr) => {
|
|
Object.entries(curr).forEach(([key, val]) => {
|
|
if (!acc[key]) acc[key] = 0;
|
|
acc[key] += val;
|
|
});
|
|
return acc;
|
|
}, {});
|
|
other['memberAvg'] = Math.floor(other.cachedMembers / shard.count);
|
|
other['messageAvg'] = Math.floor(other.cachedMessages / shard.count);
|
|
|
|
embed.fields.push({
|
|
name: message.format('C_STATS_CACHE'),
|
|
value: message.format('C_STATS_CACHE_VALUE', other),
|
|
inline: true
|
|
});
|
|
|
|
}
|
|
|
|
message.embed(embed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = StatsCommand; |