diff --git a/src/lib/stats.js b/src/lib/stats.js index 061861f..010ef8c 100644 --- a/src/lib/stats.js +++ b/src/lib/stats.js @@ -1,3 +1,5 @@ +/* eslint-disable no-underscore-dangle */ + const { version } = require('../../package.json'); const { md5, @@ -26,46 +28,51 @@ module.exports.sendToHouston = async client => { }, }, }); - const users = await client.prisma.user.findMany({ select: { messageCount: true } }); + const users = (await client.prisma.user.aggregate({ + _count: true, + _sum: { messageCount: true }, + })); + const messages = users._sum.messageCount ?? 0; const stats = { - activated_users: users.length, + activated_users: users._count, arch: process.arch, database: process.env.DB_PROVIDER, - guilds: guilds.filter(guild => { - if (!client.guilds.cache.has(guild.id)) { - client.log.warn('Guild %s is in the database but is not cached and might not exist. It will be excluded from the stats report.', guild.id); - return false; - } - return true; - }).map(guild => { - const closedTickets = guild.tickets.filter(t => t.firstResponseAt && t.closedAt); - return { - avg_resolution_time: msToMins(closedTickets.reduce((total, ticket) => total + (ticket.closedAt - ticket.createdAt), 0) ?? 1 / closedTickets.length), - avg_response_time: msToMins(closedTickets.reduce((total, ticket) => total + (ticket.firstResponseAt - ticket.createdAt), 0) ?? 1 / closedTickets.length), - categories: guild.categories.length, - features: { - auto_close: msToMins(guild.autoClose), - claiming: guild.categories.filter(c => c.claiming).length, - feedback: guild.categories.filter(c => c.enableFeedback).length, - logs: !!guild.logChannel, - // eslint-disable-next-line no-underscore-dangle - questions: guild.categories.filter(c => c._count.questions).length, - tags: guild.tags.length, - tags_regex: guild.tags.filter(t => t.regex).length, - topic: guild.categories.filter(c => c.requireTopic).length, - }, - id: md5(guild.id), - locale: guild.locale, - members: client.guilds.cache.get(guild.id).memberCount, - messages: users.reduce((total, user) => total + user.messageCount, 0), // global not guild, don't count archivedMessage table rows, they can be deleted - tickets: guild.tickets.length, - }; - }), + guilds: guilds + .filter(guild => client.guilds.cache.has(guild.id)) + .map(guild => { + const closedTickets = guild.tickets.filter(t => t.firstResponseAt && t.closedAt); + return { + avg_resolution_time: msToMins(closedTickets.reduce((total, ticket) => total + (ticket.closedAt - ticket.createdAt), 0) ?? 1 / closedTickets.length), + avg_response_time: msToMins(closedTickets.reduce((total, ticket) => total + (ticket.firstResponseAt - ticket.createdAt), 0) ?? 1 / closedTickets.length), + categories: guild.categories.length, + features: { + auto_close: msToMins(guild.autoClose), + claiming: guild.categories.filter(c => c.claiming).length, + feedback: guild.categories.filter(c => c.enableFeedback).length, + logs: !!guild.logChannel, + questions: guild.categories.filter(c => c._count.questions).length, + tags: guild.tags.length, + tags_regex: guild.tags.filter(t => t.regex).length, + topic: guild.categories.filter(c => c.requireTopic).length, + }, + id: md5(guild.id), + locale: guild.locale, + members: client.guilds.cache.get(guild.id).memberCount, + messages, // * global not guild, don't count archivedMessage table rows, they can be deleted + tickets: guild.tickets.length, + }; + }), id: md5(client.user.id), node: process.version, os: process.platform, version, }; + + const delta = guilds.length - stats.guilds.length; + if (delta !== 0) { + client.log.warn('%d guilds are not cached and were excluded from the stats report', delta); + } + try { client.log.verbose('Reporting to Houston:', stats); const res = await fetch('https://stats.discordtickets.app/api/v4/houston', {