fancy logging
This commit is contained in:
parent
726586f377
commit
afcd63039c
|
@ -12,11 +12,13 @@
|
|||
"author": "oatmealine",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"d3-array": "^2.12.1",
|
||||
"discord.js": "^14.13.0",
|
||||
"got": "^11.8.6",
|
||||
"knex": "^3.0.1",
|
||||
"parse-color": "^1.0.0",
|
||||
"pretty-bytes": "^5.6.0",
|
||||
"random-seed": "^0.3.0",
|
||||
"sqlite3": "^5.1.6"
|
||||
},
|
||||
|
|
|
@ -5,6 +5,9 @@ settings:
|
|||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
chalk:
|
||||
specifier: ^4.1.2
|
||||
version: 4.1.2
|
||||
d3-array:
|
||||
specifier: ^2.12.1
|
||||
version: 2.12.1
|
||||
|
@ -20,6 +23,9 @@ dependencies:
|
|||
parse-color:
|
||||
specifier: ^1.0.0
|
||||
version: 1.0.0
|
||||
pretty-bytes:
|
||||
specifier: ^5.6.0
|
||||
version: 5.6.0
|
||||
random-seed:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0
|
||||
|
@ -537,7 +543,6 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
color-convert: 2.0.1
|
||||
dev: true
|
||||
|
||||
/aproba@2.0.0:
|
||||
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
|
||||
|
@ -650,7 +655,6 @@ packages:
|
|||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
dev: true
|
||||
|
||||
/chownr@2.0.0:
|
||||
resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
|
||||
|
@ -679,11 +683,9 @@ packages:
|
|||
engines: {node: '>=7.0.0'}
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
dev: true
|
||||
|
||||
/color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
dev: true
|
||||
|
||||
/color-support@1.1.3:
|
||||
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
|
||||
|
@ -799,6 +801,7 @@ packages:
|
|||
|
||||
/emoji-regex@8.0.0:
|
||||
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/encoding@0.1.13:
|
||||
|
@ -1135,7 +1138,6 @@ packages:
|
|||
/has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/has-unicode@2.0.1:
|
||||
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
|
||||
|
@ -1239,6 +1241,7 @@ packages:
|
|||
|
||||
/inherits@2.0.4:
|
||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||
requiresBuild: true
|
||||
|
||||
/internmap@1.0.1:
|
||||
resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==}
|
||||
|
@ -1269,6 +1272,7 @@ packages:
|
|||
/is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/is-glob@4.0.3:
|
||||
|
@ -1739,6 +1743,11 @@ packages:
|
|||
engines: {node: '>= 0.8.0'}
|
||||
dev: true
|
||||
|
||||
/pretty-bytes@5.6.0:
|
||||
resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/promise-inflight@1.0.1:
|
||||
resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
|
||||
requiresBuild: true
|
||||
|
@ -1859,6 +1868,7 @@ packages:
|
|||
|
||||
/safe-buffer@5.2.1:
|
||||
resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/safer-buffer@2.1.2:
|
||||
|
@ -1977,6 +1987,7 @@ packages:
|
|||
|
||||
/string_decoder@1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
dev: false
|
||||
|
@ -1997,7 +2008,6 @@ packages:
|
|||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
dev: true
|
||||
|
||||
/supports-preserve-symlinks-flag@1.0.0:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
|
@ -2111,6 +2121,7 @@ packages:
|
|||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
|
||||
/webidl-conversions@3.0.1:
|
||||
|
|
|
@ -2,6 +2,7 @@ import { RoleCreateOptions, GuildMember, Interaction, EmbedBuilder, TextChannel,
|
|||
import { default as parseColor, Color } from 'parse-color';
|
||||
import { isColorRole, COLOR_ROLE_SEPERATOR } from '../lib/assignableRoles';
|
||||
import { knownServers } from '../lib/knownServers';
|
||||
import * as log from '../lib/log';
|
||||
|
||||
const PREVIEW_DURATION = 1000 * 60;
|
||||
|
||||
|
@ -17,7 +18,7 @@ async function applyColor(member: GuildMember, color: Color) {
|
|||
await removeAllColorRoles(member);
|
||||
|
||||
const colorRoleSeperator = await member.guild.roles.fetch(COLOR_ROLE_SEPERATOR);
|
||||
if (!colorRoleSeperator) console.error('no color role seperator found?!?!');
|
||||
if (!colorRoleSeperator) log.error('no color role seperator found?!?!');
|
||||
|
||||
const roleSettings: RoleCreateOptions = {
|
||||
name: color.hex,
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { RoleCreateOptions, GuildMember, Interaction, SlashCommandBuilder } from 'discord.js';
|
||||
import { pronouns, PRONOUN_ROLE_SEPERATOR } from '../lib/assignableRoles';
|
||||
import { knownServers } from '../lib/knownServers';
|
||||
import * as log from '../lib/log';
|
||||
|
||||
function extendOption(t: string) {
|
||||
return {name: t, value: t};
|
||||
|
@ -30,7 +31,7 @@ module.exports = {
|
|||
const pronoun = interaction.options.getString('pronoun', true);
|
||||
|
||||
const pronounRoleSeperator = await member.guild.roles.fetch(PRONOUN_ROLE_SEPERATOR);
|
||||
if (!pronounRoleSeperator) console.error('no pronoun role seperator found?!?!');
|
||||
if (!pronounRoleSeperator) log.error('no pronoun role seperator found?!?!');
|
||||
|
||||
const roleSettings: RoleCreateOptions = {
|
||||
name: pronoun,
|
||||
|
|
43
src/index.ts
43
src/index.ts
|
@ -1,9 +1,12 @@
|
|||
import { Client, GatewayIntentBits, Events, Collection, TextChannel } from 'discord.js';
|
||||
import { Client, GatewayIntentBits, Events, Collection } from 'discord.js';
|
||||
import * as fs from 'fs';
|
||||
const { token } = JSON.parse(fs.readFileSync('./config.json', 'utf8'));
|
||||
import * as path from 'path';
|
||||
import { initializeAnnouncements } from './lib/subscriptions';
|
||||
import { initTables } from './lib/db';
|
||||
import * as log from './lib/log';
|
||||
import chalk from 'chalk';
|
||||
import prettyBytes from 'pretty-bytes';
|
||||
|
||||
const bot = new Client({
|
||||
intents: [
|
||||
|
@ -17,7 +20,26 @@ const bot = new Client({
|
|||
],
|
||||
});
|
||||
|
||||
async function init() {
|
||||
log.nonsense('booting chip...');
|
||||
|
||||
await initTables();
|
||||
|
||||
log.nonsense('setting up connection...');
|
||||
|
||||
try {
|
||||
await bot.login(token);
|
||||
} catch (err) {
|
||||
log.error('error: network hardware broken?', err);
|
||||
log.error(`${chalk.bold('emergency mode could not be established.')} shutting down.`);
|
||||
}
|
||||
}
|
||||
|
||||
bot.on(Events.ClientReady, async () => {
|
||||
log.info('jillo online');
|
||||
|
||||
log.nonsense('finishing launch');
|
||||
|
||||
initializeAnnouncements(bot);
|
||||
|
||||
bot.commands = new Collection();
|
||||
|
@ -28,7 +50,11 @@ bot.on(Events.ClientReady, async () => {
|
|||
if (cmd.onClientReady) cmd.onClientReady(bot);
|
||||
}
|
||||
|
||||
console.log('jillo online');
|
||||
log.info('jillo firmware up and running');
|
||||
log.nonsense(`| running on ${process.platform} ${process.config.variables.host_arch}`);
|
||||
log.nonsense(`| node ${process.version} V8 v${process.versions.v8}`);
|
||||
const memory = process.memoryUsage();
|
||||
log.nonsense(`| ${prettyBytes(memory.rss)} memory usage, ${prettyBytes(memory.heapUsed)} / ${prettyBytes(memory.heapTotal)} heap usage`);
|
||||
});
|
||||
|
||||
bot.on(Events.InteractionCreate, async (interaction) => {
|
||||
|
@ -41,7 +67,7 @@ bot.on(Events.InteractionCreate, async (interaction) => {
|
|||
} catch (error) {
|
||||
if (interaction.isRepliable() && !interaction.replied && !interaction.deferred) interaction.reply({ content: '`ERROR`', ephemeral: true });
|
||||
if (interaction.deferred) interaction.followUp('`ERROR`');
|
||||
console.error(error);
|
||||
log.error(error);
|
||||
}
|
||||
} else if (interaction.isAutocomplete()) {
|
||||
const command = interaction.client.commands.get(interaction.commandName);
|
||||
|
@ -50,18 +76,13 @@ bot.on(Events.InteractionCreate, async (interaction) => {
|
|||
try {
|
||||
await command.autocomplete(interaction);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
log.error(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bot.on(Events.MessageDelete, (msg) => {
|
||||
console.log(`${msg.author?.username}#${msg.author?.discriminator} in #${msg.channel instanceof TextChannel ? msg.channel.name : '?'} at ${msg.createdAt.toISOString()}`);
|
||||
console.log(`${msg.content}`);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', err => {
|
||||
console.error(err);
|
||||
log.error(err);
|
||||
});
|
||||
|
||||
initTables().then(() => bot.login(token));
|
||||
init();
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
import knex from 'knex';
|
||||
import * as log from './log';
|
||||
|
||||
export const db = knex({
|
||||
client: 'sqlite3',
|
||||
connection: {
|
||||
filename: './jillo.sqlite'
|
||||
},
|
||||
useNullAsDefault: true
|
||||
useNullAsDefault: true,
|
||||
log: {
|
||||
warn: log.warn,
|
||||
error: log.error,
|
||||
deprecate: log.warn,
|
||||
debug: log.info
|
||||
}
|
||||
});
|
||||
|
||||
export interface ScheduledSubscription {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { Interaction, Message, TextBasedChannel, User } from 'discord.js';
|
||||
import * as log from '../lib/log';
|
||||
|
||||
export const RANDOM_WORDS = [
|
||||
'tarsorado', 'aboba', 'robtop', 'viprin', 'milk', 'milking station', 'radiation', 'extreme', 'glogging', 'glogged',
|
||||
|
@ -102,7 +103,7 @@ export async function startGame(interaction: Interaction, startingUser: User, na
|
|||
|
||||
collector.on('end', async (_, reason) => {
|
||||
clearInterval(updateInterval);
|
||||
await m.reactions.removeAll().catch(error => console.error(error));
|
||||
await m.reactions.removeAll().catch(error => log.error(error));
|
||||
|
||||
if (reason === 'cancelled') {
|
||||
m.edit(formatMessage(participants, 0, name, false, true));
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
import chalk from 'chalk';
|
||||
import * as util from 'util';
|
||||
|
||||
enum Severity {
|
||||
Info,
|
||||
Warn,
|
||||
Error,
|
||||
Nonsense
|
||||
}
|
||||
|
||||
function severityChar(severity: Severity) {
|
||||
switch (severity) {
|
||||
case Severity.Info:
|
||||
return ' ';
|
||||
case Severity.Warn:
|
||||
return chalk.yellow('!');
|
||||
case Severity.Error:
|
||||
return chalk.red('!');
|
||||
case Severity.Nonsense:
|
||||
return chalk.grey('.');
|
||||
}
|
||||
}
|
||||
|
||||
const inspectOptions: util.InspectOptions = {
|
||||
colors: true
|
||||
};
|
||||
|
||||
function format(thing: unknown): string {
|
||||
if (typeof thing === 'string') {
|
||||
return thing;
|
||||
} else if (thing instanceof Error) {
|
||||
return thing.stack || thing.toString();
|
||||
} else {
|
||||
return util.inspect(thing, inspectOptions);
|
||||
}
|
||||
}
|
||||
|
||||
function log(severity: Severity, ...message: unknown[]) {
|
||||
const formatted = message
|
||||
.map(m => format(m))
|
||||
.reduce((l, r) => l.includes('\n') || r.includes('\n') ? (l + '\n' + r) : (l + ' ' + r), '')
|
||||
.trim();
|
||||
const prefix = severityChar(severity) + ' ';
|
||||
process.stdout.write(`${prefix}${formatted.split('\n').join('\n' + prefix)}\n`);
|
||||
}
|
||||
|
||||
export function info(...message: unknown[]) {
|
||||
log(Severity.Info, ...message);
|
||||
}
|
||||
export function warn(...message: unknown[]) {
|
||||
log(Severity.Warn, ...message);
|
||||
}
|
||||
export function error(...message: unknown[]) {
|
||||
log(Severity.Error, ...message);
|
||||
}
|
||||
export function nonsense(...message: unknown[]) {
|
||||
log(Severity.Nonsense, ...message);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { Client, TextChannel } from 'discord.js';
|
||||
import { ScheduledSubscription, Subscription, db } from './db';
|
||||
import * as log from '../lib/log';
|
||||
|
||||
interface AnnouncementType {
|
||||
hour: number;
|
||||
|
@ -217,7 +218,7 @@ export function initializeAnnouncements(bot: Client) {
|
|||
`${announcement.messagesPrefix ? announcement.messagesPrefix : ''} ${announcement.messages[Math.floor(Math.random() * announcement.messages.length)]}`
|
||||
)
|
||||
)
|
||||
.catch(err => console.error(`failed to send ${k} announcement to ${channel}: ${err}`));
|
||||
.catch(err => log.error(`failed to send ${k} announcement to ${channel}:`, err));
|
||||
}
|
||||
}
|
||||
}, 1000);
|
||||
|
|
Loading…
Reference in New Issue