diff --git a/backend/routes/alertsRoutes.js b/backend/routes/alertsRoutes.js
index c93b7a5..49bb3df 100644
--- a/backend/routes/alertsRoutes.js
+++ b/backend/routes/alertsRoutes.js
@@ -11,11 +11,11 @@ const { getUptimeCacheData } = require('./mikrotikConfigRoutes');
/** Значения по умолчанию для настроек оповещений. */
const DEFAULT_ALERT_SETTINGS = {
- serverOffline: { enabled: true },
- mikrotikUnreachable: { enabled: true },
- highCpu: { enabled: true, thresholdPercent: 85 },
- highRam: { enabled: true, thresholdPercent: 85 },
- highHdd: { enabled: true, thresholdPercent: 90 },
+ serverOffline: { enabled: true, offlineMinutes: 5 },
+ mikrotikUnreachable: { enabled: true, durationMinutes: 5 },
+ highCpu: { enabled: true, thresholdPercent: 85, durationMinutes: 10 },
+ highRam: { enabled: true, thresholdPercent: 85, durationMinutes: 10 },
+ highHdd: { enabled: true, thresholdPercent: 90, durationMinutes: 10 },
};
function getAlertSettings(uiSettings) {
@@ -64,9 +64,11 @@ async function getAlerts(req, res) {
if (isRouter) {
const entry = uptimeResults[serverId];
- offline = entry ? entry.ok === false : false;
+ const offlineMinutes = Math.max(1, Math.min(1440, Number(settings.serverOffline.offlineMinutes) || 5));
+ const offlineSinceMs = entry && entry.lastCheckTs ? (Date.now() - entry.lastCheckTs) : 0;
+ offline = entry && entry.ok === false && offlineSinceMs >= offlineMinutes * 60 * 1000;
description = offline
- ? `${name} недоступен (по проверке Uptime Monitor).`
+ ? `${name} недоступен более ${offlineMinutes} мин (по проверке Uptime Monitor).`
: '';
} else {
const idx = nonRouterServers.findIndex(
diff --git a/frontend/src/SettingsPage.jsx b/frontend/src/SettingsPage.jsx
index 1a4dc23..3668e55 100644
--- a/frontend/src/SettingsPage.jsx
+++ b/frontend/src/SettingsPage.jsx
@@ -102,13 +102,18 @@ export default function SettingsPage() {
const [uptimeMonitorSchedulerEnabled, setUptimeMonitorSchedulerEnabled] = useState(true);
const [uptimeMonitorSchedulerIntervalMinutes, setUptimeMonitorSchedulerIntervalMinutes] = useState('2');
const [alertServerOffline, setAlertServerOffline] = useState(true);
+ const [alertServerOfflineMinutes, setAlertServerOfflineMinutes] = useState('5');
const [alertMikrotikUnreachable, setAlertMikrotikUnreachable] = useState(true);
+ const [alertMikrotikUnreachableMinutes, setAlertMikrotikUnreachableMinutes] = useState('5');
const [alertHighCpuEnabled, setAlertHighCpuEnabled] = useState(true);
const [alertHighCpuThreshold, setAlertHighCpuThreshold] = useState('85');
+ const [alertHighCpuDurationMinutes, setAlertHighCpuDurationMinutes] = useState('10');
const [alertHighRamEnabled, setAlertHighRamEnabled] = useState(true);
const [alertHighRamThreshold, setAlertHighRamThreshold] = useState('85');
+ const [alertHighRamDurationMinutes, setAlertHighRamDurationMinutes] = useState('10');
const [alertHighHddEnabled, setAlertHighHddEnabled] = useState(true);
const [alertHighHddThreshold, setAlertHighHddThreshold] = useState('90');
+ const [alertHighHddDurationMinutes, setAlertHighHddDurationMinutes] = useState('10');
const [serversList, setServersList] = useState([]);
const [sidebarSearch, setSidebarSearch] = useState('');
const [activeSection, setActiveSection] = useState(() => {
@@ -316,13 +321,18 @@ export default function SettingsPage() {
);
const a = data?.alertSettings || {};
setAlertServerOffline(a.serverOffline?.enabled !== false);
+ setAlertServerOfflineMinutes(a.serverOffline?.offlineMinutes != null ? String(a.serverOffline.offlineMinutes) : '5');
setAlertMikrotikUnreachable(a.mikrotikUnreachable?.enabled !== false);
+ setAlertMikrotikUnreachableMinutes(a.mikrotikUnreachable?.durationMinutes != null ? String(a.mikrotikUnreachable.durationMinutes) : '5');
setAlertHighCpuEnabled(a.highCpu?.enabled !== false);
setAlertHighCpuThreshold(a.highCpu?.thresholdPercent != null ? String(a.highCpu.thresholdPercent) : '85');
+ setAlertHighCpuDurationMinutes(a.highCpu?.durationMinutes != null ? String(a.highCpu.durationMinutes) : '10');
setAlertHighRamEnabled(a.highRam?.enabled !== false);
setAlertHighRamThreshold(a.highRam?.thresholdPercent != null ? String(a.highRam.thresholdPercent) : '85');
+ setAlertHighRamDurationMinutes(a.highRam?.durationMinutes != null ? String(a.highRam.durationMinutes) : '10');
setAlertHighHddEnabled(a.highHdd?.enabled !== false);
setAlertHighHddThreshold(a.highHdd?.thresholdPercent != null ? String(a.highHdd.thresholdPercent) : '90');
+ setAlertHighHddDurationMinutes(a.highHdd?.durationMinutes != null ? String(a.highHdd.durationMinutes) : '10');
const e =
settingsRes?.headers?.etag || settingsRes?.headers?.ETag || '';
setEtag(e ? String(e) : '');
@@ -438,19 +448,28 @@ export default function SettingsPage() {
}))
: [],
alertSettings: {
- serverOffline: { enabled: alertServerOffline },
- mikrotikUnreachable: { enabled: alertMikrotikUnreachable },
+ serverOffline: {
+ enabled: alertServerOffline,
+ offlineMinutes: Math.max(1, Math.min(1440, parseInt(alertServerOfflineMinutes, 10) || 5)),
+ },
+ mikrotikUnreachable: {
+ enabled: alertMikrotikUnreachable,
+ durationMinutes: Math.max(1, Math.min(1440, parseInt(alertMikrotikUnreachableMinutes, 10) || 5)),
+ },
highCpu: {
enabled: alertHighCpuEnabled,
thresholdPercent: Math.max(1, Math.min(100, parseInt(alertHighCpuThreshold, 10) || 85)),
+ durationMinutes: Math.max(1, Math.min(1440, parseInt(alertHighCpuDurationMinutes, 10) || 10)),
},
highRam: {
enabled: alertHighRamEnabled,
thresholdPercent: Math.max(1, Math.min(100, parseInt(alertHighRamThreshold, 10) || 85)),
+ durationMinutes: Math.max(1, Math.min(1440, parseInt(alertHighRamDurationMinutes, 10) || 10)),
},
highHdd: {
enabled: alertHighHddEnabled,
thresholdPercent: Math.max(1, Math.min(100, parseInt(alertHighHddThreshold, 10) || 90)),
+ durationMinutes: Math.max(1, Math.min(1440, parseInt(alertHighHddDurationMinutes, 10) || 10)),
},
},
};
@@ -1088,160 +1107,216 @@ export default function SettingsPage() {
<>
- Включите или отключите типы оповещений и задайте пороги. Оповещения отображаются на панели и в колокольчике в шапке. + Настройте пороги и длительность для каждого типа оповещений. Оповещения отображаются на панели и в колокольчике в шапке.
-- Для jumphost/home используются те же правила, что и в Uptime Monitor: тип проверки (HTTP, internal-ping, external-ping) и кеш. Настройки — в разделе { e.preventDefault(); goToSection('uptime-monitor'); }}>Uptime Monitor. Для остальных серверов — проверка TCP (80/443). -
-