summary refs log tree commit diff
path: root/slowcord/status/src/index.ts
blob: a4d911adcb29c467b2238ee8fbe9efbb528199ec (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
import "dotenv/config";
import fetch from "node-fetch";
import Fosscord from "fosscord-gopnik";
import mysql from "mysql2";

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 = {
	api: process.env.INSTANCE_API as string,
	cdn: process.env.INSTANCE_CDN as string,
	token: process.env.INSTANCE_TOKEN as string,
};

const client = new Fosscord.Client({
	intents: [],
	http: {
		api: instance.api,
		cdn: instance.cdn
	}
});

client.on("ready", () => {
	console.log(`Ready on gateway as ${client.user!.tag}`);

	const gatewayMeasure = async (name: string) => {
		const time = Math.max(client.ws.ping, 0);
		await savePerf(time, name, null);
		console.log(`${name} took ${time}ms`);
		setTimeout(gatewayMeasure, parseInt(process.env.MEASURE_INTERVAL as string), name);
	};

	gatewayMeasure("websocketPing")
});

client.on("error", (error) => {
	console.log(`Gateway error`, error);
});

client.on("warn", (msg) => {
	console.log(`Gateway warning:`, msg);
});

const savePerf = async (time: number, name: string, error: string | null) => {
	try {
		await executePromise("INSERT INTO performance (value, endpoint, timestamp, error) VALUES (?, ?, ?, ?)", [time, name, new Date(), error]);
		await executePromise("DELETE FROM performance WHERE DATE(timestamp) < now() - interval ? DAY", [process.env.RETENTION_DAYS]);
	}
	catch (e) {
		console.error(e);
	}
};

const measureApi = async (name: string, path: string, body?: object) => {
	const start = Date.now();

	let error: Error | null = null;
	try {
		const res = await fetch(path, {
			headers: {
				"Content-Type": "application/json",
				"Authorization": instance.token,
			},
			body: body ? JSON.stringify(body) : undefined,
		});
		await res.json();
	}
	catch (e) {
		error = e as Error;
	}

	const time = Date.now() - start;
	console.log(`${name} took ${time}ms ${(error ? "with error" : "")}`, error ?? "");

	await savePerf(time, name, error?.message ?? null);

	setTimeout(measureApi, parseInt(process.env.MEASURE_INTERVAL as string), name, path, body);
};

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}`);

	measureApi("ping", `${instance.api}/ping`);
	measureApi("users/@me", `${instance.api}/users/@me`);
};

app();