В данной статье пойдет речь о написании модулей под систему мониторинга opsviews. В предыдущей статье шла речь о написании плагина, который будет собирать для нас нужную информацию. Теперь нужно оптимизировать эти данные и выводить в удобном для просмотра виде на нашем мониторинг сервере opsview.
3 Написанные модуля opsviews
Наведу обобщенный алгоритм (шаги) написания и добавления opsview модуля и палигина к Веб-морде системы мониторинга. В дальнейшем можно будет придерживаться данной инструкции и писать более сложные модули и плагины:
- Залить на сервер файлы с кодом модуля (php, html, css файлы и папки)
- В настройках apache прописать алиасы (в зависимости от настроек веб-сервера)
- Добавить новый модуль в Веб-морду opsviews
3.1 Настройка apache
В предыдущей статье я настроил проксирование на apache, теперь нужно добавить URL для нашего модуля, для чего заходим на консоль opsview-server-а.
sudo vim /etc/apache2/sites-enabled/opsview [...] Alias /mtr/ "/usr/local/nagios/share/mtr" # alias # module location # AllowOverride None # Options None Order allow,deny Allow from all [...] ProxyPass /mtr ! # add to proxy [...] sudo /etc/init.d/apache reload</pre>
Теперь мы можем попасть на наш модуль перейдя по URL-у: /mtr (http://192.168.2.120/mtr/)
3.2 Добавляем модуль в Веб-морду opsview
Способ 1:
На сервере в Веб-морде:
- Advanced -> Modules -> Create new module (иконка в виде плюсика);
- Вносим информацию по новом модуле
- Name: test_module
- Namespace: mtr
- Description: My test module
- URL: /mtr/mtr-check.php
- Access:
- Enabled: поставить галочку
Namespace — уникальное им’я (любая бяка).
Теперь в меню Modules увидим наш модуль.
Способ 2:
- В консоли сервера:
su nagios set_module --namespace={ns} --name={name} --enabled={1|0} --description="{value}" --url={url} --access={accesslevel} --version={v}
- В Веб-морде должен появиться модуль в меню Modules
3.3 Заливаем странички с кодом модуля на сервер
mkdir /usr/local/nagios/share/mtr cp mtr-check.php /usr/local/nagios/share/mtr/
Поскольку данный модуль разрабатывался вместе с плагином, про который шла речь в предыдущей статье, в папке mtr лежать только 2 файла: mtr-check.php і style.css. Php-скрипт обрабатывает данные, полученные от плагина check_mtr.sh.
cat mtr-check.php (это было мое первое знакомство с php, по этому, не судите строго):
<!--?php<br /-->//error_reporting(E_ALL); //ini_set("display_errors", 1); define("CRITICAL","bgcolor=#FF0000"); define("OK","bgcolor=#00FF00"); define("WARNING","bgcolor=#ffd700"); define("UNAVAILABLE","bgcolor=FF00FF"); // Seting up warning and critical levels $form = " <form action="testing3.php" method="get"> <table> <tbody> <tr> <td align="right"><span>WARNING</span> level:</td> <td><input name="warning" type="number" value="1" /></td> <td></td> </tr> <tr> <td align="right"><span>CRITICAL</span> level:</td> <td><input name="critical" type="number" value="2" /></td> <td></td> </tr> <tr> <td><input type="submit" value="Apply" /></td> <td></td> </tr> </tbody> </table> </form> "; $warning = ($_GET['warning']); $critical = ($_GET['critical']); if ($warning >= $critical) { echo " <div>ERROR: <span>WARNING</span> value must be less than <span>CRITICAL</span></div> "; echo " <div>Making default...</div> "; $warning = 1; $critical = 2; echo " <div>Default values are : <span>Warning</span> - ".$warning." <span>Critical</span> - ".$critical."</div> "; } else { echo " <div>Current values are : <span>Warning</span> - ".$warning." <span>Critical</span> - ".$critical."</div> "; } // connect to DB $link = mysql_connect("localhost", "root", "alex1989") or die("Could not connect: " . mysql_error()); // choose DB $db_selected = mysql_select_db('runtime', $link); if (!$db_selected) { die ('Can\'t use foo : ' . mysql_error()); } // quary is server down?! $serverStatusQuary = mysql_query(" SELECT `nagios_hoststatus`.`current_state`, `nagios_hosts`.`display_name` FROM `nagios_hosts`, `nagios_hoststatus` WHERE `nagios_hosts`.`host_object_id` = `nagios_hoststatus`.`host_object_id` ORDER BY `nagios_hosts`.`host_object_id` ASC "); if (!mysql_num_rows($serverStatusQuary)) { echo "No rows found, nothing to print so am exiting"; exit; } else { while($items = mysql_fetch_assoc($serverStatusQuary)) { $serverStatusItems[] = $items; } /* echo " <pre>"; print_r($serverStatusItems); echo "</pre> "; */ } // quary is plugin active?! $pluginStatusQuary = mysql_query(" SELECT `name1`, `is_active` FROM `nagios_objects` WHERE (`name2` = 'mtr_plugin') AND ( `name1` = 'client_128' OR `name1` = 'client_127' OR `name1` = 'client_131' OR `name1` = 'opsview') "); if (!mysql_num_rows($pluginStatusQuary)) { echo "No rows found, nothing to print so am exiting"; exit; } else { while($items = mysql_fetch_assoc($pluginStatusQuary)) { $pluginStatus[] = $items; } /* echo " <pre>"; print_r($pluginStatus); echo "</pre> "; */ } // sql query with hostname (opsview hostname), host IP and mtr_plugin.sh perfdate $all_hosts = mysql_query(" SELECT `nagios_objects`.`name1`, `nagios_servicestatus`.`perfdata`, `nagios_hosts`.`address` as `host_ip` FROM `nagios_servicestatus`, `nagios_objects`, `nagios_hosts` WHERE ( `nagios_servicestatus`.`service_object_id` = `nagios_objects`.`object_id` AND `nagios_objects`.`name2` = 'mtr_plugin' AND `nagios_objects`.`name1` = `nagios_hosts`.`display_name` ) AND ( `nagios_objects`.`name1` = 'client_127' OR `nagios_objects`.`name1` = 'client_128' OR `nagios_objects`.`name1` = 'client_131' OR `nagios_objects`.`name1` = 'opsview' ) ORDER BY `nagios_hosts`.`host_object_id` ASC "); if (!$all_hosts) die("Could not query:" . mysql_error()); // check output of query if (!mysql_num_rows($all_hosts)) { echo "No rows found, nothing to print so am exiting"; exit; } else { // put query to array while($item = mysql_fetch_assoc($all_hosts)) { $all_hosts_arr[] = $item; } /* echo " <pre>"; print_r($all_hosts_arr); echo "</pre> "; */ // view all entries foreach($all_hosts_arr as $host) { // if find 'localhost' - replace to 'IP' if($host['host_ip'] == "localhost") $host['host_ip'] = "192.168.2.120"; // split "perfdata" by spaces (by removing spaces) $perfDataValues = preg_split("/[\s]+/",$host['perfdata']); // split previous "perfdata" by '=' (by removing '=') foreach($perfDataValues as $perfDataValue) { $perfDataValue_arr[] = preg_split("/[=]+/", $perfDataValue); } // update value of $host['perfdata'] field $host['perfdata'] = $perfDataValue_arr; // щоб недописувало unset($perfDataValue_arr); // saving updated array $all_hosts_arr_full[] = $host; } /* echo " <pre>"; print_r($all_hosts_arr_full); echo "</pre> "; */ } /* ***** DATA output ***** */ echo ""; echo " <h1> <div>Monitoring table</div></h1> "; echo " "; echo " "; // output of first line of table (hosts IP) for ($i = 0; $i < count($all_hosts_arr_full); $i++) { echo " "; } echo " "; // rest output for ($i = 0; $i < count($all_hosts_arr_full); $i++) { // check if server is ON/OFF if ($serverStatusItems[$i]['current_state'] == '1') { //$serverStatus[] = "server is DOWN"; $serverCellbg = "cellbgNo"; } else { //$serverStatus[] = "server is UP"; $serverCellbg = "cellbgOk"; } // check if plugin is ON/OFF if ($pluginStatus[$i]['is_active'] == '0') { //$pluginIs[] = "plugin OFF"; $cellbackground = "cellbgNo"; } else { //$pluginIs[] = "plugin ON"; $cellbackground = "cellbgOk"; } // hostname output echo " "; // count of perfdata entries in each host for ($j = 0; $j < count($all_hosts_arr_full[0]['perfdata']); $j++) { // diagonal should be empty if ($i == $j) { echo " "; } // check if host is reachable if ($serverStatusItems[$i]['current_state'] == '1' || $all_hosts_arr_full[$i]['perfdata'][$j][1] == "Avg" || $all_hosts_arr_full[$i]['perfdata'][$j][0] == '' || $pluginStatus[$i]['is_active'] == '0') { $all_hosts_arr_full[$i]['perfdata'][$j][1] = "Unavailable"; $status[$j] = UNAVAILABLE; } else { // check AVG volue if ($all_hosts_arr_full[$i]['perfdata'][$j][1] < $warning) { $status[$j] = OK; } else { if (($all_hosts_arr_full[$i]['perfdata'][$j][1] >= $warning) && ($all_hosts_arr_full[$i]['perfdata'][$j][1] < $critical)) { $status[$j] = WARNING; } else { if ($all_hosts_arr_full[$i]['perfdata'][$j][1] >= $critical) { $status[$j] = CRITICAL; } } } } // Avg output echo " "; } // add an empty cell at the end of table if($i == count($all_hosts_arr_full[0]['perfdata'])) echo " "; echo " "; } echo " <table class="main_table" cellspacing="0" cellpadding="0" width="60%" height="30%" align="center" bgcolor="ffffff"> <tbody> <tr> <td></td> <th>".$all_hosts_arr_full[$i]['name1']."</th> <th>Plugin status</th> <th>Server status</th> </tr> <tr> <th>".$all_hosts_arr_full[$i]['name1']."</th> <td></td> <td align="center">".$all_hosts_arr_full[$i]['perfdata'][$j][1]."</td> <td></td> <td class="".$cellbackground.""></td> <td class="".$serverCellbg.""></td> </tr> </tbody> </table> "; // form echo $form; // Free resultset mysql_free_result($all_hosts); // Close connect mysql_close($link);
Таблица стилей style.css:
.cellbgOk { background-image: url(ok.png) ; background-repeat: no-repeat; background-position: center; } .cellbgNo { background-image: url(down.png) ; background-repeat: no-repeat; background-position: center; } body { color: black; font-family:"Segoe UI"; font-size:100% } span { color: red; } .main_table { border: 4px solid black; border-collapse: collapse; } .main_table tr td { padding: 10px 20px; border: 4px solid black; } .main_table tr th { padding: 10px 20px; border: 4px solid black; }
С модулем все готово. Еще можно добавить phpmyadmin для удобной работы с SQL.
3.4 Добавление phpmyadmin
Подключаемся к консоли сервера.
sudo vim /etc/apache2/sites-enabled/opsview [...] Alias /pma/ "/var/www/pma/" Order allow,deny Allow from all [...] ProxyPass /pma ! [...] cd /var/www/pma wget http://sourceforge.net/projects/phpmyadmin/files/phpMyAdmin/3.5.2.2/phpMyAdmin-3.5.2.2-all-languages.tar.gz/download#!md5!86f87e85d9eb6210c7b79d4a4b6efa58 tar xzvf phpMyAdmin-3.5.2.2-all-languages.tar.gz
Теперь, по ссылке http://192.168.2.120/pma будет веб-морда phpmyadmin.
login: mysql-user (ваш логин к БД)
pass: mysql-user-pass (пароль)
Полезные ссылки: http://docs.opsview.org/doku.php?id=developer:menus
Исходники: mtr_module.tar