Мониторинг с помощью ServiceCheck.HTTP

Started by Anth0ny, June 30, 2008, 10:30:38 AM

Previous topic - Next topic

Anth0ny

Quote from: Victor Kirhenshtein

^HTTP/1\.[01] 200.*<html.*red.* - togda mi budem iskat' slovo red tol'ko posle taga <html>.


Виктор, вопрос:
ServiceCheck.HTTP(10.200.1.100,80,/worktest.html,www.intwww.local,"^HTTP/1\.[01] 200.*<body.*red.*")

я правильно понял Вашу мысль?
будет такой запрос искать слово red начиная с тега <body id="popup"> ?

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


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:x="http://www.w3.org/1999/xhtml" xml:space="x">
<head>
<link rel="stylesheet" type="text/css" href="/css/firefox/main.css" media="screen"/>
<link rel="stylesheet" type="text/css" href="/css/firefox/popup.css" media="screen"/>
<link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" />
<script type="text/javascript" src="/MonoRail/Files/AjaxScripts.visp"></script>
<script type="text/javascript" src="/MonoRail/Files/BehaviourScripts.visp"></script>
<!-- Behaviours -->
<script type="text/javascript">
<!--//--><![CDATA[//><!--
function writeX( parNode, elem, val)
{
            var par = document.getElementById(parNode);
            if( val && par)
            {
                var p = document.createElement( elem);
                try
                {
                    p.innerHTML = val;
                    par.appendChild(p);
                }
                catch(e){}
            }
        }

document.write = function (s)
        {
            writeX( "counters", "span", s);
        }

        function addSpyLog()
        {
            writeX( 'counters', 'span', '<a href="http://u10123.54.spylog.com/cnt?cid=1012354&amp;f=3&amp;p=0" onclick="window.open(this.href); return false;"><img src="http://u10123.54.spylog.com/cnt?cid=1012354&amp;p=0" alt="SpyLOG" border="0" width="88" height="31"/></a>');
        }

function validateMail( mail)
{
var pattern = new RegExp("[\.\-_A-Za-z0-9]+@([\.\-_A-Za-z0-9]+)+(\.[A-Za-z0-9]{2,6})+");
return pattern.test(mail);
}





function getElementsByClass(searchClass,node,tag)
{
var classElements = new Array();
if (node == null) node = document;
if (tag == null) tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++)
{
if (pattern.test(els[i].className) )
{
classElements[j] = els[i];
j++;
    }
}
return classElements;
}

function setCursorPosition(oInput,oStart,oEnd)
    {
        if (oInput.setSelectionRange)
        {
        oInput.setSelectionRange(oStart,oEnd);
        }
        else if (oInput.createTextRange)
        {
                range = oInput.createTextRange();
                range.collapse(true);
                range.moveEnd('character', oEnd);
                range.moveStart('character',oStart);
                range.select();
        }
    }

function focusSearch()
{
var elem = getElementsByClass('textformFields',null,'input');
if (elem.length > 0)
{
elem[0].focus();
setCursorPosition(elem[0], elem[0].value.length, elem[0].value.length);
    }
return true ;
}

function focusFirstField()
{
  var elem = document.getElementsByName("focusField");
  if (elem.length > 0)
  {
  var el = elem[0];
el.focus();
}
      return false;
}

function bannerPublicView()
        {
var publicBanner = document.getElementById('publicBanner');
                      if(publicBanner)
{publicBanner.style.display = "none";}
          }

        function onloadDefault()
{
focusSearch();
    bannerPublicView();
    addSpyLog();
}

    function supportEMailView()
{
var oFrame = $('mailframe');
    if (oFrame)
    {
    var frmHeight = window.innerHeight;
    var frTop = (frmHeight/2-260);
oFrame.style.display = 'block';
oFrame.style.height = '520px';
oFrame.style.width = '520px';
oFrame.style.top = frTop +'px';
oFrame.src="/support/supportframe.visp";
}
return false;
}

