import express, { Request, Response } from "express"; import { container } from "tsyringe"; import { Counter, Gauge, collectDefaultMetrics, register } from "prom-client"; import { LocationService } from "../services/locationService"; import { WifiLocationService } from "../services/wifiLocationService"; const router = express.Router(); const locationService = container.resolve(LocationService); const wifiLocationService = container.resolve(WifiLocationService); // Collect default system metrics (e.g., CPU, memory usage) const prefix = 'locationhub_'; collectDefaultMetrics({ prefix }); // Define a custom Counter metric const requestCounter = new Counter({ name: `${prefix}http_requests_total`, help: "Total number of HTTP requests", labelNames: ["method", "route", "status"], }); const locationsTotal = new Gauge({ name: `${prefix}locations_total`, help: "Total number of location entries in database", labelNames: ["database"], }); const wifiLocationTotal = new Gauge({ name: `${prefix}wifi_locations_total`, help: "Total number of wifi location entries in database", labelNames: ["database"], }); const wifiLocationNotResolvable = new Gauge({ name: `${prefix}wifi_locations_not_resolvable`, help: "Unresolved number of wifi location entries in database", labelNames: ["database"], }); const wifiLocationRequestLimitExceeded = new Gauge({ name: `${prefix}wifi_locations_request_limit_exceeded`, help: "Unresolved number of wifi location because request limit exceeded entries in database", labelNames: ["database"], }); // Define the metrics endpoint router.get("/", async (req: Request, res: Response) => { try { console.log("Metric Endpoint triggered"); locationsTotal.set((await locationService.getAllLocations()).length); wifiLocationTotal.set((await wifiLocationService.getAllWifiLocations()).length); wifiLocationNotResolvable.set((await wifiLocationService.getAllWifiLocationsByNotResolvable).length); wifiLocationRequestLimitExceeded.set((await wifiLocationService.getAllWifiLocationsByRequestLimitExceeded).length); // Increment the counter with labels requestCounter.inc({ method: req.method, route: req.route.path, status: 200 }); // Expose metrics in Prometheus format res.set("Content-Type", register.contentType); res.send(await register.metrics()); } catch (error) { // Increment the counter for errors requestCounter.inc({ method: req.method, route: req.route.path, status: 500 }); console.error("Error running metrics endpoint:", error); res.status(500).json({ error: "Error running metrics endpoint" }); } }); export default router;