summary refs log tree commit diff
path: root/src-slowcord/status/src/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src-slowcord/status/src/index.ts')
-rw-r--r--src-slowcord/status/src/index.ts129
1 files changed, 129 insertions, 0 deletions
diff --git a/src-slowcord/status/src/index.ts b/src-slowcord/status/src/index.ts
new file mode 100644
index 00000000..735b8a9b
--- /dev/null
+++ b/src-slowcord/status/src/index.ts
@@ -0,0 +1,129 @@
+import "dotenv/config";
+import https from "https";
+import mysql from "mysql2";
+import fetch from "node-fetch";
+
+const dbConn = mysql.createConnection(process.env.DATABASE as string);
+const executePromise = (sql: string, args: any[]) => new Promise((resolve, reject) => dbConn.execute(sql, args, (err, res) => { if (err) reject(err); else resolve(res); }));
+
+const instance = {
+	app: process.env.INSTANCE_WEB_APP as string,
+	api: process.env.INSTANCE_API as string,
+	cdn: process.env.INSTANCE_CDN as string,
+	token: process.env.INSTANCE_TOKEN as string,
+};
+
+const savePerf = async (time: number, name: string, error?: string | Error) => {
+	if (error && typeof error != "string") error = error.message;
+	try {
+		await executePromise("INSERT INTO performance (value, endpoint, timestamp, error) VALUES (?, ?, ?, ?)", [time ?? 0, name, new Date(), error ?? null]);
+		// await executePromise("DELETE FROM performance WHERE DATE(timestamp) < now() - interval ? DAY", [process.env.RETENTION_DAYS]);
+	}
+	catch (e) {
+		console.error(e);
+	}
+};
+
+const saveSystemUsage = async (load: number, procUptime: number, sysUptime: number, ram: number, sessions: number) => {
+	try {
+		await executePromise("INSERT INTO monitor (time, cpu, procUp, sysUp, ram, sessions) VALUES (?, ?, ?, ?, ?, ?)", [new Date(), load, procUptime, sysUptime, ram, sessions]);
+	}
+	catch (e) {
+		console.error(e);
+	}
+};
+
+const makeTimedRequest = (path: string, body?: object): Promise<number> => new Promise((resolve, reject) => {
+	const opts = {
+		hostname: new URL(path).hostname,
+		port: 443,
+		path: new URL(path).pathname,
+		method: "GET",
+		headers: {
+			"Content-Type": "application/json",
+			"Authorization": instance.token,
+		},
+		timeout: 1000,
+	};
+
+	let start: number, end: number;
+	const req = https.request(opts, res => {
+		if (res.statusCode! < 200 || res.statusCode! > 300) {
+			return reject(`${res.statusCode} ${res.statusMessage}`);
+		}
+
+		res.on("data", (data) => {
+		});
+
+		res.on("end", () => {
+			end = Date.now();
+			resolve(end - start);
+		});
+	});
+
+	req.on("finish", () => {
+		if (body) req.write(JSON.stringify(body));
+		start = Date.now();
+	});
+
+	req.on("error", (error) => {
+		reject(error);
+	});
+
+	req.end();
+});
+
+const measureApi = async (name: string, path: string, body?: object) => {
+	let error, time = -1;
+	try {
+		time = await makeTimedRequest(path, body);
+	}
+	catch (e) {
+		error = e as Error | string;
+	}
+
+	console.log(`${name} took ${time}ms ${(error ? "with error" : "")}`, error ?? "");
+
+	await savePerf(time, name, error);
+};
+
+interface monitorzSchema {
+	load: number[];
+	procUptime: number;
+	sysUptime: number;
+	memPercent: number;
+	sessions: number;
+}
+
+const app = async () => {
+	await new Promise((resolve) => dbConn.connect(resolve));
+	console.log("Connected to db");
+	// await client.login(instance.token);
+
+	console.log(`Monitoring performance for instance at ${new URL(instance.api).hostname}`);
+
+	const doMeasurements = async () => {
+		await measureApi("ping", `${instance.api}/ping`);
+		await measureApi("users/@me", `${instance.api}/users/@me`);
+		await measureApi("login", `${instance.app}/login`);
+		// await gatewayMeasure("websocketPing");
+
+		try {
+			const res = await fetch(`${instance.api}/-/monitorz`, {
+				headers: {
+					Authorization: process.env.INSTANCE_TOKEN as string,
+				}
+			});
+			const json = await res.json() as monitorzSchema;
+			await saveSystemUsage(json.load[1], json.procUptime, json.sysUptime, json.memPercent, json.sessions);
+		}
+		catch (e) {
+		}
+
+		setTimeout(doMeasurements, parseInt(process.env.MEASURE_INTERVAL as string));
+	};
+
+	doMeasurements();
+};
+
+app();
\ No newline at end of file