//--><!]]>
</script>
</head>
<body id="popup">

<h1>Монитор работоспособности ресурса IQLib</h1>

<h2>Получение файлов из хранилища фондов</h2>
<div class='green'><b>Успешно</b></div>

<h2>Получение файлов из хранилища баннеров</h2>
<div class='green'><b>Успешно</b></div>

<h2>Соединение с SQL-сервером</h2>
<div><b><span class='red'>IQLib.Site: OK</span><br/><span class='green'>IQLib.Site.Sys: OK</span><br/><span class='green'>IQLib.Users: OK</span><br/><span class='green'>IQLib.Statistic.Raw: OK</span><br/></b></div>

<h2>Выполнение запросов к поисковой системе и получение документов</h2>
<div><b><span class='green'>IQLib.XBook: OK</span><br/><span class='green'>IQLib.XRef: OK</span><br/></b></div>

<h2>Выполнение распределенной транзакции SQL-сервером</h2>
<div class='green'><b>Успешно</b></div>

<h2>Тестирование сервисов на сервере приложений</h2>
<div><b><span class='green'>Job: [Days] Garbage Collector: OK</span><br/><span class='green'>Job: [Days] Publishing Remove: OK</span><br/><span class='green'>Job: [Hours] Publishing Add: OK</span><br/><span class='green'>Job: [Hours] Statistic Collector: OK</span><br/><span class='green'>Job: [Minutes] Statistic Collector: OK</span><br/><span class='green'>Job: [Weeks] Statistic Collector: OK</span><br/><span class='green'>Send Message Service: OK</span><br/><span class='green'>User Query Execute Service: OK</span><br/><span class='green'>User Query Notify Service: OK</span><br/></b></div>
<br/>
<p>
<strong>Дата выполнения теста:</strong> 07.07.2008 10:33:01
</p>

<div class="more green" title="Повторить тест"><a href="/monitor/view.visp">Повторить тест</a></div>

</body>
</html>


Как только убираю всё, что завёрнуто в <HEAD>, так запрос начинает работать нормально и обнаруживает слово red на этой странице. В чём может быть проблема, не подскажете?

Я собственно потому и спросил выше, можно ли начать просмотр с тега <body> а не с <html>. Чтобы не парсить заголовок.

Anth0ny

