Skip to content
This repository has been archived by the owner on Dec 9, 2022. It is now read-only.

Commit

Permalink
✨ Introduce new logger system (#471)
Browse files Browse the repository at this point in the history
* ✨ Introduce new logger system

* 🔖 Tag!
  • Loading branch information
Jasper Mayone authored Aug 28, 2022
1 parent b83f40b commit ef5484d
Show file tree
Hide file tree
Showing 13 changed files with 140 additions and 92 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "heptagram",
"version": "5.0.1",
"version": "5.1.0",
"description": "The open-source multipurpose discord bot with the goal to be the single needed bot for any server.",
"main": "./prod/src/main.js",
"scripts": {
Expand All @@ -21,11 +21,11 @@
"homepage": "https://github.com/Heptagram-Bot/Heptagram#readme",
"dependencies": {
"@pm2/io": "^5.0.0",
"@sapphire/time-utilities": "^1.7.4",
"@types/chai": "^4.3.1",
"@types/mocha": "^9.1.1",
"axios": "^0.27.2",
"chai": "^4.3.6",
"chalk": "^5.0.1",
"cors": "^2.8.5",
"dayjs": "^1.11.3",
"discord.js": "^14.0.2",
Expand Down
8 changes: 4 additions & 4 deletions src/events/clientEvents/ready.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EmbedBuilder } from "discord.js";

import { Heptagram } from "../../interfaces/Heptagram";
import { heptagramLogHandler } from "../../modules/heptagramLogHandler";
import * as logger from "../../mo../../modules/heptagramLogger";

/**
* Sends a notification to the debug hook when Heptagram has connected to
Expand All @@ -10,7 +10,7 @@ import { heptagramLogHandler } from "../../modules/heptagramLogHandler";
* @param {Heptagram} Heptagram's Client instance.
*/
export const ready = async (Heptagram: Heptagram): Promise<void> => {
heptagramLogHandler.log("info", "Fetching reaction role data...");
logger.info("Fetching reaction role data...");
const readyEmbed = new EmbedBuilder();
readyEmbed.setTitle(
"<:status_online:951855000605298708> Heptagram is online <:status_online:951855000605298708>"
Expand All @@ -26,8 +26,8 @@ export const ready = async (Heptagram: Heptagram): Promise<void> => {
});

await Heptagram.debugHook.send({ embeds: [readyEmbed] });
heptagramLogHandler.log("info", "Discord ready!");
logger.info("Discord ready!");

heptagramLogHandler.log("info", "Loaded PM2 counts!");
logger.info("Loaded PM2 counts!");
Heptagram.pm2.metrics.events.mark();
};
48 changes: 25 additions & 23 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Heptagram } from "./interfaces/Heptagram";
import { loadCommands } from "./modules/commands/loadCommands";
import { registerCommands } from "./modules/commands/owner/registerCommands";
import { heptagramErrorHandler } from "./modules/heptagramErrorHandler";
import { heptagramLogHandler } from "./modules/heptagramLogHandler";
import * as logger from "./modules/heptagramLogger";
import { loadPM2 } from "./modules/loadPM2";
import { validateEnv } from "./utils/validateEnv";
import { validateNode } from "./utils/validateNode";
Expand All @@ -18,14 +18,14 @@ import { validateNode } from "./utils/validateNode";
* call the necessary helpers to prepare Heptagram, and then log in to Discord.
*/
void (async () => {
heptagramLogHandler.log("info", "Starting bot...");
logger.info("Starting bot...");

const validatedNode = await validateNode();
if (!validatedNode.valid) {
heptagramLogHandler.log("error", validatedNode.message);
logger.error(validatedNode.message);
process.exit(1);
} else {
heptagramLogHandler.log("info", validatedNode.message);
logger.info(validatedNode.message);
}

const Heptagram = new Client({
Expand All @@ -34,30 +34,30 @@ void (async () => {
allowedMentions: { parse: ["users", "roles"], repliedUser: true },
}) as Heptagram;

heptagramLogHandler.log("info", "Validating environment variables...");
logger.info("Validating environment variables...");
const validatedEnvironment = await validateEnv(Heptagram);
if (!validatedEnvironment.valid) {
heptagramLogHandler.log("error", `${validatedEnvironment.message}`);
logger.error(validatedEnvironment.message);
return;
} else {
heptagramLogHandler.log("info", "Environment variables validated.");
logger.info("Environment variables validated.");
}

heptagramLogHandler.log("info", "Loading PM2...");
logger.info("Loading PM2...");
const loadedPM2 = await loadPM2(Heptagram);
if (!loadedPM2) {
heptagramLogHandler.log("error", "Unable to load Grafana metrics");
logger.error("Unable to load Grafana metrics");
return;
} else {
heptagramLogHandler.log("info", "PM2 loaded.");
logger.info("PM2 loaded.");
}

Heptagram.debugHook = new WebhookClient({ url: Heptagram.configs.whUrl });

/* This catches when the process is about to exit
and destroys the discord.js client in order to allow for a graceful shutdown. */
process.on("exit", () => {
heptagramLogHandler.log("info", "Shutting down gracefully...");
logger.info("Shutting down gracefully...");
Heptagram.destroy();
});

Expand All @@ -67,52 +67,54 @@ and destroys the discord.js client in order to allow for a graceful shutdown. */
*/
process.on("unhandledRejection", async (error: Error) => {
await heptagramErrorHandler(Heptagram, "Unhandled Rejection Error", error);
await heptagramLogHandler.log("error", error);
await logger.error(`${error}`);
});

process.on("uncaughtException", async (error) => {
await heptagramErrorHandler(Heptagram, "Uncaught Exception Error", error);
await heptagramLogHandler.log("error", error);
await logger.error(`${error}`);
});

heptagramLogHandler.log("info", "Importing commands...");
logger.info("Importing commands...");
const commands = await loadCommands(Heptagram);
// eslint-disable-next-line require-atomic-updates
Heptagram.commands = commands;
if (!commands.length) {
heptagramLogHandler.log("error", "failed to import commands.");
logger.error("failed to import commands.");
return;
}

if (process.env.NODE_ENV !== "production") {
heptagramLogHandler.log("info", "Registering commands in development...");
logger.info("Registering commands in development...");
const success = await registerCommands(Heptagram);
if (!success) {
heptagramLogHandler.log("error", "failed to register commands.");
logger.error("failed to register commands.");
return;
}
}

heptagramLogHandler.log("info", "Connecting to database...");
logger.info("Connecting to database...");
const databaseConnection = await connectDatabase(Heptagram);
if (!databaseConnection) {
heptagramLogHandler.log("error", "failed to connect to database.");
logger.error("failed to connect to database.");
return;
} else {
heptagramLogHandler.log("info", "Database connected.");
logger.info("Database connected.");
}

heptagramLogHandler.log("info", "Attaching event listeners...");
logger.info("Attaching event listeners...");
handleEvents(Heptagram);

heptagramLogHandler.log("info", "Connecting to Discord...");
logger.info("Connecting to Discord...");
await Heptagram.login(Heptagram.configs.token);
heptagramLogHandler.log("info", "Setting activity...");
logger.info("Setting activity...");

Heptagram.user?.setActivity({
name: `over ${Heptagram.guilds.cache.size} guilds`,
type: ActivityType.Watching,
});

logger.ready("Heptagram is now running.");
})();

export default Heptagram;
7 changes: 2 additions & 5 deletions src/modules/commands/owner/reboot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import moment from "moment";

import { Heptagram } from "../../../interfaces/Heptagram";
import { heptagramErrorHandler } from "../../heptagramErrorHandler";
import { heptagramLogHandler } from "../../heptagramLogHandler";
import * as logger from "../../heptagramLogger";

/**s
* Reloads and restarts the bot.
Expand Down Expand Up @@ -42,10 +42,7 @@ export const reboot = async (Heptagram: Heptagram, message: Message) => {
})
.then(async (collected) => {
if (collected.first()?.content.toLowerCase() === "yes") {
heptagramLogHandler.log(
`info`,
`${message.author.username} has rebooted the bot.`
);
logger.info(`${message.author.username} has rebooted the bot.`);
(await Heptagram.debugHook.send({ embeds: [embed] })) &&
message.reply({ embeds: [embed] }).then(() => {
process.exit();
Expand Down
6 changes: 3 additions & 3 deletions src/modules/commands/owner/registerCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {

import { Heptagram } from "../../../interfaces/Heptagram";
import { heptagramErrorHandler } from "../../heptagramErrorHandler";
import { heptagramLogHandler } from "../../heptagramLogHandler";
import * as logger from "../../heptagramLogger";

/**
* Takes both the commands and contexts, parses the `data` properties as needed,
Expand Down Expand Up @@ -40,13 +40,13 @@ export const registerCommands = async (
});

if (process.env.NODE_ENV === "production") {
heptagramLogHandler.log("info", "registering commands globally!");
logger.info("registering commands globally!");

await rest.put(Routes.applicationCommands(Heptagram.configs.id), {
body: commandData,
});
} else {
heptagramLogHandler.log("info", "registering to home guild only");
logger.info("registering to home guild only");
await rest.put(
Routes.applicationGuildCommands(
Heptagram.configs.id,
Expand Down
9 changes: 3 additions & 6 deletions src/modules/heptagramErrorHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ import { Types } from "mongoose";
import { version as tsVersion } from "typescript";

import { Heptagram } from "../interfaces/Heptagram";
import * as logger from "../modules/heptagramLogger";
import { customSubstring } from "../utils/customSubstring";

import { heptagramLogHandler } from "./heptagramLogHandler";

/**
* Takes the error object generated within the code, logs the
* information in the console. Then, generates an error ID, builds an error embed, and sends
Expand All @@ -37,12 +36,10 @@ export const heptagramErrorHandler = async (
Heptagram.pm2.metrics.errors.mark();
}
const error = err as Error;
heptagramLogHandler.log("error", `There was an error in the ${context}:`);
heptagramLogHandler.log(
"error",
logger.error(`There was an error in the ${context}:`);
logger.error(
JSON.stringify({ errorMessage: error.message, errorStack: error.stack })
);

const errorId = new Types.ObjectId();
const errorEmbed = new EmbedBuilder();
errorEmbed.setTitle(
Expand Down
24 changes: 0 additions & 24 deletions src/modules/heptagramLogHandler.ts

This file was deleted.

75 changes: 75 additions & 0 deletions src/modules/heptagramLogger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import chalk from "chalk";
import moment from "moment";

export const log = (
content: string,
type:
| "log"
| "info"
| "warn"
| "error"
| "debug"
| "load"
| "ready"
| "mongo"
| "heptagram" = "log"
) => {
const timestamp = `${chalk.white(`[${moment().format("DD-MM-YY H:m:s")}]`)}`;

switch (type) {
case "log":
return console.log(`${chalk.grey("[LOG]")} ${timestamp} ${content}`);
case "info":
return console.log(
`${chalk.blueBright("[INFO]")} ${timestamp} ${chalk.blueBright(
content
)}`
);
case "warn":
return console.log(
`${chalk.yellow("[WARN]")} ${timestamp} ${chalk.yellow(content)} `
);
case "error":
return console.log(
`${chalk.red("[ERROR]")} ${timestamp} ${chalk.red(content)} `
);
case "debug":
return console.log(
`${chalk.blueBright("[DEBUG]")} ${timestamp} ${chalk.magenta(
content
)} `
);
case "load": {
return console.log(
`${timestamp} ${chalk.magenta(type.toUpperCase())} ${content} `
);
}
case "ready":
return console.log(
`${chalk.green("[READY]")} ${timestamp} ${chalk.green(content)}`
);
case "mongo":
return console.log(
`${chalk.hex("#f1421a")("[MONGO]")} ${timestamp} ${chalk.hex("#f1421a")(
content
)}`
);
case "heptagram":
return console.log(
`${chalk.hex("#FFF800")("[HEPTAGRAM]")} ${timestamp} ${chalk.hex(
"#FFF800"
)(`${content}`)}`
);
default:
throw new TypeError("Logger type not correct.");
}
};

export const info = (content: string) => log(content, "info");
export const warn = (content: string) => log(content, "warn");
export const error = (content: string) => log(content, "error");
export const debug = (content: string) => log(content, "debug");
export const load = (content: string) => log(content, "load");
export const ready = (content: string) => log(content, "ready");
export const mongo = (content: string) => log(content, "mongo");
export const heptagram = (content: string) => log(content, "heptagram");
4 changes: 2 additions & 2 deletions src/modules/loadPM2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import io from "@pm2/io";

import { Heptagram } from "../interfaces/Heptagram";

import { heptagramLogHandler } from "./heptagramLogHandler";
import * as logger from "./modules/heptagramLogHandler";

/**
* Module to load the PM2 config and attach it to Heptagram.
Expand All @@ -25,7 +25,7 @@ export const loadPM2 = (Heptagram: Heptagram): boolean => {
io.init();
return true;
} catch (err) {
heptagramLogHandler.log("error", err);
heptagramLogger.log("error", err);
return false;
}
};
10 changes: 10 additions & 0 deletions src/utils/randomNumber.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* gets a random number between min and max
*
* @param {number} min
* @param {number} max
* @returns {number} A human-readable format of the number of seconds.
*/
export const randomNumber = (min: number, max: number): number => {
return Math.floor(Math.random() * (max - min)) + min;
};
Loading

0 comments on commit ef5484d

Please sign in to comment.