koalvi.blogspot.com - другой мой блог "сойдет на троечку"

среда, 16 июля 2025 г.

Mikrotik. ROS. Мониторинг состояния хостов по icmp.

 задача по мониторингу состояния хостов в сети древняя, у меня было несколько реализаций, какую-то реализацию делал некий Влад (судя по коду может и не один), но собравший с остатками здравомыслия пришел я к следующему проекту:

1. Перечень хостов и их названий хранится в файле.

2. Мы отслеживаем отключение либо включение хоста в сети (по протоколу icmp)

3. Сообщения "уходят" в телеграмм, так как задач несколько, с ним мы работаем на модульном уровне, как в результат сложилось - используем глобальную переменную для сообщения, а в теле вызываем скрипт.

4. Периодически проверяем состояние и работоспособность самого скрипта, например в начале рабочего времени и в конце.

Программу решил писать не я, а стать архитектором, поручив Искусственному интеллекту реализацию идей, и был я довольно раздосадован....с ROS неважно работает ИИ, а сколько раз он указывал что мой скрипт работать не будет и мне нужно обновиться на 7ю версию ROS и без этого вообще никак.....но результат положительный есть, и опыт у ИИ есть, получал я седые волосы с Gemni и Grok, кстати второй очень неплохо пишет короткий код, а вот в многострочный проектах его дерзость в принятии спорных решений просто убивает желание с ним работать, он тот самый неуч:) который может всё, а вот  Gemni почти наоборот,  и плохо что я не почувствовал явного прогресса от ИИ, иногда приходилось возвращаться по коду, так они не могли воспроизвести уже отработанный рабочий код. Да скрипт в ROS это специфическое, но не Perl и т.п. в конце концов...

начнем:

файл в котором хранятся  данные
=================== host_data.txt ========================
192.168.0.2;comp1
192.168.0.3;comp10

====================================================

файл самого скрипта...
===================skript1

:local filePath "flash/host_data.txt"
:local fileCheckResult [/file find name=$filePath]
:global telegramMessage
:global hostStatus
:if ([:typeof $hostStatus] = "nothing") do={
    :set hostStatus [:toarray ""]
    :local i
    :for i from=0 to=129 do={
        :set ($hostStatus->$i) -1
    }
}
#:log info "MONITORING_START: Skript zapushen dlya monitoringa uzlov i otpravki Telegram."
:if ($fileCheckResult = "") do={
    :set telegramMessage "MONITORING_ERROR: FAIL flash/host_ping.txt NE NAIDEN!"
    :log error $telegramMessage
    :log info "MONITORING_TELEGRAM_FILE_ALERT: Vyzyvayu telegram_api_get dlya faila."
    /system script run telegram_api_get
    :log info "MONITORING_TELEGRAM_FILE_ALERT: telegram_api_get vyzvan dlya faila."
    :return
}
:local fileContent [/file get $filePath contents]
:local remainingContent $fileContent
:local lineCount 0
:local currentLine ""
:local newlinePos 0
:while ([:len $remainingContent] > 0) do={
    :set newlinePos [:find $remainingContent "\n"]
    :if ($newlinePos != -1) do={
        :set currentLine [:pick $remainingContent 0 $newlinePos]
        :set remainingContent [:pick $remainingContent ($newlinePos + 1) [:len $remainingContent]]
#    :log info $newlinePos
    } else={
        :set currentLine $remainingContent
        :set remainingContent ""
    }

    :set lineCount ($lineCount + 1)
    
    # Ïðîïóñêàåì ïóñòûå ñòðîêè
    :if ([:len $currentLine] = 0) do={:continue}

    # Ïðîâåðêà íà ïðåâûøåíèå ìàêñèìàëüíîãî êîëè÷åñòâà ýëåìåíòîâ
    :if ($lineCount > 130) do={
        :set telegramMessage ("MONITORING_ERROR: Prevyøåí limit v 130 uzlov v faile " . $filePath . "!")
        :log error $telegramMessage
        :log info "MONITORING_TELEGRAM_LIMIT_ALERT: Vyzyvayu telegram_api_get dlya oshibki limita."
        /system script run telegram_api_get
        :log info "MONITORING_TELEGRAM_LIMIT_ALERT: telegram_api_get vyzvan dlya oshibki limita."
        :return
    }
    :local ipAddress ""
    :local nodeName ""
    :local semicolonPos [:find $currentLine ";"]
    :if ($semicolonPos != -1) do={
        :set ipAddress [:pick $currentLine 0 $semicolonPos]
        :set nodeName [:pick $currentLine ($semicolonPos + 1) [:len $currentLine]]
#       :log info ("MONITORING_INFO: Obrabotka uzla: " . $nodeName . " (" . $ipAddress . ")")
    } else={
        :set telegramMessage ("MONITORING_WARNING: Nepravilniy format stroki #" . $lineCount . ": '" . $currentLine . "'. Propuskaem.")
#        :log warning $telegramMessage
#        :log info "MONITORING_TELEGRAM_FORMAT_ALERT: Vyzyvayu telegram_api_get dlya oshibki formata."
        /system script run telegram_api_get
#        :log info "MONITORING_TELEGRAM_FORMAT_ALERT: telegram_api_get vyzvan dlya oshibki formata."
        :continue
    }
    :local pingCommandResult [/ping $ipAddress count=3 interface=bridge]
    :local currentStatus
    :if ($pingCommandResult = 0) do={
        :set currentStatus 0
    } else={
        :set currentStatus 1
    }
    :local arrayIndex ($lineCount - 1)
    :local previousStatus ($hostStatus->$arrayIndex)
    :if ($currentStatus != $previousStatus) do={
        :if ($currentStatus = 0) do={
            :set telegramMessage ("MONITORING_ALERT: UZEL NE OTVETCHAET: " . $nodeName . " (" . $ipAddress . ")!")
            /system script run telegram_api_get
        } else={
            :set telegramMessage ("MONITORING_STATUS: UZEL " . $nodeName . " (" . $ipAddress . ") - VOSSTANOVLEN!")
            /system script run telegram_api_get
         }
    } else={
        :if ($currentStatus = 0) do={
#            :log info ("MONITORING_STATUS: UZEL " . $nodeName . " (" . $ipAddress . ") - OSTAYETSYA NEDOSTUPNYM.")
        } else={
#            :log info ("MONITORING_STATUS: UZEL " . $nodeName . " (" . $ipAddress . ") - OSTAYETSYA DOSTUPNYM.")
        }
    }
    :set ($hostStatus->$arrayIndex) $currentStatus
}
#:log info "MONITORING_COMPLETE: Skript zavershen."

========================


:global hostStatus
:if ([:typeof $hostStatus] != "array") do={
    :log warning "UPDATE_HOST_STATUS: non massiv."
    :return
}
:local arrayLength [:len $hostStatus]
:local i 0
:while ($i < $arrayLength) do={
    :local currentValue ($hostStatus->$i)
    :if ($currentValue = 0) do={
        :do {
            :set ($hostStatus->$i) -1
        } on-error={
            :log error "UPDATE_HOST_STATUS: error update"
        }
        :log info "UPDATE_HOST_STATUS: update"
    } else={
        :log info "UPDATE_HOST_STATUS: non update"
    }
    :set i ($i + 1)
}

====================
Дальше думаем о sheduler

Комментариев нет:

Отправить комментарий