с предыдущей проблемой разобрались: при внимательном осмотре нашего файла в коде был замечен regexp. очевидно NetXMS на может завернуть один regexp в другой (согласен- это очень-очень частный случай, не баг). и изза этого не отрабатывает как положено. пофиксили, убрав из кода страницы лишние элементы (указанные regexp'ы). всё отлично работает.

но в процессе дальнейшего углублённого тестирования столкнулись со следующей проблемой (правда, может это и не проблема а наш собственный косяк, но тогда нужен совет Мастера):

1. мы мониторим веб-страницу при помощи запроса
ServiceCheck.HTTP(10.200.1.100,80,/worktest.html,www.intwww.local,"^HTTP/1\.[01] 200.*<html.*red.*")

2. для обработки ответов сервера на DCI созданы Event'ы, WWW_NOK (Not OK, слово "red" обнаружено, нода переводится в статус Warning) и WWW_OK (слово "red" не обнаружено, нода переводится в статус Normal).

и у нас возникла проблема с процессингом:

условия:

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

- мы НЕ ХОТИМ реагировать на кратковременные ошибки-всплески (в общем случае, при следующем обращении к тестовой странице на ней уже всё хорошо)

- мы НЕ ХОТИМ, чтобы почта отправлялась сразу же после обнаружения на странице слова "red" и перевода ноды в статус Warning (Event = NOK)

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

в соответствии с документацией, мы решили задействовать поле Timeout в Processing Policy и решить данную задачу с его помошью.

для этого мы:

- создали ещё один Event, WWW_WARN (статус - Normal), и прописали его в Procrssing Policy, где для этого Event'а мы указали в Action акцию "mailto" (заранее созданная операция по отправке почтового извещения оператору).

- для Event'а WWW_NOK в поле Seconds ставим значение 300 а в поле Event мы выбираем WWW_WARN

я ведь правильно понимаю, что указав в поле Seconds "300" и указав в поле Event наше событие "WWW_WARN" мы должны получить тот эффект, что при наступлении события WWW_NOK наш DCI с запросом помечается как проблемный, почта отправлена не будет (для WWW_NOK не указана Action), а вот при истечении указанных 300 секунд должно быть обработано событие WWW_WARN и тогда почта будет отправлена?

соответственно, мы должны получить нужный эффект: если в течение указанных 300 секунд статус DCI вернётся к состоянию Normal при помощи события "WWW_OK" , то почта о сбое вообще не будет отправлена, так как согласно нашей логике срабатывание на ошибку будет выглядеть как СЛУЧАЙНОЕ срабатывание на кратковременную проблему (пиковую загрузку) и ошибка сама рассосалась в пределах 300 секунд. Соответственно, ручное вмешательство оператора не требуется. но в логах обнаружение проблемы будет отмечено.

мм... надеюсь понятно объясняю... да-с.

так вот. а что мы имеем на самом деле?

1. при задании в поле Seconds любого значения, не равного "0" срабатывание происходит мгновенно, без указанной отсрочки.

2. какой бы Event мы бы не указывали в поле Event, ВСЕГДА в Event Log'е появляется сообщение, что сработало событие именно SYS_ALARM_TIMEOUIT. и как я уже сказал- срабатывание происходит мгновенно, без учёта поля Seconds.

складывается впечатление, что не срабатывают поля:
Seconds- не даёт отсрочки по запуску ДОПОЛНИТЕЛЬНОГО Event'а
Event - не запускает указанное в нём событие на обработку

соответственно, мы не можем добиться нужного эффекта "ОТЛОЖЕННОГО" извещения (которое не будет выслано, если проблема сама рассосалась в указанные временные рамки в поле Seconds).

дальше-больше =)

пробовал привязать отправку сообщения к этому событию SYS_ALARM_TIMEOUIT, но опять же получаю мгновенную отправку сообщения, а не отложенную на 300 секунд.

кроме того, прошу обратить внимание на то, что для использования поля Timeout обязательно необходимо включить в Alarm'е поле "generate New Alarm", а тогда нода помечается как Outstanding. вопрос в том, как потом ВЫВЕСТИ её из этого состояния? ведь нам нужна только операция по запуску дополнительного события, а не пометка ноды, как сбойной...

А так же есть проблема с ALARM_TIMEOUT: этот Event помечает ноду как Outstanding, а вот автоматического способа вернуть ноду из Outstanding в состояние Normal для этого Event'а мы не нашли...


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

Anth0ny

UP

Виктор, нужна Ваша помощь...

Anth0ny

прошу прощения за настойчивость, но предыдущий вопрос всё ещё актуален.

UP.

Victor Kirhenshtein

V alarm timeout'ah dejstvitel'no bil bag, i ne odin: vo pervih, timeout ne sobljudalsja i srabatival nemedlenno, vo vtorih - vsegda posilalsja event SYS_ALARM_TIMEOUT. Vrode vse ispravil, rabotaet kak nado.

Chto kasaetsja alarmov, kotorie ostajutsja na node, to mozno ved' sdelat' avtomaticheskij terminate cherez kljuchi - ja tak ponjal chto u vas tak i sdelano, chto WWW_OK avtomaticheski terminiruet alarm, sozdannij po WWW_NOK. Pri zelanii vi mozete sdelat' toze-samoe i po WWW_WARN, esli ne hotite chtobi alarm ostavalsja aktivnim posle otsilki meila.


Anth0ny

Виктор, спасибо! =)
Усиленно ждём 0.2.22.

Anth0ny

#21
Виктор, приветствую!

Возникла следующая проблема.

