Тут показані розбіжності між вибраною ревізією та поточною версією сторінки.
Порівняння попередніх версій Попередня ревізія | Попередня ревізія Наступна ревізія По сторонах наступні версії | ||
watchdog [2019/12/11 12:54] |
watchdog [2023/01/22 10:02] nightfly [Собака-спостерігака aka Watchdog] |
||
---|---|---|---|
Рядок 1: | Рядок 1: | ||
+ | ====== Собака-спостерігака aka Watchdog ====== | ||
+ | {{: | ||
+ | |||
+ | Собака-спостерігака призначена для < | ||
+ | |||
+ | ===== Можливі перевірки ===== | ||
+ | |||
+ | ^ Типи задач | ||
+ | | icmpping | ||
+ | | tcpping | ||
+ | | udpping | ||
+ | | hopeping | ||
+ | | script | ||
+ | | httpget | ||
+ | | getusertraff | отримання кількості трафіку в байтах логіну користувача вказаного в параметрі | ||
+ | | fileexists | ||
+ | | opentickets | ||
+ | | onepunch | ||
+ | | snmpwalk | ||
+ | | freediskspace | Повертає кількість вільного місця на розділі (точці монтування) вказаній в параметрі. Повертає цифру в Гб. | float | | ||
+ | |||
+ | |||
+ | ===== Можливі оператори для перевірок ===== | ||
+ | |||
+ | ^ Оператор | ||
+ | | =true | Істинно | ||
+ | | =false | ||
+ | | == | Рівне | ||
+ | | != | Не рівне | ||
+ | | > | Більше | ||
+ | | < | Менше | ||
+ | | > = | Більше або рівне | + | | ||
+ | | < = | Менше або рівне | ||
+ | | empty | Пустий результат | | | ||
+ | | notempty | ||
+ | | changed | ||
+ | | notchanged | ||
+ | | like | Містить | ||
+ | | notlike | ||
+ | | rised | Збільшилось | ||
+ | | decreased | ||
+ | |||
+ | |||
+ | ===== Дії що будуть виконані у разі проходження умов ===== | ||
+ | |||
+ | ^ Дії | ||
+ | | log | запис події в системний лог | ||
+ | | sms | надсилання SMS сповіщення на номери стільникових, | ||
+ | | noprimary | ||
+ | | email | надсилання сповіщення електропоштою, | ||
+ | | telegram | ||
+ | | no_tg_primary | ||
+ | | andresult | ||
+ | | oldresult | ||
+ | | script | ||
+ | |||
+ | ===== Логіка роботи ===== | ||
+ | |||
+ | Кожне завдання для Собаки-спостерігаки слід сприймати як " | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | Гугл не пингается | icmpping | ||
+ | |||
+ | При обнаружении того, что ping на адрес 8.8.8.8 вернул значение " | ||
+ | |||
+ | А что делать, | ||
+ | ^ Активный ^ Имя | ||
+ | | X | Чего-то изменилось | icmpping | ||
+ | |||
+ | |||
+ | В принципе никто не запрещает нам делать и задачи такого плана: | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | В серверной пожар | script | ||
+ | |||
+ | |||
+ | Вызывая внешний скрипт, | ||
+ | |||
+ | Если творчески подойти к парсингу вывода внешнего ПО - можно мониторить много интересных вещей без дописывания внешних скриптов: | ||
+ | ^ Активный ^ Имя | ||
+ | | X | DNS сломался | ||
+ | |||
+ | Также мы можем очень просто и элегантно контролировать запущенность важных сервисов типа stargazer создав задачу такого плана: | ||
+ | ^ Активный ^ Имя | ||
+ | | X | Stargazer упал | ||
+ | |||
+ | Хотя ту же самую по сути задачу мы можем оформить как | ||
+ | ^ Активный ^ Имя | ||
+ | | X | Stargazer упал | ||
+ | |||
+ | |||
+ | Чтобы не сосредотачиваться на тривиальных вещах, мы можем предусмотреть ситуацию, | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | Важный клиент подох | getusertraff | ||
+ | |||
+ | Окей, а если мы хотим также эту же СМС-ку послать скажем администратору этого же важного клиента, | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | Важный клиент подох | getusertraff | ||
+ | |||
+ | |||
+ | а если мы хотим послать СМС только на дополнительный номер? Да, без проблем: | ||
+ | | ||
+ | log, | ||
+ | | ||
+ | |||
+ | |||
+ | |||
+ | а если мы хотим послать алерт только в дополнительный/ | ||
+ | | ||
+ | log, | ||
+ | | ||
+ | |||
+ | |||
+ | а можно миксовать СМС и Telegram? Да вообще без проблем: | ||
+ | | ||
+ | log, | ||
+ | | ||
+ | |||
+ | |||
+ | Хотя опять же никто не запрещает нам, скажем мониторить этого клиента скажем внешним скриптом запрашивающим по SNMP состояние порта или счетчик трафика на свиче, куда он воткнут, | ||
+ | |||
+ | А еще мы, можем реагировать не только на изменения текущих значений относительно каких-то порогов, | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | Ошибки полезли | onepunch | ||
+ | |||
+ | Ну либо какой-то уровень роста ошибок мы считаем допустимым, | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | Ошибки полезли резво | onepunch | ||
+ | |||
+ | Также мы можем таким способом отлавливать либо резкие всплески либо падения утилизации, | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | Канал разогнался как-то | onepunch | ||
+ | |||
+ | Ну или наоборот резкие падения относительно предыдущих значений (типа утилизация аплинка провалилась на 20 гиг от последнего запуска собаки) | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | Трафик рухнул куда-то | onepunch | ||
+ | |||
+ | А еще мы можем очень просто проверять рабочесть сервисов которые должны слушать соединения на какие-то TCP или UDP порты, типа так | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | http на хосте | tcpping | ||
+ | |||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | https на хосте | tcpping | ||
+ | |||
+ | ^ Активный ^ Имя | ||
+ | | X | syslogd на хосте | udpping | ||
+ | |||
+ | |||
+ | А еще мы можем получать и проверять любые данные, | ||
+ | ^ Активный ^ Имя | ||
+ | | X | Версия OS | snmpwalk | ||
+ | |||
+ | Или банально нотифицировать себя о том, что в корневом разделе заканчивается место | ||
+ | ^ Активный ^ Имя | ||
+ | | X | Место в корне заканчивается | freediskspace | ||
+ | |||
+ | ===== Отсылка SMS ===== | ||
+ | Не требует включенного модуля рассылки [[turbosms|TurboSMS]]. Весь функционал отправки реализован посредством подсистемы [[senddog|" | ||
+ | |||
+ | ===== Отсылка Telegram ===== | ||
+ | Осуществляется тоже при проходе " | ||
+ | |||
+ | ===== Примеры скриптов ===== | ||
+ | Как уже говорилось выше, при помощи собаки-наблюдаки, | ||
+ | |||
+ | ==== Получение трафика с порта свитча ==== | ||
+ | <file php switch_traffic> | ||
+ | # | ||
+ | <?php | ||
+ | |||
+ | //config section | ||
+ | $port=' | ||
+ | $oid=' | ||
+ | $ip=' | ||
+ | $community=' | ||
+ | //end of config | ||
+ | |||
+ | $cmd='/ | ||
+ | $raw=shell_exec($cmd); | ||
+ | $newTime=time(); | ||
+ | if (!empty($raw)) { | ||
+ | $raw=explode(' | ||
+ | $raw=trim($raw[1]); | ||
+ | if (!empty($raw)) { | ||
+ | $cacheName=dirname(__FILE__).'/ | ||
+ | if (file_exists($cacheName)) { | ||
+ | $oldTime=filemtime($cacheName); | ||
+ | $oldOctets=file_get_contents($cacheName); | ||
+ | $traffDiff=$raw-$oldOctets; | ||
+ | $timeDiff=$newTime-$oldTime; | ||
+ | if ($timeDiff!=0) { | ||
+ | $speed=($traffDiff*8*100)/ | ||
+ | print(round($speed/ | ||
+ | } else { | ||
+ | print(' | ||
+ | } | ||
+ | file_put_contents($cacheName, | ||
+ | } else { | ||
+ | file_put_contents($cacheName, | ||
+ | print(' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Снятие температуры с eping3 ==== | ||
+ | |||
+ | <file php eping_temp> | ||
+ | # | ||
+ | <?php | ||
+ | |||
+ | $ip=' | ||
+ | $community=' | ||
+ | $oid=' | ||
+ | $result=0; | ||
+ | |||
+ | |||
+ | $command='/ | ||
+ | $resultRaw=shell_exec($command); | ||
+ | if (!empty($resultRaw)) { | ||
+ | $result=explode(' | ||
+ | $result=(isset($result[1])) ? $result[1] : 0; | ||
+ | $result=$result/ | ||
+ | } | ||
+ | |||
+ | print($result); | ||
+ | </ | ||
+ | |||
+ | ==== Наличие электропитания с eping3 ==== | ||
+ | |||
+ | <file php eping_power> | ||
+ | # | ||
+ | <?php | ||
+ | |||
+ | $ip=' | ||
+ | $community=' | ||
+ | $oid=' | ||
+ | $result=0; | ||
+ | |||
+ | |||
+ | $command='/ | ||
+ | $resultRaw=shell_exec($command); | ||
+ | if (!empty($resultRaw)) { | ||
+ | $result=explode(' | ||
+ | $result=(isset($result[1])) ? $result[1] : 0; | ||
+ | $result=($result==1) ? ' | ||
+ | } | ||
+ | |||
+ | print($result); | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Количество свободного места в /var/ ==== | ||
+ | |||
+ | <file php var_stat> | ||
+ | # | ||
+ | <?php | ||
+ | $result=disk_free_space("/ | ||
+ | $result=$result/ | ||
+ | $result=round($result, | ||
+ | |||
+ | print($result); | ||
+ | ?> | ||
+ | </ | ||
+ | |||
+ | ==== Джиттер до гугла ==== | ||
+ | |||
+ | <file bash check_icmp_google> | ||
+ | #!/bin/sh | ||
+ | ping -c 1 8.8.8.8 | head -n 2 | tail -n 1 | awk -F " | ||
+ | </ | ||
+ | |||
+ | ==== Хешрейт на ethermine.org ==== | ||
+ | |||
+ | <file php ethereum_hashrate> | ||
+ | # | ||
+ | <?php | ||
+ | |||
+ | $wallet=' | ||
+ | $workersStatsUrl = ' | ||
+ | $jsonRaw = file_get_contents($workersStatsUrl); | ||
+ | $reportedHashrate = 0; | ||
+ | |||
+ | if (!empty($jsonRaw)) { | ||
+ | $workersStats = json_decode($jsonRaw, | ||
+ | if (!empty($workersStats)) { | ||
+ | foreach ($workersStats[' | ||
+ | $reportedHashrate+=$each[' | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | print(round($reportedHashrate/ | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== PPS на интерфейсе ==== | ||
+ | |||
+ | <file bash stat_pps> | ||
+ | #!/bin/sh | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Утилизация CPU Linux хоста ==== | ||
+ | |||
+ | <file php lin_cpustats> | ||
+ | # | ||
+ | <?php | ||
+ | |||
+ | /** | ||
+ | CPU Statistics | ||
+ | |||
+ | Load | ||
+ | 1 minute Load: .1.3.6.1.4.1.2021.10.1.3.1 | ||
+ | 5 minute Load: .1.3.6.1.4.1.2021.10.1.3.2 | ||
+ | 15 minute Load: .1.3.6.1.4.1.2021.10.1.3.3 | ||
+ | |||
+ | CPU | ||
+ | percentage of user CPU time: .1.3.6.1.4.1.2021.11.9.0 | ||
+ | raw user cpu time: .1.3.6.1.4.1.2021.11.50.0 | ||
+ | percentages of system CPU time: .1.3.6.1.4.1.2021.11.10.0 | ||
+ | raw system cpu time: .1.3.6.1.4.1.2021.11.52.0 | ||
+ | percentages of idle CPU time: .1.3.6.1.4.1.2021.11.11.0 | ||
+ | raw idle cpu time: .1.3.6.1.4.1.2021.11.53.0 | ||
+ | raw nice cpu time: .1.3.6.1.4.1.2021.11.51.0 | ||
+ | |||
+ | */ | ||
+ | $oid=' | ||
+ | $ip=' | ||
+ | $community=' | ||
+ | //end of config | ||
+ | |||
+ | $cmd='/ | ||
+ | $raw=shell_exec($cmd); | ||
+ | $newTime=time(); | ||
+ | if (!empty($raw)) { | ||
+ | $raw=explode(' | ||
+ | $raw=trim($raw[1]); | ||
+ | if (!empty($raw)) { | ||
+ | print($raw); | ||
+ | } else { | ||
+ | print(' | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ===== Использование One-Punch скриптов ===== | ||
+ | |||
+ | Еще более предпочтительным, | ||
+ | |||
+ | - Они храняться в вашей БД и переезжают всегда вместе с ней | ||
+ | - Они выполняются внутри Ubilling и имеют прямой доступ ко всему его функционалу | ||
+ | |||
+ | ===== Как это работает? | ||
+ | |||
+ | Допустим берем и создаем [[onepunch|One-Punch]] скрипт следующего вида: | ||
+ | |||
+ | <code php> | ||
+ | $watchdogCallbackResult=' | ||
+ | </ | ||
+ | |||
+ | Вот как-то так | ||
+ | |||
+ | {{: | ||
+ | |||
+ | И допустим мы хотим контролировать не изменятся ли данные возвращаемые этим скриптом (с чего-бы это? ;) | ||
+ | |||
+ | {{: | ||
+ | |||
+ | |||
+ | |||
+ | Надеюсь очевидно, | ||
+ | \\ | ||
+ | Также есть еще одно небольшое ограничение относящееся не только к данным возвращаемым One-Punch скриптами, | ||
+ | |||
+ | ==== Трафик с порта ==== | ||
+ | |||
+ | |||
+ | Вот например то же самое снятие данных о трафике с порта, но в виде One-Punch скрипта: | ||
+ | |||
+ | <code php> | ||
+ | //config section | ||
+ | $port=' | ||
+ | $oid=' | ||
+ | $ip=' | ||
+ | $community=' | ||
+ | //end of config | ||
+ | |||
+ | $cmd='/ | ||
+ | $raw=shell_exec($cmd); | ||
+ | $newTime=time(); | ||
+ | if (!empty($raw)) { | ||
+ | $raw=explode(' | ||
+ | $raw=trim($raw[1]); | ||
+ | if (!empty($raw)) { | ||
+ | $cacheName=' | ||
+ | if (file_exists($cacheName)) { | ||
+ | $oldTime=filemtime($cacheName); | ||
+ | $oldOctets=file_get_contents($cacheName); | ||
+ | $traffDiff=$raw-$oldOctets; | ||
+ | $timeDiff=$newTime-$oldTime; | ||
+ | if ($timeDiff!=0) { | ||
+ | $speed=($traffDiff*8*100)/ | ||
+ | $watchdogCallbackResult=round($speed/ | ||
+ | } else { | ||
+ | $watchdogCallbackResult=' | ||
+ | } | ||
+ | file_put_contents($cacheName, | ||
+ | } else { | ||
+ | file_put_contents($cacheName, | ||
+ | $watchdogCallbackResult=' | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Свободное место на диске ==== | ||
+ | |||
+ | <code php> | ||
+ | $result=disk_free_space("/" | ||
+ | $result=$result/ | ||
+ | $watchdogCallbackResult=round($result, | ||
+ | </ | ||
+ | |||
+ | ==== Load Average удаленного Linux хоста ==== | ||
+ | |||
+ | <code php> | ||
+ | $oid = ' | ||
+ | $ip = ' | ||
+ | $community = ' | ||
+ | |||
+ | |||
+ | $cmd = '/ | ||
+ | $raw = shell_exec($cmd); | ||
+ | $watchdogCallbackResult = ''; | ||
+ | if (!empty($raw)) { | ||
+ | $raw = explode(' | ||
+ | $raw = trim($raw[1]); | ||
+ | if (!empty($raw)) { | ||
+ | $watchdogCallbackResult .= $raw; | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Мониторинг isc-dhcpd ==== | ||
+ | |||
+ | <code php> | ||
+ | $command=' | ||
+ | $result=shell_exec($command); | ||
+ | if (!empty($result)) { | ||
+ | $watchdogCallbackResult=' | ||
+ | } else { | ||
+ | $watchdogCallbackResult=' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ==== Мониторинг TrassirServer ==== | ||
+ | <code php> | ||
+ | $watchdogCallbackResult = ''; | ||
+ | $dvrs = new NyanORM(' | ||
+ | $dvrs-> | ||
+ | $allDvrs = $dvrs-> | ||
+ | |||
+ | if (!empty($allDvrs)) { | ||
+ | foreach ($allDvrs as $io => $each) { | ||
+ | $dvrName = $each[' | ||
+ | $trassir = new TrassirServer($each[' | ||
+ | $health = $trassir-> | ||
+ | if (!$health[' | ||
+ | $watchdogCallbackResult .= $dvrName . ' - FAILS '; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Мониторинг температуры на Equicom PING3 ==== | ||
+ | <code php> | ||
+ | $ip = ' | ||
+ | $community = ' | ||
+ | $oid = ' | ||
+ | $correction = 0; | ||
+ | |||
+ | |||
+ | $snmp = new SNMPHelper(); | ||
+ | $resultRaw = $snmp-> | ||
+ | $watchdogCallbackResult = 0; | ||
+ | if (!empty($resultRaw)) { | ||
+ | $watchdogCallbackResult = zb_SanitizeSNMPValue($resultRaw) / 10; | ||
+ | $watchdogCallbackResult = $watchdogCallbackResult + $correction; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Мониторинг наличия питания на Equicom PING3 === | ||
+ | <code php> | ||
+ | $ip = ' | ||
+ | $community = ' | ||
+ | $oid = ' | ||
+ | $result = 0; | ||
+ | |||
+ | |||
+ | $snmp = new SNMPHelper(); | ||
+ | $resultRaw = $snmp-> | ||
+ | $watchdogCallbackResult = 0; | ||
+ | if (!empty($resultRaw)) { | ||
+ | $watchdogCallbackResult = zb_SanitizeSNMPValue($resultRaw); | ||
+ | $watchdogCallbackResult = ($watchdogCallbackResult == 1) ? ' | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ==== Мониторинг температур на OLT-ах === | ||
+ | |||
+ | <code php> | ||
+ | $criticalTemp = 70; | ||
+ | |||
+ | $watchdogCallbackResult = ''; | ||
+ | $tempPath = OLTAttractor:: | ||
+ | $tempExt = OLTAttractor:: | ||
+ | |||
+ | $switchesDb = new nya_switches(); | ||
+ | $switchesDb-> | ||
+ | $allOlt = $switchesDb-> | ||
+ | |||
+ | foreach ($allOlt as $io => $eachOltData) { | ||
+ | $tempData = $tempPath . $eachOltData[' | ||
+ | if (file_exists($tempData)) { | ||
+ | $oltTemp = file_get_contents($tempData); | ||
+ | if ($oltTemp >= $criticalTemp) { | ||
+ | $watchdogCallbackResult .= $eachOltData[' | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | | ||
+ | if (empty($watchdogCallbackResult)) { | ||
+ | $watchdogCallbackResult=' | ||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | ==== Нагадування про оплату TurboSMS === | ||
+ | |||
+ | <code php> | ||
+ | // ключ HTTP API | ||
+ | $apiKey = ' | ||
+ | // поріг коштів після якого нотифікувати | ||
+ | $lowerLimit = 4000; | ||
+ | |||
+ | $apiCallback = ' | ||
+ | $turboSmsApi = new OmaeUrl($apiCallback); | ||
+ | $turboSmsApi-> | ||
+ | $balanceRaw = $turboSmsApi-> | ||
+ | | ||
+ | $watchdogCallbackResult = ''; | ||
+ | if (!empty($balanceRaw)) { | ||
+ | @$balanceRaw = json_decode($balanceRaw, | ||
+ | if (!empty($balanceRaw)) { | ||
+ | if (isset($balanceRaw[' | ||
+ | if (isset($balanceRaw[' | ||
+ | $balance = $balanceRaw[' | ||
+ | if ($balance> | ||
+ | $watchdogCallbackResult.=' | ||
+ | } else { | ||
+ | $watchdogCallbackResult.=' | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </ |