diff options
Diffstat (limited to 'src-slowcord/status/src/index.ts')
-rw-r--r-- | src-slowcord/status/src/index.ts | 129 |
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 |