Уведомление о росте использования swap
Растущий swap — тихий предвестник беды. Пока приложение просто «подтекает» по памяти, система молча вытесняет страницы в подкачку: сервер ещё живой, но уже начинает тормозить на дисковом вводе-выводе. Заметить это лучше на 50 % занятого swap, чем ловить OOM killer, когда память кончилась окончательно.
Что мы будем делать
Заголовок раздела «Что мы будем делать»Скрипт каждые 5 минут читает /proc/meminfo, считает процент занятого swap
(SwapTotal минус SwapFree) и:
- если занято ≥ 50 % — присылает обычное предупреждение;
- если занято ≥ 80 % — присылает сообщение с высоким приоритетом.
Как приятное дополнение, при высоком заполнении мы добавляем текущую скорость
подкачки (si/so из vmstat) — активный swap-in/out гораздо опаснее статично
занятого, но неиспользуемого swap.
Чтобы не получать одно и то же сообщение каждые 5 минут, храним состояние
(ok/warn/crit) в /var/lib/notifly-swap/ — как в рецепте про
место на диске.
Сохраните как /usr/local/bin/notifly-swap-check:
#!/usr/bin/env bashset -euset -a; source /etc/notifly.env; set +a
WARN=50CRIT=80STATE_DIR=/var/lib/notifly-swapSTATE_FILE="$STATE_DIR/level"mkdir -p "$STATE_DIR"
HOST=$(hostname -s)
# SwapTotal / SwapFree — в килобайтахSWAP_TOTAL=$(awk '/^SwapTotal:/{print $2}' /proc/meminfo)SWAP_FREE=$(awk '/^SwapFree:/{print $2}' /proc/meminfo)
# Нет swap вовсе — тихо выходим[ "${SWAP_TOTAL:-0}" -gt 0 ] || exit 0
SWAP_USED=$(( SWAP_TOTAL - SWAP_FREE ))SWAP_PCT=$(( SWAP_USED * 100 / SWAP_TOTAL ))USED_MB=$(( SWAP_USED / 1024 ))TOTAL_MB=$(( SWAP_TOTAL / 1024 ))
LAST=$(cat "$STATE_FILE" 2>/dev/null || echo ok)
LEVEL=ok[ "$SWAP_PCT" -ge "$WARN" ] && LEVEL=warn[ "$SWAP_PCT" -ge "$CRIT" ] && LEVEL=crit
if [ "$LEVEL" != "$LAST" ]; then # Скорость подкачки прямо сейчас (si/so, КБ/с) — usefull при активном swap read -r SI SO <<<"$(vmstat 1 2 | tail -1 | awk '{print $7, $8}')"
case "$LEVEL" in warn) /usr/local/bin/notifly-send \ "⚠️ Swap заполнен на $SWAP_PCT% — $HOST" \ "Занято $USED_MB из $TOTAL_MB МБ swap. Похоже, кто-то подтекает по памяти." 5 ;; crit) /usr/local/bin/notifly-send \ "🔥 КРИТИЧНО: swap $SWAP_PCT% — $HOST" \ "Занято $USED_MB из $TOTAL_MB МБ swap. Подкачка: si=${SI} so=${SO} КБ/с. До OOM недалеко!" 9 ;; ok) /usr/local/bin/notifly-send \ "✅ Swap в норме — $HOST" \ "Использование swap вернулось в норму ($SWAP_PCT%)." 3 ;; esac echo "$LEVEL" > "$STATE_FILE"fiСделайте исполняемым:
sudo chmod +x /usr/local/bin/notifly-swap-checkЗапуск по расписанию
Заголовок раздела «Запуск по расписанию»Через cron
Заголовок раздела «Через cron»sudo crontab -eДобавьте строку:
*/5 * * * * /usr/local/bin/notifly-swap-check >/dev/null 2>&1Через systemd timer (рекомендуется)
Заголовок раздела «Через systemd timer (рекомендуется)»/etc/systemd/system/notifly-swap.service:
[Unit]Description=Notifly swap usage check
[Service]Type=oneshotExecStart=/usr/local/bin/notifly-swap-check/etc/systemd/system/notifly-swap.timer:
[Unit]Description=Run notifly-swap every 5 minutes
[Timer]OnBootSec=5minOnUnitActiveSec=5min
[Install]WantedBy=timers.targetАктивируем:
sudo systemctl daemon-reloadsudo systemctl enable --now notifly-swap.timersudo systemctl list-timers notifly-swap.timerWindows: PowerShell + Task Scheduler
Заголовок раздела «Windows: PowerShell + Task Scheduler»Эквивалент для Windows-серверов. У Windows нет swap в linux-смысле, но роль
подкачки играет pagefile — следим за его заполнением через Win32_PageFileUsage
(CurrentUsage / AllocatedBaseSize) и за общим объёмом закоммиченной памяти
через Win32_OperatingSystem. Используется общая функция Send-Notifly
из шаблона sysadmin/index.
. C:\scripts\Notifly.ps1
$Warn = 50$Crit = 80$StateDir = "C:\ProgramData\Notifly\swap-state"New-Item -ItemType Directory -Path $StateDir -Force | Out-Null$StateFile = Join-Path $StateDir "level.txt"$Host = $env:COMPUTERNAME
# Заполнение pagefile: CurrentUsage / AllocatedBaseSize (в МБ)$page = Get-CimInstance Win32_PageFileUsage -ErrorAction SilentlyContinue | Sort-Object CurrentUsage -Descending | Select-Object -First 1if (-not $page -or $page.AllocatedBaseSize -le 0) { exit 0 }
$usedPct = [int](($page.CurrentUsage / $page.AllocatedBaseSize) * 100)$usedMB = [int]$page.CurrentUsage$totalMB = [int]$page.AllocatedBaseSize
# Общая закоммиченная память для контекста в сообщении$os = Get-CimInstance Win32_OperatingSystem$committedMB = [int](($os.TotalVirtualMemorySize - $os.FreeVirtualMemory) / 1024)
$last = if (Test-Path $StateFile) { Get-Content $StateFile -Raw } else { "ok" }
$level = "ok"if ($usedPct -ge $Warn) { $level = "warn" }if ($usedPct -ge $Crit) { $level = "crit" }
if ($level -ne $last.Trim()) { switch ($level) { "warn" { Send-Notifly -Title "⚠️ Pagefile $usedPct% — $Host" ` -Message "Занято $usedMB из $totalMB МБ pagefile (закоммичено $committedMB МБ)." -Priority 5 } "crit" { Send-Notifly -Title "🔥 КРИТИЧНО: pagefile $usedPct% — $Host" ` -Message "Занято $usedMB из $totalMB МБ pagefile. Закоммичено $committedMB МБ. Память на исходе!" -Priority 9 } "ok" { Send-Notifly -Title "✅ Pagefile в норме — $Host" ` -Message "Использование pagefile вернулось в норму ($usedPct%)." -Priority 3 } } $level | Set-Content $StateFile}Регистрация в Task Scheduler (от администратора, каждые 5 минут от SYSTEM):
$Action = New-ScheduledTaskAction ` -Execute "powershell.exe" ` -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\scripts\Notifly-Swap-Check.ps1"$Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date) ` -RepetitionInterval (New-TimeSpan -Minutes 5)$Princ = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel HighestRegister-ScheduledTask -TaskName "Notifly Swap Check" ` -Action $Action -Trigger $Trigger -Principal $Princ -Description "Notifly: проверка swap/pagefile"- Раннее предупреждение об утечках памяти — растущий swap виден за часы до того, как сработает OOM killer и что-то упадёт.
- Понятная причина тормозов. «Сервер вроде живой, но всё дико медленно» —
почти всегда это активная подкачка;
si/soв сообщении подтверждают догадку сразу. - Трехуровневая логика (
ok→warn→crit) исключает спам: пока уровень не меняется — уведомлений нет.
Что улучшить дальше
Заголовок раздела «Что улучшить дальше»- Прикладывать топ по памяти
ps -eo pid,user,pmem,rss,comm --sort=-rss | head -6, чтобы сразу видеть виновника — передавайте через полеextras. - Алертить не по абсолютному проценту, а по скорости роста swap за последний час — медленно занятый swap на «спящем» сервере часто безобиден.
- Связать порог с приоритетом push-сообщения: днём достаточно тихого уведомления, ночью критичный swap должен будить. Все хосты удобно собрать в один канал мониторинга — hostname уже в заголовке.