Thank you for reading this post, don't forget to subscribe!
Теория
- При возникновении проблемы zabbix сервер должен выполнить bash скрипт, который нам и выполнит всю работу по совершению звонка. Весь необходимый функционал в zabbix уже есть, нам нужно только написать скрипт и всё настроить.
- Bash скрипт генерирует из текста ошибки звуковой WAV файл и CALL файл для Asterisk.
- Bash скрипт загружает по SCP на сервер Asterisk сгенерированные файлы, устанавливает им нужные права, помещает в нужные директории.
- Asterisk совершает звонок и проигрывает сообщение.
Дополнительные условия:
- Bash скрипт должен чистить за собой старые WAV файлы. Call файлы Asterisk почистит сам.
- Bash скрипт не должен звонить слишком часто при массовом сбое. Основная задача — разбудить админов, а не отправить максимальное количество звонков.
- Должны быть логи звонков.
- Должна быть поддержка русского языка.
- Должна быть возможность тонкой настройки для каждого пользователя, о каких триггерах уведомлять по телефону.
Подготовка серверов
WAV файл будем создавать на zabbix сервере, пример:
Для преобразования текста в аудиофайл нам понадобится пакет festival, для поддержки русского языка дополнительно установим festvox-ru:
apt-get install festival festvox-ru
Создаю текстовый файл C:\wav\test.txt с текстом, который нужно преобразовать в WAV.
Содержимое файла test.txt:
В подсистеме Linux он в /mnt/c/wav/test.txt.
Выполняем:
cat /mnt/c/wav/test.txt | /usr/bin/text2wave -f 8000 -eval '(voice_msu_ru_nsh_clunits)' > /mnt/c/wav/test.wav
Немного о параметрах:
- -eval '(voice_msu_ru_nsh_clunits)'
Принудительно включаем поддержку русского языка из пакета festvox-ru. - -f 8000
Выходная частота. Для asterisk следует устанавливать именно 8000.
Получаем нужный нам файл test.wav:
Устанавливаем на zabbix сервере библиотеки:
apt-get install festival festvox-ru uuid
- festival — библиотека для генерации звукового файла из текста.
- festvox-ru — поддержка русского языка для festival.
- uuid — в bash скрипте я использую uuid для генерации уникального имени файла.
В скрипте я буду копировать WAV и CALL файлы на asterisk по SCP. Нужно настроить беспарольный вход по SSH от пользователя zabbix на zabbix сервере пользователю root на asterisk сервере
А если коротко, то на zabbix сервере под рутом:
ssh-keygen
На все вопросы жмём ввод, получаем пару ключей. Копируем публичный ключ на asterisk сервер (он у меня называется freepbx):
scp ~/.ssh/id_rsa.pub root@freepbx:~/.ssh/authorized_keys
Папку .ssh с ключами переношу в домашнюю директорию пользователя zabbix на zabbix сервере, потому что bash скрипт будет выполняться от его имени, и SCP тоже.
Bash скрипт
В настройках zabbix сервера /etc/zabbix/zabbix_server.conf смотрим что написано в параметре AlertScriptsPath:
AlertScriptsPath=/usr/lib/zabbix/alertscripts
Раскомментируйте параметр при необходимости.
У меня скрипт для уведомлений находятся по умолчанию в директории /usr/lib/zabbix/alertscripts. Создаю в ней пустой файл для логов /usr/lib/zabbix/alertscripts/freepbxgate.log, пользователь zabbix должен иметь права на чтение и запись. B создаю bash скрипт /usr/lib/zabbix/alertscripts/freepbxgate.sh. Пользователь zabbix должен иметь права на чтение и выполнение. Содержимое скрипта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#!/bin/bash export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games # ----------------------------------- # настройки # local zabbix server workdir="/tmp" logfile="/usr/lib/zabbix/alertscripts/freepbxgate.log" prefix="zabbix1" prefixname="Сообщ+ение от монит+оринга." # remote asterisk сервер aserver="root@freepbx.domain.local" adir="/tmp" asounds="/var/lib/asterisk/sounds/" aout="/var/spool/asterisk/outgoing/" # ----------------------------------- to=$1 subject=$2 phone=`echo $to | awk -F"/" '{ print $1}'` tags=`echo $to | awk -F"/" '{ print $2}'` #чистим subject txt2wav=$(echo "$subject" | sed -r 's/[\.,\!\?]/ /g' | sed 's/(\([^)]*\))//g' | sed 's/[^0-9a-zA-Zа-яА-ЯёЁ ]//g' | tr -s " " | sed 's/^[ \t]*//;s/[ \t]*$//') # функция генерации и отправки файлов на asterisk callme(){ px=$1 #уникальное имя для wav и call файлов uid=`uuid` fp="${prefix}_${uid}_${phone}" #генерация wav wavfile="${workdir}/${fp}.wav" command1="echo $prefixname $px $txt2wav | /usr/bin/text2wave -F 8000 -eval '(voice_msu_ru_nsh_clunits)' 2>/dev/null > ${wavfile}" echo $command1 | /bin/bash #генерация call callfile="${workdir}/${fp}.call" touch $callfile echo "Channel: Local/$phone@from-internal" > $callfile echo "MaxRetries: 3" >> $callfile echo "RetryTime: 60" >> $callfile echo "WaitTime: 60" >> $callfile echo "Callerid: Wake Up Calls <*68>" >> $callfile echo "Application: Playback" >> $callfile echo "Data: $fp" >> $callfile #Перенос файлов на asterisk scp $wavfile $aserver:$adir scp $callfile $aserver:$adir rm $wavfile rm $callfile ssh $aserver "chown asterisk\: ${adir}/${fp}* && chmod 777 ${adir}/${fp}.wav && mv ${adir}/${fp}.wav ${asounds} && mv ${adir}/${fp}.call ${aout} && find ${asounds} -name '${prefix}*' -type f -mmin +10 -delete" } while IFS=',' read -ra item; do for i in "${item[@]}"; do if grep -q "$i" <<<$subject; then date_now1=`date | awk -F":" '{print $1":"$2}'` date_now2=`date | awk '{print $5,$6}'` msg_count=`tail -n 5000 ${logfile} | grep "${date_now1}" | grep "${date_now2}" | grep "${phone}" | wc -l` date_now=`date` if [ $msg_count -gt 0 ]; then if [ $msg_count -eq 1 ]; then callme "+Очень мн+ого сообщ+ений, ч+асть звонк+ов проп+ущена!" echo "$date_now $to $txt2wav" >> ${logfile} else echo "$date_now $to $txt2wav | не отправлено" >> ${logfile} fi else callme echo "$date_now $to $txt2wav" >> ${logfile} fi fi done done <<< "$tags" |
На вход принимается два параметра:
- Получатель в формате "79990001122/(TAG1),(TAG2),(TAG3)"
- Заголовок триггера, например, "Всё сломалось! (TAG2) Срочно просыпайтесь!"
Получатель состоит из номера мобильного телефона и списка тегов через запятую, тегов может быть много. Тег — это кусок текста из заголовка триггера. Я, например, вставляю в названия триггеров теги вида (WIN) или (LINUX) или (SMS).
Заголовок — это название триггера.
Если у получателя есть тег, который присутствует в тексте заголовка, то получателю будет отправлен звонок на телефон. Если у получателя нет такого тега или тегов, то звонка не будет.
Параметры bash скрипта:
- workdir="/tmp" — директория на zabbix сервере, в которой будут генерироваться WAV и CALL файлы.
- logfile="/usr/lib/zabbix/alertscripts/freepbxgate.log" — лог файл на zabbix сервере.
- prefix="zabbix1" — префикс в названиях файлов. У меня несколько zabbix серверов, для каждого будет уникальный префикс.
- prefixname="Сообщ+ение от монит+оринга." — с этого текста начинается каждый звонок. Плюсы указывают на ударение в слове.
- aserver="root@freepbx.domain.local" — логин и имя сервера asterisk для передачи файлов SCP.
- adir="/tmp" — директория на asterisk сервере, в которую первоначально копируются файлы. В ней им настраиваются права и владелец.
- asounds="/var/lib/asterisk/sounds/" — директория на asterisk сервере, в которую копируются WAW файлы.
- aout="/var/spool/asterisk/outgoing/" — директория на asterisk сервере, в которую копируются CALL файлы.
Если за минуту поступит второй звонок, то в текст добавится "+Очень мн+ого сообщ+ений, ч+асть звонк+ов проп+ущена!", больше в эту минуту звонков не будет, хотя логи продолжат записываться. Думаю, потом я сделаю период звонков побольше.
Параметры CALL файла измените для своих нужд. Например, у меня в качестве Callerid используется существующий Wake Up Calls <*68>, который есть в freepbx для звонков будильника. Если сообщение нужно проиграть три раза, то замените строчку:
echo "Data: $fp" >> $callfile
на
echo "Data: $fp&$fp&$fp" >> $callfile
Настройка zabbix
Administration > Media types. Добавляем новый тип FreePBX Gate.
Настраиваем:
- Name: FreePBX Gate
- Type: Script
-
Configuration > Actions. Создаём Report problems to Zabbix administrators (FREEPBX).
Action — указываем нужные нам условия.
Operations. Здесь можно настроить Subject, именно он будет читаться в телефоне.
Добавляем операцию Send message to user groups: Zabbix administrators via FreePBX Gate.
Здесь нужно указать, что уведомление отправляем через FreePBX Gate.
В Recovery operations можно тоже добавить звонок о том, что проблема устранена, но я убрал эту возможность.
Acknowledgement operations мне тоже не нужно.
Теперь у себя в настройках смотрю раздел Media и добавляю FreePBX Gate 79990001122/(SMS AGENT),(PING),(SMS),(WEB),(VR),(HW),(1C),(WIN),(CRM) 1-7,00:00-24:00 NIWAHD, потом перенастрою на ночь.
Вот пример триггеров, на которые должен отреагировать скрипт:
Текст "(SMS AGENT)" есть в списке моих тегов, поэтому звонок пройдёт.