diff --git a/prod.env b/prod.env index caf02b4..4660602 100644 --- a/prod.env +++ b/prod.env @@ -7,4 +7,5 @@ STRIPE_SECRET_KEY="op://Environment Variables - Naomi/Alert Server/stripe" STRIPE_WEBHOOK_SECRET="op://Environment Variables - Naomi/Alert Server/stripe_webhook" DISCORD_TOKEN="op://Environment Variables - Naomi/Alert Server/discord_token" LOG_TOKEN="op://Environment Variables - Naomi/Alert Server/log_token" -ERROR_LOG_TOKEN="op://Environment Variables - Naomi/Alert Server/error_token" \ No newline at end of file +ERROR_LOG_TOKEN="op://Environment Variables - Naomi/Alert Server/error_token" +TELEMETRY_TOKEN="op://Environment Variables - Naomi/Alert Server/telemetry_token" \ No newline at end of file diff --git a/src/interfaces/metric.ts b/src/interfaces/metric.ts new file mode 100644 index 0000000..c43ef94 --- /dev/null +++ b/src/interfaces/metric.ts @@ -0,0 +1,11 @@ +/** + * @copyright nhcarrigan + * @license Naomi's Public License + * @author Naomi Carrigan + */ +export interface Metric { + application: string; + name: string; + value: number; + metadata?: Record; +} diff --git a/src/modules/pipeLog.ts b/src/modules/pipeLog.ts index fecd8ce..5c201a6 100644 --- a/src/modules/pipeLog.ts +++ b/src/modules/pipeLog.ts @@ -4,13 +4,6 @@ * @author Naomi Carrigan */ -const priority: Record = { - debug: 0, - error: 3, - info: 1, - warn: 2, -}; - /** * Pipes a log message to the Gotify server. * @param appName - The name of the application. @@ -26,15 +19,17 @@ const pipeLog = async( if (logToken === undefined) { return; } - await fetch(`https://logs.nhcarrigan.com/message?token=${logToken}`, { + await fetch(`https://telemetry.nhcarrigan.com/api/33kzMoHcYaaEyqCFsauKPhTvEtx/default/_json`, { body: JSON.stringify({ - message: message, - priority: priority[level] ?? priority.debug, - title: appName, + job: appName, + level: level, + log: message, }), headers: { // eslint-disable-next-line @typescript-eslint/naming-convention -- Standard header. - "Content-Type": "application/json", + "Authorization": `Basic ${process.env.TELEMETRY_TOKEN ?? ""}`, + // eslint-disable-next-line @typescript-eslint/naming-convention -- Standard header. + "Content-Type": "application/json", }, method: "POST", }); @@ -56,15 +51,17 @@ const pipeError = async( if (logToken === undefined) { return; } - await fetch(`https://logs.nhcarrigan.com/message?token=${logToken}`, { + await fetch(`https://telemetry.nhcarrigan.com/api/33kzMoHcYaaEyqCFsauKPhTvEtx/default/_json`, { body: JSON.stringify({ - message: message, - priority: priority[level] ?? priority.debug, - title: appName, + job: appName, + level: level, + log: message, }), headers: { // eslint-disable-next-line @typescript-eslint/naming-convention -- Standard header. - "Content-Type": "application/json", + "Authorization": `Basic ${process.env.TELEMETRY_TOKEN ?? ""}`, + // eslint-disable-next-line @typescript-eslint/naming-convention -- Standard header. + "Content-Type": "application/json", }, method: "POST", }); diff --git a/src/server/serve.ts b/src/server/serve.ts index 30f9f9e..2effa1e 100644 --- a/src/server/serve.ts +++ b/src/server/serve.ts @@ -3,6 +3,7 @@ * @license Naomi's Public License * @author Naomi Carrigan */ +/* eslint-disable max-lines -- this is kinda the main file. */ import fastify from "fastify"; import rawBody from "fastify-raw-body"; @@ -20,6 +21,7 @@ import { errorHandler } from "../utils/errorHandler.js"; import type { Entitlement } from "../interfaces/entitlement.js"; import type { Error } from "../interfaces/error.js"; import type { Log } from "../interfaces/log.js"; +import type { Metric } from "../interfaces/metric.js"; import type { Uptime } from "../interfaces/uptime.js"; const stripe = new StripeApp(process.env.STRIPE_SECRET_KEY ?? ""); @@ -77,6 +79,40 @@ export const instantiateServer = async(): Promise => { response.send(html); }); + // eslint-disable-next-line @typescript-eslint/naming-convention -- Body must be capitalised for Fastify. + server.post<{ Body: Metric }>("/metric", async(request, response) => { + try { + if (!auth(request)) { + await response.status(401).send({ success: false }); + return; + } + const { application, name, value, metadata } = request.body; + await fetch(`https://telemetry.nhcarrigan.com/api/33kzMoHcYaaEyqCFsauKPhTvEtx/ingest/metrics/_json`, { + body: JSON.stringify([ { + // eslint-disable-next-line @typescript-eslint/naming-convention -- Needs to match API's structure. + __name__: "metrics", + // eslint-disable-next-line @typescript-eslint/naming-convention -- Needs to match API's structure. + __type__: "count", + app: application, + metadata: metadata ?? {}, + name: name, + timestamp: Date.now(), + value: value, + } ]), + headers: { + // eslint-disable-next-line @typescript-eslint/naming-convention -- Standard header. + "Authorization": `Basic ${process.env.TELEMETRY_TOKEN ?? ""}`, + // eslint-disable-next-line @typescript-eslint/naming-convention -- Standard header. + "Content-Type": "application/json", + }, + method: "POST", + }); + } catch (error) { + await errorHandler(error, "Metric Webhook"); + await response.status(500).send({ success: false }); + } + }); + // eslint-disable-next-line @typescript-eslint/naming-convention -- Body must be capitalised for Fastify. server.post<{ Body: Log }>("/log", logSchema, async(request, response) => { try { @@ -330,7 +366,6 @@ export const instantiateServer = async(): Promise => { }); server.listen({ port: 5003 }, (error) => { - // eslint-disable-next-line max-lines -- This block is long because of logging. const application = "Rosalia Nightsong"; if (error) { const { message, stack } = error;