prometheus + load-testing
This commit is contained in:
@@ -14,6 +14,7 @@ import cookieParser from "cookie-parser";
|
||||
import cors from "cors";
|
||||
import { authMiddleware } from "modules/expressMiddleware";
|
||||
import "modules/chron";
|
||||
import { socketConnections } from "modules/prometheus";
|
||||
|
||||
const app = express();
|
||||
const server = createServer(app);
|
||||
@@ -25,7 +26,10 @@ export const io = new Server(server, {
|
||||
io.use(jwtMiddleware);
|
||||
|
||||
io.on("connection", (socket) => {
|
||||
console.log("New socket connection", socket.id);
|
||||
socketConnections.inc();
|
||||
socket.on("disconnect", () => {
|
||||
socketConnections.dec();
|
||||
});
|
||||
socket.on("connect-dispatch", handleConnectDispatch(socket, io));
|
||||
socket.on("connect-pilot", handleConnectPilot(socket, io));
|
||||
socket.on("connect-desktop", handleConnectDesktop(socket, io));
|
||||
|
||||
50
apps/dispatch-server/modules/prometheus.ts
Normal file
50
apps/dispatch-server/modules/prometheus.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { prisma } from "@repo/db";
|
||||
import promClient from "prom-client";
|
||||
|
||||
export const promRegister = new promClient.Registry();
|
||||
promClient.collectDefaultMetrics({ register: promRegister });
|
||||
|
||||
export const socketConnections = new promClient.Gauge({
|
||||
name: "socket_connections",
|
||||
help: "Number of active socket connections",
|
||||
registers: [promRegister],
|
||||
});
|
||||
|
||||
export const aircraftPatches = new promClient.Counter({
|
||||
name: "aircraft_patches",
|
||||
help: "Counts patch requests for aircrafts",
|
||||
registers: [promRegister],
|
||||
});
|
||||
|
||||
export const connectedPilots = new promClient.Gauge({
|
||||
name: "connected_pilots",
|
||||
help: "Counts connected pilots",
|
||||
registers: [promRegister],
|
||||
collect: async () => {
|
||||
const count = await prisma.connectedAircraft.count({
|
||||
where: {
|
||||
logoutTime: null,
|
||||
},
|
||||
});
|
||||
connectedPilots.set(count);
|
||||
},
|
||||
});
|
||||
|
||||
export const connectedDispatcher = new promClient.Gauge({
|
||||
name: "connected_dispatcher",
|
||||
help: "Counts connected dispatchers",
|
||||
registers: [promRegister],
|
||||
collect: async () => {
|
||||
const count = await prisma.connectedDispatcher.count({
|
||||
where: {
|
||||
logoutTime: null,
|
||||
},
|
||||
});
|
||||
connectedDispatcher.set(count);
|
||||
},
|
||||
});
|
||||
|
||||
promRegister.registerMetric(socketConnections);
|
||||
promRegister.registerMetric(aircraftPatches);
|
||||
promRegister.registerMetric(connectedPilots);
|
||||
promRegister.registerMetric(connectedDispatcher);
|
||||
@@ -5,7 +5,7 @@ import jwt from "jsonwebtoken";
|
||||
|
||||
export const jwtMiddleware = async (socket: Socket, next: (err?: ExtendedError) => void) => {
|
||||
try {
|
||||
const { uid } = socket.handshake.auth;
|
||||
const uid = socket.handshake.auth.uid || socket.handshake.query.uid;
|
||||
if (!uid) return new Error("Authentication error");
|
||||
/* const token = socket.handshake.auth?.token;
|
||||
if (!token) return new Error("Authentication error");
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"packageManager": "pnpm@10.11.0",
|
||||
"devDependencies": {
|
||||
"@repo/db": "workspace:*",
|
||||
"@repo/typescript-config": "workspace:*",
|
||||
"@repo/shared-components": "workspace:*",
|
||||
"@repo/typescript-config": "workspace:*",
|
||||
"@types/cookie-parser": "^1.4.8",
|
||||
"@types/cors": "^2.8.18",
|
||||
"@types/express": "^5.0.2",
|
||||
@@ -37,6 +37,7 @@
|
||||
"node-cron": "^4.1.0",
|
||||
"nodemailer": "^7.0.3",
|
||||
"nodemon": "^3.1.10",
|
||||
"prom-client": "^15.1.3",
|
||||
"react": "^19.1.0",
|
||||
"redis": "^5.1.1",
|
||||
"socket.io": "^4.8.1",
|
||||
|
||||
@@ -1,13 +1,7 @@
|
||||
import {
|
||||
AdminMessage,
|
||||
ConnectedAircraft,
|
||||
getPublicUser,
|
||||
MissionLog,
|
||||
Prisma,
|
||||
prisma,
|
||||
} from "@repo/db";
|
||||
import { AdminMessage, getPublicUser, MissionLog, Prisma, prisma } from "@repo/db";
|
||||
import { Router } from "express";
|
||||
import { io } from "../index";
|
||||
import { aircraftPatches } from "modules/prometheus";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
@@ -97,7 +91,7 @@ router.patch("/:id", async (req, res) => {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
aircraftPatches.inc();
|
||||
res.json(updatedConnectedAircraft);
|
||||
// When change is only the estimated logout time, we don't need to emit an event
|
||||
if (Object.keys(aircraftUpdate).length === 1 && aircraftUpdate.esimatedLogoutTime) return;
|
||||
|
||||
9
apps/dispatch-server/routes/metrics.ts
Normal file
9
apps/dispatch-server/routes/metrics.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { Router } from "express";
|
||||
import { promRegister } from "modules/prometheus";
|
||||
|
||||
export const metricsRouter: Router = Router();
|
||||
|
||||
metricsRouter.get("/", async (req, res) => {
|
||||
res.setHeader("Content-Type", promRegister.contentType);
|
||||
res.end(await promRegister.metrics());
|
||||
});
|
||||
@@ -4,6 +4,7 @@ import missionRouter from "./mission";
|
||||
import statusRouter from "./status";
|
||||
import aircraftsRouter from "./aircraft";
|
||||
import reportRouter from "./report";
|
||||
import { metricsRouter } from "routes/metrics";
|
||||
|
||||
const router: Router = Router();
|
||||
|
||||
@@ -12,5 +13,6 @@ router.use("/mission", missionRouter);
|
||||
router.use("/status", statusRouter);
|
||||
router.use("/aircrafts", aircraftsRouter);
|
||||
router.use("/report", reportRouter);
|
||||
router.use("/metrics", metricsRouter);
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -16,6 +16,7 @@ export const handleConnectPilot =
|
||||
debug: boolean;
|
||||
}) => {
|
||||
try {
|
||||
console.log("Connecting pilot:", socket.id, "Station ID:", stationId, "Debug mode:", debug);
|
||||
if (!stationId) return Error("Station ID is required");
|
||||
const user: User = socket.data.user; // User ID aus dem JWT-Token
|
||||
const userId = socket.data.user.id; // User ID aus dem JWT-Token
|
||||
@@ -43,7 +44,7 @@ export const handleConnectPilot =
|
||||
},
|
||||
});
|
||||
|
||||
if (existingConnection) {
|
||||
if (existingConnection && !debug) {
|
||||
await io.to(`user:${user.id}`).emit("force-disconnect", "double-connection");
|
||||
await prisma.connectedAircraft.updateMany({
|
||||
where: {
|
||||
|
||||
Reference in New Issue
Block a user