Есть 4 одинаковых web-сервера. На них одинаковая ОС и набор софта. Задача: нужно через ServiceCheck.HTTP мониторить на всех 4ёх серверах один и тот же файл, находящийся у всех серверов в одном и том же месте и называющийся одинаково для всех серверов.

примерно так:

сервера: www01.test.local, www02.test.local, www03.test.local и www04.test.local
файл: /load/test.xml

используемый regexp (для www01.test.local):
ServiceCheck.HTTP(10.101.123.1,80,/load/test.xml,www01.test.local,"^HTTP/1\.[01] 200.*<?xml.*/cross-domain-policy.*")

содержимое страницы (текст):


<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
            <allow-access-from domain="testdom.local" />
            <allow-access-from domain="site.dmz.off" />
<allow-access-from domain="*" />
</cross-domain-policy>


HTTP-заголовок:


http://www01.test.local/load/test.xml

GET /load/test.xml HTTP/1.1
Host: www01.test.local
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.0.1) Gecko/2008070208 Firefox/3.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,ru;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: windows-1251,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Proxy-Connection: keep-alive
If-Modified-Since: Fri, 05 Sep 2008 07:15:29 GMT
Cache-Control: max-age=0

HTTP/1.1 200 OK
Via: 1.1 PROXY
Content-Length: 314
Date: Mon, 08 Sep 2008 05:05:30 GMT
Content-Type: text/xml
Server: nginx/0.5.33
Last-Modified: Fri, 05 Sep 2008 07:15:29 GMT
Accept-Ranges: bytes


Собственно проблема в следующем: на 2 серверах данный запрос получает и обрабатывает данные корректно, а на ещё 2ух- нет. Разницы как я уже сказал между серверами нет. Программно и аппаратно они идентичны.

Не понятно ещё вот что: если regexp на 2ух странных серверах урезать до определения только статуса ответа HTTP (200), то тогда запрос на них работает (получаем "0"). Но как только в запрос добавляется поиск слов в тексте страницы - всё, начинаем получать "3". И никакие ухищрения не помогают =(. Пока есть текст в запросе- запрос всегда выдаёт "3", убираем текст (остаётся только проверка на HTTP-ответ, ищем 200) - всё отлично, "0"...

Повторяюсь: на 2ух серверах полный запрос работает прекрасно!

Виктор, не можем понять что происходит.

Написали скрипт на Unix-сервере, что бы проверить код regexp'а:


if($response=~/^HTTP\/1\.[01] 200.*<?xml.*\/cross-domain-policy.*/s) {

        print "Match!\n";

}


Скрипт говорит что с нашим запросом всё в порядке: полученный от сервера ответ содержит всё необходимое.

Просим помощи...  ???

Alex Kirhenshtein

Я посмотрел в коде - да, есть такая бага. Сейчас несколько переделаю субагента и выложу дифф.

Anth0ny

спасибо, ждём-с =)
а можно рекомпильнуть субагента?

Alex Kirhenshtein

Файл в аттаче. Надо положить в корень дистрибутива (e.g. netxms-0.2.22/) и запустить:
patch -p0 < /путь/к/portcheck.diff

Я погонял на файлах разного размера и с разных серверов - вроде проблем нету.

Про сборку только субагента - если не чистили каталог из которого делали make install - то можно после патча пойти в src/agent/subagents/portCheck и сделать оттуда make install - субагент должен пересобраться и поставиться. Если из чистого дистрибутива - то для ускорения можно сделать configure --with-agent, сборка пройдет быстрее (но foundation libraries и core agent тоже будут собраны - как зависимости).

Anth0ny

аа.. эээ... а если у меня сервер Win32...?
я так вижу что имеется ввиду *nix...

???

Alex Kirhenshtein

Мда, это я не подумал.

Виктор в ближайшее время выложит новый бинарник субагента.

Victor Kirhenshtein

Peresobrannij subagent dlja Windows.

Anth0ny

Спасибо! Залито и проверено- работает так как должно.