Идея проекта заключается в оповещении ответственных в порядке их приоритетности по серверам.
Сервис должен собирать информацию о проблемных машинах, т.е. в случае падения нескольких сервисов или серверов втечение некоторого времени (назовем это время временем реакции на пробники, которое задается через веб интерфейсhttps://contacts.kds.corp.hostcomm.ru/cgi-bin/servers_new.pl (по умолчанию равно 100 секунд)), система должна распознать ответственного группы серверов и сформировать один вызов на мобильный телефон. Если абонент отвечает и нажимает цифру 1, тогда вызов считается принятым и ему приходит емейл со списком проблемных серверов. В случае неответа или отказа приниять вызов, система должна впоследствии пересобрать всю информацию о проблемах и вызвать следующего по списку ответственного и т.д. Совершая вызов необходимо сообщить абоненту краткую информацию о случившемся и дождаться реакции абонента.
Для решения такой задачи выбран подход с использованием внешней базы данных nagios_notify, в которой будет храниться информация по ответственным, информация о группах проектов, о всех серверах, о срабатывании пробников (т.е. алертов), о совершении вызовов.
Всё это добро работает на машине contacts.kds.corp.hostcomm.ru. Скрипты написаны на языке perl, веб интерфейсы на perl+javascript. Кого заинтересовало пишите в личку :)
1. Схема БД nagios_notify
1.1 Таблица servers
Таблицы servers, projects, members заполняются вызовом скрипта insert_bd.pl по расписанию.
Данные для таблицы servers берутся из парсинга json странички https://nagios.corp.ru/nagios/cgi-bin/status_new.cgi?style=hostdetail&jsonoutput
Где status_new.cgi - переписанный из исходников и скомпилированный в бинарник программа под нашу версию Icinga 1.9.3 бинарник. Он научен выводить дополнительное поле «notes» в веб интерфейс нагиоса из его файлов конфигурации, в котором будет имя проекта, к которому принадлежит сервер.
status_new.cgi отдает:
{ "cgi_json_version": "1.9.0",
"icinga_status": {
"status_data_age": 56,
"status_update_interval": 15,
"reading_status_data_ok": true,
"program_version": "1.9.3",
"icinga_pid": 48889,
...
},
"status": {
"host_status": [
{ "host_name": "cf19.hc.ru", "host_display_name": ".sweb.ru", "status": "UP", "last_check": "25-09-2015 06:50:47", "duration": "4d 7h 58m 53s", "attempts": "1/3", "state_type": "HARD", "is_flapping": false, "in_scheduled_downtime": false, "active_checks_enabled": false, "passive_checks_enabled": true, "notifications_enabled": true, "has_been_acknowledged": false, "action_url": "https://grapher2.nagios.corp.hostcomm.ru/pnp4nagios/index.php/graph?host=$HOSTNAME$&srv=_HOST_' class='tips' rel='/grapher2/pnp4nagios/index.php/popup?host=$HOSTNAME$&srv=_HOST_", "notes_url": null, "notes": "devops_hc_cpanel", "status_information": "PING OK - Packet loss = 0%, RTA = 1.26 ms"},
{ "host_name": "cf9.hc.ru", "host_display_name": "77.222.32.1", "status": "UP", "last_check": "25-09-2015 06:50:36", "duration": "45d 4h 21m 38s", "attempts": "1/3", "state_type": "HARD", "is_flapping": false, "in_scheduled_downtime": false, "active_checks_enabled": false, "passive_checks_enabled": true, "notifications_enabled": true, "has_been_acknowledged": false, "action_url": null, "notes_url": null, "notes": "devops_hc_cpanel", "status_information": "PING OK - Packet loss = 0%, RTA = 2.62 ms"},
Тут забираем в БД значения полей "host_name" и "notes".
Поле servername таблицы servers уникально, что не дает вставить дубликаты. Изменения в списке, т.е. удаление хоста также реализовано (удаление всех хостов что не в списке).
Для управления временем реакции на пробники по оповещению ответственных есть поле time_konsolid, которые можно изменять через веб интерфейс https://contacts.kds.corp.hostcomm.ru/cgi-bin/servers_new.pl
1.2. Таблица projects
Проекты хранятся в базе LDAP по пути «ou=nagios_responsible,ou=groups,ou=corp,ou=sites,o=hc»
Поле project_name заполняется значением атрибута cn (в данном примере project_name = devops_hc_vps) и оно уникально.
Таблица projects синхронизируется с базой LDAP.
1.3. Таблица members
Таблица заполняется согласно полю uniqueMember проекта в «ou=nagios_responsible,ou=groups,ou=corp,ou=sites,o=hc». Поля email, sip заполняются из ветки LDAP «ou=users,o=hc» по фильтру uid.
Учитываются изменения в LDAP значений email, sip, принадлежность к группе.
Поля name и group_id вместе уникальны.
Присутствует поле weight, которое показывает приоритетность ответственного к проекту.
Поле weight заполняется вручную через веб-интерфейс https://contacts.kds.corp.hostcomm.ru/cgi-bin/weight.pl
1.4. Таблица nagios_ntf (таблица аларминга нагиоса)
Таблица заполняется вызовом скрипта nagios_ntf.pl по событию (т.е. когда срабатывает аларм) в системе nagios.
На вход программы передается тип пробника (т.е. сервис это или хост), статус сервиса/хоста, хостнейм, идентификатор события, название упавшего сервиса (если хост упал то поле пустое):
./nagios_ntf.pl "SERVICE" "PROBLEM" "std.node24.nagios.corp.hostcomm.ru" "APACHE"
Конфигурация Nagios в описании контактов должна иметь следующий вид:
Описание контактов:
define contact{
use contact-by-sip-perl #темплейт
contact_name nagios_notify_sip
}
define contact{
name contact-by-sip-perl ; The name of this contact template
service_notification_period 24x7 ; service notifications can be sent anytime
host_notification_period 24x7 ; host notifications can be sent anytime
service_notification_options c,r
host_notification_options d,r
service_notification_commands notify-service-by-sip-perl ; send service notifications via sip
host_notification_commands notify-host-by-sip-perl ; send host notifications via sip
register 0 ; ITS NOT A REAL CONTACT, JUST A TEMPLATE!
}
define host{
use hostcomm_graph-host-template
host_name nic.ru
contact_groups kds
contacts nagios_notify_sip
notes nagios_sys_infra
}
Передаваемые статусы :
c = notify on CRITICAL service states
r = notify on service recoveries (OK states)
d = notify on DOWN host states
r = notify on host recoveries (UP states)
Таблица заполняется статусами PROBLEM и RECOVERY только для тех хостов, которые входят в группу KDS, и для которых в конфигурации указано поле notes, равное имени проекта.
Пример заполненной таблицы:
id | date_0 | date_1 | type | status | count | contact_group_id |
444362 | 2015-10-29 10:45:41 | 2015-10-29 10:56:25 | SERVICE | PROBLEM | 2 | 2574 |
444362 | 2015-10-29 10:46:27 | NULL | SERVICE | RECOVERY | 1 | 2574 |
444364 | 2015-10-29 10:48:39 | NULL | SERVICE | PROBLEM | 1 | 2574 |
444364 | 2015-10-29 10:49:27 | NULL | SERVICE | PROBLEM | 1 | 2574 |
description | primary_key | asterisk_state | tel_number | date_answer | date_recovery | que_mail |
APACHE | 1262 | 1 | 81234567891 | 2015-10-29 10:50:45 | NULL | 2 |
HTTP | 1263 | -1 | 81234567891 | 2015-10-29 10:50:45 | 2015-10-29 10:55:09 | 2 |
HTTP | 1264 | 1 | 81234567891 | 2015-10-29 10:54:54 | NULL | 2 |
APACHE | 1265 | 1 | 81234567891 | 2015-10-29 10:54:54 | NULL | 2 |
В веб-интерфейсе она выглядит так
servername | date_0 | date_1 | date_recovery | status | description |
fe104.hc.ru | 2015-10-28 16:22:17 | 2015-10-28 16:24:15 | RECOVERY | HTTP | |
std.node24.nagios.corp.hostcomm.ru | 2015-10-28 14:25:22 | 2015-10-28 14:31:25 | RECOVERY | PUPPET | |
kiae.node23.nagios.corp.hostcomm.ru | 2015-10-28 14:25:34 | 2015-10-28 14:31:16 | RECOVERY | PUPPET | |
cf24.hc.ru | 2015-10-28 14:27:43 | RECOVERY | HTTP | ||
fe53.hc.ru | 2015-10-28 15:29:27 | 2015-10-28 15:31:27 | RECOVERY | HTTP |
contact_group_id | project_name | count | tel_number | person | date_answer |
2574 | devops_hc_fe | 1 | 81234567891 | skuleshov | 2015-10-28 16:24:44 |
4985 | devops_infra_nagios | 1 | 81234567891 | skuleshov | 2015-10-28 14:28:35 |
4985 | devops_infra_nagios | 1 | 81234567891 | skuleshov | 2015-10-28 14:28:35 |
2571 | devops_hc_cpanel | 0 | 81234567891 | skuleshov | |
2574 | devops_hc_fe | 1 | 81234567891 | skuleshov | 0000-00-00 00:00:00 |
Где servername – имя сервера; id – это id сервера;date_0 – время первого срабатывания пробника; date_1 – время последнего повторного срабатывания пробника; type – что поломалось: либо сервис либо хост; date_recovery – время, когда сервис/хост стал работоспособным; status – статус (Problem, Recovery); description – описание пробника, для хоста поле пустое; asterisk_state – статус астериска (имеет технологическое значение); contact_group_id – группа контактов проекта; project_name – имя проекта; count – количество срабатываний пробника (показывает сколько раз подряд прилетал статус PROBLEM не становясь ни разу RECOVERY); tel_number – телефонный номер ответственного, ответившенго на звонок подтверждением вызова (тот, кто нажал “1”); person – логин ответственного; date_answer – дата ответа ответственного на звонок; que_mail – значение: 0 – по умолчанию; 1 – звонок был совершен; 2 – по этому пробнику было отправлено письмо ответственному.
2. Совершение вызова ответственному.
Вызовы формирует скрипт alarm.pl, который запускается по крону каждые 2 минуты.
Формируется список контактных групп и список серверов из таблицы nagios_ntf по условию консолидации пробников ( из скрипта: UNIX_TIMESTAMP(date_0)+t_s.time_konsolid<$now_date ).
На основе этого списка для каждой группы совершается вызов ответственному согласно весовой конфигурации, заданной через веб интерфейс https://contacts.kds.corp.hostcomm.ru/cgi-bin/weight.pl
Веса могут иметь значения от 0 и выше. Начинается обзвон с низкого приоритета. Также может быть, что у нескольких ответственных будет один вес, в таком случае абонент выбирается рандомно.
По каждому звонившему абоненту запоминается его статус, и когда по всем отзвонились, система совершает повторный круг и т.д.
Вызов совершается посредством отправки callback файла в систему Asterisk, в котором передается переменная group_id и номер абонента.
Примерный callback файл выглядит так:
# cat /tmp/nagios/2574.call
Channel: SIP/81234567891@reconn
CallerID: 4955555555
MaxRetries: 3
RetryTime: 10
WaitTime: 40
Context: nagios_auto
Extension: s
Priority: 1
Set: group_id=2574
Set: dst=81234567891
Set: src=37927
AlwaysDelete: Yes
Asterisk получив файл callback совершает вызов (dial) на номер абонента. Затем ждет, что наберет вызываемый абонент после ответа на звонок:
0 – "не могу" – ответственный не готов поработать;
1- "могу" – ответственный готов взяться за работу;
и если ничего не набрал или не дозвонились - "-1";
Данные о текущем состоянии вызова содержатся в перезаписываемой таблице dialer
id | group_id | file | status | count | date_0 | date_1 | sip_number | servers |
16 | 4985 | 0 | 1 | 2015-10-28 14:28:01 | 2015-10-28 14:28:35 | 81234567891 | kiae.node23.nagios.corp.hostcomm.ru, std.node24.nagios.corp.hostcomm.ru |
|
17 | 2574 | -1 | 2 | 2015-10-29 11:12:02 | 2015-10-29 11:15:03 | 81234567891 | fe105.hc.ru |
Тому абоненту, который нажмет “1” придет e-mail уведомление со списком проблемных серверов.Где group_id – номер группы проекта; status – статус вызова(0,-1,1); date_0 – время совершения вызова; date_1 – время ответа; sip_number -номер абонента; servers – список серверов, по которым звонили(не используется это поле).
За это отвечает скрипт send_email.pl (вызывается по крону каждые 30сек): для каждой группы ответственных формируется список серверов, по которым надо звонить исходя из таблицы nagios_ntf полей que_mail=1 и status=PROBLEM. Если в это время все сервисы по которым звонили поднялись, то в сообщении так и будет указано, что всё ок.
Вот и всё, теперь у нас есть автоматическая звонилка по пробникам.
Если кого-то этот проект заинтересовал и хотелось бы поработать с ним, то прошу обращаться в личку, подумаем чем вам помочь :)
Обновлено 05.04.2016 15:21