Делаю обработку эвента SNMP_LINK_DOWN, при этом стоит задача сигнализировать при появлении только с определённого интерфейса. Таким образом пытаюсь использовать следующий скрипт по аналогии с https://www.netxms.org/forum/index.php/topic,250.0.html:
sub main()
{
return (%2 == 4227794) ? 1 : 0;
}
где 4227794 - интересующий interface index.
Однако не работает =(
Версия NetXMS 0.2.20
Должно быть
sub main()
{
return ($2 == 4227794) ? 1 : 0;
}
пардон, туплю.
и ещё вопросик по теме - нельзя ли в этом скрипте поменять %m?
вроде EVENT_TEXT есть, можно ли его вернуть?
Поменять нельзя. Но могу это сделать в следующем релизе, технически это не сложно.
думаю это будет полезно: во-первых - чтобы не плодить на каждое событие по action а передавать одному и тому же разные сообщения; во вторых - например пришёл трап с индексом интерфейса, в скрипте этот индекс преобразуем во что-нить более понятное и формируем уже нормальное сообщение об ошибке.
Начиная с версии 0.2.21 это можно делать - в скрипте выставляем переменную CUSTOM_MESSAGE в нужное значение, и потом можем получить его используя макрос %M при создании аларма или actions.
=) только начинаю разбираться в скриптовании, а потому вопросы в основном будут глупыми...
Задача: нужно сделать Правило-ловушку, в которую должны попадаться только события, в которых фигурирует Parameter System.ServiceState(lanmanserver). Остальные События с ошибками от других сервисов должны игнорироваться и проходить на процессинг дальше...
Если я создам такое Правило в EPPE (Event Processing Policy Editor), это должно сработать?:
Source: Any
Event: SYS_SERVICE_DOWN (Major)
Severity: Major
Script:
sub main()
{
return ($2 == System.ServiceState(lanmanserver)) ? 1 : 0;
}
Alarm: указан только параметр "%m"
Situation: нет
Action: 2 реакции
1) отправить почтой оповещение
2) перезапустить сервис "lanmanserver"
Options: нет
Правда возникает вопрос: а как сделать так что бы не происходило двойного срабатывания правил, если есть 2 правила, 1 - Специальное (то, что я привёл выше) и 2 - общее, общего назначения для всех отслеживаемых служб?
Нужно использовать "Options: Stop processing if rule match"?
Все почти правильно. Первый комментарий - по событию: SYS_SERVICE_DOWN - это системное событие, если мониторится что-то через DCI и thresholds - то должно быть какое-то свое событие (это уже обсуждалось где-то на форуме). И если это событие от срабатывания трешолда, то имя параметра DCI будет в первом параметре события, т.е. надо использовать $1 вместо $2. Ну и поскольку это строка, то она должна быть в кавычках. Таким образом, правильный скрипт:
sub main()
{
return $1 == "System.ServiceState(lanmanserver)";
}
или просто
$1 == "System.ServiceState(lanmanserver)"
Я убрал "? 1 : 0", поскольку результатом операции сравнения и так будет 1 или 0.
И да, для прекращения обработки события надо использовать "Options: Stop processing if rule match".
Виктор, спасибо за помощь =)
т.е. мне нужно использовать при генерации события и его обработке только собственное событие и приведённый скрипт?
=)
а чем плох метод использования системного события? ведь по идее таким образом можно было бы минимизировать количество дополнительных событий? а можно поподробнее, почему предложенный мною метод не сработает? ведь обработка Правил идёт сверху вниз и по идее при обработке SYS_SERVIСE_DOWN, дополненного указанным скриптом, именно это Правило должно обрабатывать ВСЕ события, связанные с SYS_SERVIСE_DOWN + System.ServiceState(lanmanserver). а остальные события должны проваливаться по иерархии Правил дальше, пока не будут соответствующим образом обработаны.
у меня предварительно настроено так:
мониторим System.ServiceState(lanmanserver), если получаем 1, то используем событие SYS_SERVIСE_DOWN, если возвращаемся к 0, то SYS_SERVIСE_UP. я просто при разработке этого DCI предположил что именно так и нужно использовать данные события...
мне просто не очень понятно...
=)
и кстати: только что проверил. моя метода + новый скрипт = работают.
Quote from: Anth0ny on January 28, 2009, 09:51:16 AM
а чем плох метод использования системного события? ведь по идее таким образом можно было бы минимизировать количество дополнительных событий? а можно поподробнее, почему предложенный мною метод не сработает? ведь обработка Правил идёт сверху вниз и по идее при обработке SYS_SERVIСE_DOWN, дополненного указанным скриптом, именно это Правило должно обрабатывать ВСЕ события, связанные с SYS_SERVIСE_DOWN + System.ServiceState(lanmanserver). а остальные события должны проваливаться по иерархии Правил дальше, пока не будут соответствующим образом обработаны.
В данном случае все действительно будет работать, поскольку есть дополнительный скрипт для проверки. Просто получится что в разных местах одно и то-же событие обозначает совершенно разные вещи - через год самому можно будет запутаться. А в общем случае получается такая ситуация: сервер генерирует SYS_xxx события в заранее определенных ситуациях, и если их-же использовать в DCI, то потом без использования скриптов невозможно разделить события, созданные сервером по внутренним правилам и по трешолдам. Например, если я определил HTTP сервис на ноде, то если он станет недоступен, сервер создаст событие SYS_SERVICE_DOWN. Если это событие используется и в DCI трешолде, то в event processing policy без скрипта различить их будет нельзя. Ну и текст сообщения для SYS_SERVICE_DOWN определен как
Network service "%1" is not responding
что при использовании в трешолде даст например
Network service "System.ServiceState(lanmanserver)" is not responding
В общем, вывод такой: использовать системные события в трешолдах можно, но не рекомендуется, поскольку конфигурация усложняется, легче допустить ошибку, и возможно появление неожиданных эффектов если где-то недосмотреть.
всё, понял, спасибо за помощь =)
Добрый день!
У нас возник следующий вопрос. Имеется оборудование Хуавей, которое в SNMP-трапах не шлёт ifDescr, а только ifIndex интерфейса. Сейчас пытаемся написать скрипт который бы преобразовывал индекс в дескрипшен, для внятного отображения. Придумали пока что-то типа этого:
sub main()
{
if ($1==770)
$CUSTOM_MESSAGE="FastEthernet 0/3";
return $CUSTOM_MESSAGE;
}
И сделать так для всех существующих у нас индексов. Но этот скрипт у нас не работает. Может подскажете как это организовать. И может это возможно как то более оптимально сделать?
A v kakom meste ispol'zuetsja skript? V event processing policy? Esli da, to on dolzen vozvraschat' 0 ili 1 - 0 oznachaet chto sobitie pod pravilo ne podhodit - 1 - chto podhodit. Custom message nado zadavat' cherez peremennuju CUSTOM_MESSAGE, bez znaka dollara, i potom mozete ispol'zovat' eto znachenie v alarmah i action'ah cherez macros %M. Naprimer:
sub main()
{
if ($1==770)
CUSTOM_MESSAGE="FastEthernet 0/3";
return 1;
}
I ja podumaju kak sdelat', chtobi ne pisat' if dlja kazdogo interfejsa.
Добрый день.
Скрипт используется в event processing policy. Спасибо, сейчас все работает, однако возникло желание уменьшить скрипт. Уж очень он большой получается. Пока что идея выглядит вот так:
sub main()
{
index = 386;
counter = 0;
while (index < 3458)
{
index = index + 128;
counter=counter+1;
if ($2 == index)
{
CUSTOM_MESSAGE="Interface Ethernet0/counter changed state to DOWN";
return 1;
}
}
}
Однако возник вопрос, можно ли значение counter как то поместить в строку?
Dobrij den'!
Znachenie peremennoj counter mozno vstavit' v stroku vot tak:
CUSTOM_MESSAGE="Interface Ethernet0/" . counter . " changed state to DOWN";
A sam skript mozno sokratit' do
sub main()
{
CUSTOM_MESSAGE = "Interface Ethernet0/" . int32(($2 - 386) / 128) . " changed state to DOWN";
return 1;
}
ili, esli trebuetsja proverka chto $2 - eto 386 + chislo, kratnoe 128, i ne previshaet 3458, to:
sub main()
{
if (($2 >= 3458) || (($2 - 386) % 128 != 0))
return 0;
CUSTOM_MESSAGE = "Interface Ethernet0/" . int32(($2 - 386) / 128) . " changed state to DOWN";
return 1;
}