Skip to content

Commit

Permalink
healthcheck
Browse files Browse the repository at this point in the history
vrtnd committed Jan 18, 2025

Verified

This commit was signed with the committer’s verified signature.
Sonicadvance1 Ryan Houdek
1 parent b1ee60c commit d0bd836
Showing 2 changed files with 88 additions and 10 deletions.
81 changes: 81 additions & 0 deletions src/server/health.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { cpuUsage } from "process";
import { cpus, freemem, totalmem, hostname, loadavg } from "os";

const CPU_HISTORY_HOURS = 24;
const cpuHistory: Array<{ timestamp: string; usage: string }> = [];

function formatBytes(bytes: number) {
const gb = bytes / (1024 * 1024 * 1024);
return `${gb.toFixed(2)} GB`;
}

function formatUptime(seconds: number) {
const days = Math.floor(seconds / (24 * 60 * 60));
const hours = Math.floor((seconds % (24 * 60 * 60)) / (60 * 60));
const minutes = Math.floor((seconds % (60 * 60)) / 60);
return `${days}d ${hours}h ${minutes}m`;
}

function updateCpuHistory() {
const startUsage = cpuUsage();

setTimeout(() => {
const endUsage = cpuUsage(startUsage);
const totalUsage = endUsage.user + endUsage.system;
const usagePercent = (totalUsage / 1000000 / 3600).toFixed(1);

cpuHistory.push({
timestamp: new Date().toISOString(),
usage: `${usagePercent}%`,
});

if (cpuHistory.length > CPU_HISTORY_HOURS) {
cpuHistory.shift();
}
}, 1000);
}

export function startHealthMonitoring() {
setInterval(updateCpuHistory, 3600000);
updateCpuHistory();
}

export function getHealthStatus() {
const memoryTotal = totalmem();
const memoryFree = freemem();
const memoryUsed = memoryTotal - memoryFree;
const memoryUsagePercent = ((memoryUsed / memoryTotal) * 100).toFixed(1);

const [oneMin, fiveMin, fifteenMin] = loadavg();
const cpuCount = cpus().length;

const health = {
status: "OK",
timestamp: new Date().toISOString(),
server: {
hostname: hostname(),
uptime: formatUptime(process.uptime()),
},
memory: {
total: formatBytes(memoryTotal),
used: formatBytes(memoryUsed),
free: formatBytes(memoryFree),
usage: `${memoryUsagePercent}%`,
status: Number(memoryUsagePercent) > 90 ? "WARNING" : "OK",
},
cpu: {
cores: cpuCount,
load: {
"1min": ((oneMin / cpuCount) * 100).toFixed(1) + "%",
"5min": ((fiveMin / cpuCount) * 100).toFixed(1) + "%",
"15min": ((fifteenMin / cpuCount) * 100).toFixed(1) + "%",
},
history: cpuHistory,
status: oneMin / cpuCount > 0.8 ? "WARNING" : "OK",
},
};

const statusCode = health.memory.status === "WARNING" || health.cpu.status === "WARNING" ? 207 : 200;

return { health, statusCode };
}
17 changes: 7 additions & 10 deletions src/server/index.ts
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ import runAdapter from "../handlers/runAdapter";
import getBridgeStatsOnDay from "../handlers/getBridgeStatsOnDay";
import cron from "./cron";
import { generateApiCacheKey, cache, registerCacheHandler, warmCache, needsWarming } from "../utils/cache";
import { startHealthMonitoring, getHealthStatus } from "./health";

dotenv.config();

@@ -22,15 +23,8 @@ const server: FastifyInstance = fastify({
keepAliveTimeout: 65000,
});

server.addHook("onRequest", async (request, reply) => {
server.addHook("onRequest", async (_, reply) => {
reply.raw.setTimeout(55000);

const startTime = process.hrtime();
request.raw.on("end", () => {
const [seconds, nanoseconds] = process.hrtime(startTime);
const duration = seconds * 1000 + nanoseconds / 1000000;
request.log.info(`Request to ${request.url} took ${duration.toFixed(2)}ms`);
});
});

const lambdaToFastify = (handler: Function) => async (request: any, reply: any) => {
@@ -96,11 +90,14 @@ const start = async () => {
server.get("/netflows/:period", lambdaToFastify(getNetflows));
server.get("/transactions/:id", lambdaToFastify(getTransactions));
server.post("/run-adapter", lambdaToFastify(runAdapter));
server.get("/healthcheck", (_, reply) => {
return reply.send("OK");
server.get("/healthcheck", async (_, reply) => {
const { health, statusCode } = getHealthStatus();
return reply.code(statusCode).send(health);
});
cron();

startHealthMonitoring();

const port = process.env.PORT ? parseInt(process.env.PORT) : 3000;
await server.listen({ port, host: "0.0.0.0" });
console.log(`Server listening on port ${port}`);

0 comments on commit d0bd836

Please sign in to comment.