Додан моніторінг застосунку

Додани веб компоненти карточок територій та повідомлень
This commit is contained in:
2025-12-08 00:14:56 +02:00
parent e41590546c
commit 85483b85bb
206 changed files with 2370 additions and 595 deletions

133
metrics/metrics.js Normal file
View File

@@ -0,0 +1,133 @@
const express = require("express");
const cors = require("cors");
const WebSocket = require("ws");
const app = express();
const PORT_HTTP = 4005;
const PORT_WS = 4006;
const PUSHGATEWAY = "http://pushgateway:9091";
// --- HTTP server ---
app.use(cors({ origin: "*", methods: ["GET", "POST"], allowedHeaders: ["Content-Type"], credentials: true }));
app.use(express.json({ limit: "50mb" }));
app.post("/push", (req, res) => {
const metric = req.body;
if (metric) pushToProm(metric);
res.send("ok");
});
// --- WS server ---
const wss = new WebSocket.Server({ port: PORT_WS });
wss.on("connection", ws => {
console.log("New WS connection. Online users:", wss.clients.size);
pushOnlineCount();
ws.on("message", msg => {
try {
const m = JSON.parse(msg);
pushToProm(m);
} catch (e) {
console.error("Invalid WS message:", e);
}
});
ws.on("close", () => pushOnlineCount());
});
// --- Push metrics to Pushgateway ---
async function pushToProm(metric) {
if (!metric || !metric.type) return;
const lines = [];
let job = "webapp"; // default job
let groupingKey = {};
switch (metric.type) {
case "frontend_metrics":
job = "webapp_frontend";
lines.push(`# HELP frontend_load_time Frontend page load time in ms`);
lines.push(`# TYPE frontend_load_time gauge`);
lines.push(`frontend_load_time{instance="${metric.id || 'default'}"} ${metric.navigation?.loadEventEnd || 0}`);
if (metric.memory?.usedJSHeapSize) {
lines.push(`# HELP frontend_memory_used JS heap used in MB`);
lines.push(`# TYPE frontend_memory_used gauge`);
lines.push(`frontend_memory_used{instance="${metric.id || 'default'}"} ${metric.memory.usedJSHeapSize / 1024 / 1024}`);
}
if (metric.resources?.length) {
lines.push(`# HELP frontend_resource_count Number of resources loaded`);
lines.push(`# TYPE frontend_resource_count gauge`);
lines.push(`frontend_resource_count{instance="${metric.id || 'default'}"} ${metric.resources.length}`);
}
break;
case "rest":
job = "webapp_api";
lines.push(`# HELP rest_request_duration_ms REST request duration in ms`);
lines.push(`# TYPE rest_request_duration_ms gauge`);
lines.push(`rest_request_duration_ms{path="${metric.path}",status="${metric.status}"} ${metric.time}`);
break;
case "ws_in":
job = "webapp_ws";
lines.push(`# HELP ws_in_bytes_total WS bytes in`);
lines.push(`# TYPE ws_in_bytes_total counter`);
lines.push(`ws_in_bytes_total ${metric.length}`);
break;
case "ws_out":
job = "webapp_ws";
lines.push(`# HELP ws_out_bytes_total WS bytes out`);
lines.push(`# TYPE ws_out_bytes_total counter`);
lines.push(`ws_out_bytes_total ${metric.length}`);
break;
case "connection_status":
job = "webapp_connection";
lines.push(`# HELP users_online Users online`);
lines.push(`# TYPE users_online gauge`);
lines.push(`users_online ${metric.count || wss.clients.size}`);
const putBody = lines.join("\n") + "\n";
// Отправляем как PUT для Gauge, чтобы сбросить старые значения
return await pushToPrometheus(`${PUSHGATEWAY}/metrics/job/${job}`, putBody, "PUT");
}
const body = lines.join("\n") + "\n";
console.log(`Pushing metric for job=${job}:\n${body}\n`);
// Используем POST по умолчанию для инкремента/добавления
await pushToPrometheus(`${PUSHGATEWAY}/metrics/job/${job}`, body, "POST");
}
async function pushToPrometheus(url, body, method) {
try {
const response = await fetch(url, {
method: method,
headers: { "Content-Type": "text/plain" },
body
});
if (response.status !== 200) {
console.error(`PushGateway error (${method} ${url}):`, response.status, await response.text());
}
} catch (err) {
console.error("PushGateway network error:", err.message);
}
}
function pushOnlineCount() {
pushToProm({ type: "connection_status", count: wss.clients.size });
}
// --- Start HTTP server ---
app.listen(PORT_HTTP, () => console.log("Metrics HTTP listening on", PORT_HTTP));
console.log("Metrics WS listening on", PORT_WS);
// Запуск интервала после инициализации wss
setInterval(pushOnlineCount, 5000);