Инструменты пользователя

Инструменты сайта


mikrotik:rb951ui-2nd:routeros:tools:netwatch

Оповещение о восстановлении Интернет-соединения на MikroTik

Прошел тут у нас недавно во Владивостоке ледяной дождь. Небывалых масштабов и разрушений! И, конечно же, пропал Интернет! Вовсе! Надолго!

Первый день я иногда подключался к роутеру и смотрел, а не появился ли он, искомый. Во второй день уже что-то поднадоело! А на третий день появились эти скрипты. 8-) В итоге, через 5 дней мне на почту свалилось уведомление, что Интернет есть и можно расслабиться.

В отличии от полноценного фэйловера, в данном случае я решил использовать утилиту Netwatch из пакета Advanced Tools – во-первых, для разнообразия, а, во-вторых, чтобы не нагружать периодическим выполнением скриптов и так не очень мощный маршрутизатор hAP.

Логика работы

Утилита Netwatch периодически проверяет связь с указанным хостом и, если она пропадает, один раз выполняет инструкции из раздела Down, а когда появляется – один раз из раздела Up.

Эти разделы ссылаются на соответствующие скрипты, которые:

  • при падении связи запоминают дату и время;
  • при восстановлении – отправляют письмо со временем падения и восстановления.

При реализации этого же, но только через скрипты, пришлось бы еще писать счетчик, который подавлял бы выдачу постоянных уведомлений, а так, это не нужно.

Важное замечание

В принципе, в разделах Up и Donw можно расположить сами скрипты, но! У Netwatch есть две проблемы1):

  1. Он не может нормально оперировать глобальными переменными, из-за чего приходится использовать файл для хранения значений. Для этого нужна политика ftp.
  2. Он строго ограничен четырьмя политиками – read,write,test,reboot, а нам нужна еще и ftp!

Поэтому приходится размещать тексты скриптов отдельно и во всех обязательно включать Don't Require Permissions!

Комментарии к коду

Вся эта затея сводится к настройке Netwatch и добавлению двух2) скриптов.

netwatch

Тут все просто – что пингуем3), с какой периодичностью и названия наших скриптов. Таймаут по умолчанию 1000 мс, но я поставил 300 и это нормально работает.

host=8.8.8.8
interval=00:01:00
timeout=300ms
down-script=internet-down
up-script=internet-up

internet-down

Вводим переменные для работы преобразователя даты в нормальную.

:local monthToNum;
:local dateToPick;
:local dateToLog;
:local timeToLog;

Текст, выводящийся в логах, когда Интернет падает.

:local errorTxt "Netwatch определил, что нет Интернета!";

Получаем и преобразовываем дату в нормальный вид. Получаем время.

:set monthToNum {jan="01";feb="02";mar="03";apr="04";may="05";jun="06";jul="07";aug="08";sep="09";oct="10";nov="11";dec="12";};
:set dateToPick [/system clock get date];
:set dateToLog ( [:pick $dateToPick 4 6] . "." . ( $monthToNum -> [:pick $dateToPick 0 3] ) . "." . [:pick $dateToPick 7 11] );
:set timeToLog [/system clock get time];

Пишем в файл дату и время. Если файла нет, создаем его и опять таки пишем в него дату и время. Задержка нужна обязательно, т.к. иначе файл не успевает создаться и… все плохо.

/file {
  :do { set lastInternetStaus.txt contents="$dateToLog $timeToLog";
  } on-error={
    /system routerboard print file="lastInternetStaus";
    :delay 2s;
    set lastInternetStaus.txt contents="$dateToLog $timeToLog";
  }
}

Пишем в лог ошибку о том, что нет Интернета.

:log error ("$errorTxt");

internet-up

Электронный адрес того, кого будем оповещать.

:local myEmail "nikolay@soloshin.su";

Объявляем необходимые переменные.

:local internetStatus;

Поучаем и преобразовываем дату. Получаем время.

:local monthToNum;
:local dateToPick;
:local dateToLog;
:local timeToLog;

:set monthToNum {jan="01";feb="02";mar="03";apr="04";may="05";jun="06";jul="07";aug="08";sep="09";oct="10";nov="11";dec="12";};
:set dateToPick [/system clock get date];
:set dateToLog ( [:pick $dateToPick 4 6] . "." . ( $monthToNum -> [:pick $dateToPick 0 3] ) . "." . [:pick $dateToPick 7 11] );
:set timeToLog [/system clock get time];

