/
Krams
/
nodemon2
Обзор
Документация
Войти
/
Krams
/
nodemon2
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
backend/controllers/CollectorInternalController.js
118 строк
4 KB
Иван Новиков
final
25 май 2026, 17:46
25 май 2026, 17:46
2c76ffd
Код
Авторство
О чём код?
import db from '../database.js'; import { ingestCollectorNodes } from '../services/NodeStatusSyncService.js'; import { getMonitoringSettings } from '../services/NodeService.js'; export async function getNodesForCollectionController(_req, res) { try { const settings = await getMonitoringSettings(); if (settings?.enabled === false) { return res.json([]); } } catch (error) { console.error('[COLLECTOR] failed to read monitoring settings', error); } db.all( `SELECT id, name, COALESCE(monitoring_enabled, 1) AS monitoring_enabled, COALESCE(binding_mac_interface, 'eth0') AS binding_mac_interface FROM node ORDER BY name`, [], (err, rows) => { if (err) { console.error('[COLLECTOR] failed to fetch nodes for collection', err); return res.status(500).json({ error: 'Failed to fetch nodes' }); } const payload = (rows || []).map((row) => ({ id: row.id, hostname: row.name, monitoring_enabled: Number(row.monitoring_enabled) !== 0, binding_mac_interface: String(row.binding_mac_interface || 'eth0'), })); return res.json(payload); } ); } function normalizeSampledAtSec(value) { const n = Number(value); if (!Number.isFinite(n) || n <= 0) return null; return n > 1e12 ? Math.floor(n / 1000) : Math.floor(n); } function toLegacyNodePayload(report) { const nodeName = String(report?.hostname || report?.node_id || '').trim(); if (!nodeName) return null; const out = { node_id: nodeName, reservation: String(report?.reservation || ''), reason: String(report?.reason || ''), reason_time: String(report?.reason_time || ''), }; const sampledAt = normalizeSampledAtSec(report?.sampled_at); if (sampledAt !== null) out.sampled_at = sampledAt; if (typeof report?.mac === 'string' && report.mac.trim()) { out.mac = report.mac.trim().toLowerCase(); } if (typeof report?.error === 'string' && report.error.trim()) { out.error = report.error.trim(); } if (typeof report?.in_queue === 'string') { out.in_queue = report.in_queue; } if (report?.metrics && typeof report.metrics === 'object') { Object.assign(out, report.metrics); } if (report && typeof report === 'object') { for (const [key, value] of Object.entries(report)) { if ( key === 'hostname' || key === 'node_id' || key === 'reservation' || key === 'reason' || key === 'reason_time' || key === 'sampled_at' || key === 'metrics' ) { continue; } if (typeof out[key] === 'undefined') { out[key] = value; } } } return out; } export async function collectorReportController(req, res) { try { const incoming = Array.isArray(req.body?.reports) ? req.body.reports : [req.body]; const nodes = incoming .map(toLegacyNodePayload) .filter(Boolean); const result = await ingestCollectorNodes(nodes); return res.json({ ok: true, ...result }); } catch (error) { console.error('[COLLECTOR] ingest failed', error); return res.status(500).json({ error: 'Collector ingest failed' }); } } let lastCollectorHeartbeatAt = null; export function collectorHeartbeatController(req, res) { const tsRaw = req.body?.timestamp; const ts = tsRaw ? new Date(tsRaw) : new Date(); lastCollectorHeartbeatAt = Number.isNaN(ts.getTime()) ? new Date() : ts; return res.json({ ok: true, heartbeat_at: lastCollectorHeartbeatAt.toISOString() }); } export function collectorHeartbeatStatusController(_req, res) { return res.json({ ok: true, last_heartbeat_at: lastCollectorHeartbeatAt ? lastCollectorHeartbeatAt.toISOString() : null, }); }