Получаем в переменную internetStatus значение из файла, если его нет, создаем его и устанавливаем в значение none, т.е. нет даты и времени предыдущего отключения Интернета – это нужно, т.к. при запуске или перезагрузке устройства Netwatch сразу же проверяет соединение с хостом. По сути, это бонус, позволяющий отслеживать незапланированные перезагрузки роутера.

/file {
  :do { :set internetStatus [ get lastInternetStaus.txt contents ];
  } on-error={
    /system routerboard print file="lastInternetStaus";
    :delay 2s;
    set lastInternetStaus.txt contents="none";
    :set internetStatus "none";
  }
}

Вводим всякие разные тексты.

:local mySubj "Состояние подключения к Интернету ($dateToLog $timeToLog)";
:local myMsg "Доступ к сети Интернет восстановлен в $dateToLog $timeToLog!\r\n\r\nДоступа не было с $internetStatus.";
:local errorTxt "невозможно отправить e-mail для Netwatch";

Отправляем письмо, если ошибка, пишем в лог.

:do { /tool e-mail send to=$myEmail subject=$mySubj body=$myMsg; } on-error={ :log error ("$errorTxt"); }

Сбрасываем значение в файле.

/file set lastInternetStaus.txt contents="none";

Код для импорта

Разработано для RouterOS v6.45.1, проверено на v6.47.8.

netwatch-scripts.rsc
/tool netwatch
add down-script=internet-down host=8.8.8.8 timeout=300ms up-script=\
    internet-up interval=00:01:00
/system script
add dont-require-permissions=yes name=internet-down owner=vasya policy=\
    ftp,read,write source="# Written by Nikolay Soloshin (nikolay@soloshin.su)\
    \_for RouterOS v6.45.1 on hAP (mipsbe) @ 2020.11\r\
    \n\r\
    \n:local monthToNum;\r\
    \n:local dateToPick;\r\
    \n:local dateToLog;\r\
    \n:local timeToLog;\r\
    \n\r\
    \n:local errorTxt \"Netwatch \EE\EF\F0\E5\E4\E5\EB\E8\EB, \F7\F2\EE \ED\E5\
    \F2 \C8\ED\F2\E5\F0\ED\E5\F2\E0!\";\r\
    \n\r\
    \n:set monthToNum {jan=\"01\";feb=\"02\";mar=\"03\";apr=\"04\";may=\"05\";\
    jun=\"06\";jul=\"07\";aug=\"08\";sep=\"09\";oct=\"10\";nov=\"11\";dec=\"12\
    \";};\r\
    \n:set dateToPick [/system clock get date];\r\
    \n:set dateToLog ( [:pick \$dateToPick 4 6] . \".\" . ( \$monthToNum -> [:\
    pick \$dateToPick 0 3] ) . \".\" . [:pick \$dateToPick 7 11] );\r\
    \n:set timeToLog [/system clock get time];\r\
    \n\r\
    \n/file {\r\
    \n  :do { set lastInternetStaus.txt contents=\"\$dateToLog \$timeToLog\";\
    \r\
    \n  } on-error={\r\
    \n    /system routerboard print file=\"lastInternetStaus\";\r\
    \n    :delay 2s;\r\
    \n    set lastInternetStaus.txt contents=\"\$dateToLog \$timeToLog\";\r\
    \n  }\r\
    \n}\r\
    \n\r\
    \n:log error (\"\$errorTxt\");\r\
    \n\r\
    \n# With love from Vladivostok."
add dont-require-permissions=yes name=internet-up owner=vasya policy=\
    ftp,read,write,test source="# Written by Nikolay Soloshin (nikolay@soloshi\
    n.su) for RouterOS v6.45.1 on hAP (mipsbe) @ 2020.11\r\
    \n\r\
    \n:local myEmail \"nikolay@soloshin.su\";\r\
    \n\r\
    \n:local internetStatus;\r\
    \n\r\
    \n:local monthToNum;\r\
    \n:local dateToPick;\r\
    \n:local dateToLog;\r\
    \n:local timeToLog;\r\
    \n\r\
    \n:set monthToNum {jan=\"01\";feb=\"02\";mar=\"03\";apr=\"04\";may=\"05\";\
    jun=\"06\";jul=\"07\";aug=\"08\";sep=\"09\";oct=\"10\";nov=\"11\";dec=\"12\
    \";};\r\
    \n:set dateToPick [/system clock get date];\r\
    \n:set dateToLog ( [:pick \$dateToPick 4 6] . \".\" . ( \$monthToNum -> [:\
    pick \$dateToPick 0 3] ) . \".\" . [:pick \$dateToPick 7 11] );\r\
    \n:set timeToLog [/system clock get time];\r\
    \n\r\
    \n/file {\r\
    \n  :do { :set internetStatus [ get lastInternetStaus.txt contents ];\r\
    \n  } on-error={\r\
    \n    /system routerboard print file=\"lastInternetStaus\";\r\
    \n    :delay 2s;\r\
    \n    set lastInternetStaus.txt contents=\"none\";\r\
    \n    :set internetStatus \"none\";\r\
    \n  }\r\
    \n}\r\
    \n\r\
    \n:local mySubj \"\D1\EE\F1\F2\EE\FF\ED\E8\E5 \EF\EE\E4\EA\EB\FE\F7\E5\ED\
    \E8\FF \EA \C8\ED\F2\E5\F0\ED\E5\F2\F3 (\$dateToLog \$timeToLog)\";\r\
    \n:local myMsg \"\C4\EE\F1\F2\F3\EF \EA \F1\E5\F2\E8 \C8\ED\F2\E5\F0\ED\E5\
    \F2 \E2\EE\F1\F1\F2\E0\ED\EE\E2\EB\E5\ED \E2 \$dateToLog \$timeToLog!\\r\\\
    n\\r\\n\C4\EE\F1\F2\F3\EF\E0 \ED\E5 \E1\FB\EB\EE \F1 \$internetStatus.\";\
    \r\
    \n:local errorTxt \"\ED\E5\E2\EE\E7\EC\EE\E6\ED\EE \EE\F2\EF\F0\E0\E2\E8\
    \F2\FC e-mail \E4\EB\FF Netwatch\";\r\
    \n\r\
    \n:do { /tool e-mail send to=\$myEmail subject=\$mySubj body=\$myMsg; } on\
    -error={ :log error (\"\$errorTxt\"); }\r\
    \n\r\
    \n/file set lastInternetStaus.txt contents=\"none\";\r\
    \n\r\
    \n# With love from Vladivostok."

Политики запуска

Это минимально необходимый набор для работы скрипта.

internet-down internet-up
dont-require-permissions=yes
ftp
read
write
test

Дисклеймер

  • Использование материалов данной базы знаний разрешено на условиях лицензии, указанной внизу каждой страницы! При использовании материалов активная гиперссылка на соответствующую страницу данной базы знаний обязательна!
  • Автор не несет и не может нести какую либо ответственность за последствия использования материалов, размещенных в данной базе знаний. Все материалы предоставляются по принципу «как есть». Используйте их исключительно на свой страх и риск.
  • Все высказывания, мысли или идеи автора, размещенные в материалах данной базе знаний, являются исключительно его личным субъективным мнением и могут не совпадать с мнением читателей!
  • При размещении ссылок в данной базе знаний на интернет-страницы третьих лиц автор не несет ответственности за их техническую функциональность (особенно отсутствие вирусов) и содержание! При обнаружении таких ссылок, можно и желательно сообщить о них в комментариях к соответствующей статье.
1)
Подробнее в официальной wiki или на разных профильных форумах.
2)
Хотелось бы обойтись одним, но передача параметров, как, к примеру, здесь, тут, увы, невозможна!
3)
Я предпочитаю Google DNS, но, вероятно, лучше было бы указать что-то поближе к вашему провайдеру.

Обсуждение

Денис, 2023/01/27 19:35, 2023/01/27 20:15
Добрый день!

Вы сделали очень полезный скрипт, подскажите пожалуйста, как его дополнить, чтобы мне приходила еще информация о том, сколько времени отсутствовал интернет и сколько присутствовал?

$timeToLog-$internetStatus=Разница во времени (как получить это чило?)

Заранее спасибо!
Николай Солошин, 2023/01/27 20:25, 2023/01/27 20:26
Насколько я помню, Микротик возвращает дату-время только в текстовом формате в виде "mar/01/2009" и "20:24:58". В скрипте оно в таком виде и фигурирует, т.е. без дополнительного преобразования с ним работать (складывать, вычитать) невозможно.

Для решения вашей задачи, нужно искать в нете или самостоятельно писать функцию-костыль, которая будет переводить время в unix-формат. Далее все просто - вычитаем и переводим обратно у удобоваримый вид. )
Ваш комментарий:
K B A᠎ K W X V Y V S I T G J A X
 
Последнее изменение: 2022/02/12 11:40 (внешнее изменение)