Отправка алертов Zabbix в Telegram
Zabbix — самая вменяемая система мониторинга всего, что возможно. Чтобы быстро реагировать на алерты электронная почта не очень подходит, да и почта не всегда может дойти. А телега для этого самое то.
Для отправки алертов в телегу долго использовал свой малюсенький скриптик на баше. Потом через какое-то время появилась встроенная поддержка в самом заббиксе, но по сути делает то же самое.
В некоторых случаях при алертах приходилось залезать в графану и смотреть на графики, чтобы лучше понять проблему. Мысль добавить графики приходила в голову, но как-то думал, что не особо то и нужно. Но оказалось, что многим нужна. Допилил скрипт для отправки еще и графиков + добавил всяких плюшек. Оказалось с графиками стало жить легче 🙂 Скрипт выложен на гитхабе. Дока там есть, но опишу все здесь попонятнее. Настройка будет идти на Debian 11 и Zabbix 6.0.
Установка и настройка скрипта
Для начала нужно установить зависимости:
apt install curl jo jq
Переходим в директорию с кастомными скриптами заббикса:
cd /usr/lib/zabbix/alertscripts
Качаем сам скрипт:
wget https://raw.githubusercontent.com/zevilz/zabbix-alertscript-telegram/main/telegram.sh
Сразу меняем права у скрипта, т.к. там будут важные данные, и делаем его исполняемым:
chmod 700 telegram.sh
chown zabbix:zabbix telegram.sh
Чтобы скрипт мог отправлять в телегу, нужен бот. Зарегистрировать его можно у другого известного официального бота @BotFather. Процесс регистрации описывать не буду, там все просто. Нам для скрипта нужен будет только токен нового бота. Он будет выдан после регистрации бота. Копируем его, открываем скрипт в любом любимом редакторе, вставляем в значение переменной TELEGRAM_BOT_TOKEN полученный токен, сохраняем и выходим.
По дефолту ошибки скрипта будут писаться в /usr/lib/zabbix/alertscripts/zbx_tlg_bot.log
. Если лог нужно писать в другое место, то указываем этот путь в переменной SCRIPT_LOG_PATH
. Файл лога создается автоматически, если его нет. Если юзер zabbix
не сможет его создать, то получим ошибку при тесте отправки.
Не забываем перейти к чату с ботом и стартануть его. Если будете тестить в группе, то нужно добавить в нее бота и дать права на отправку сообщений.
Скрипт уже готов к отправке текстовых сообщений. Теперь нужно добавить новый способ оповещений в Zabbix. Для этого переходим Администрирование
-> Способы оповещений
и там вверху справа жмем на кнопку Создать способ оповещения
.
В окрывшемся окне указываем следующее:
- Имя —
Telegram
- Тип —
Скрипт
- Имя скрипта —
telegram.sh
В параметры скрипта добавляем:
{ALERT.SENDTO}
{ALERT.SUBJECT}
{ALERT.MESSAGE}
Во вкладке Шаблоны сообщений
добавляем нужные шаблоны. Сам текст шаблонов можно скопировать из существующих способов оповещений. Никакого дополнительного форматирования не нужно, просто текст. Дополнительно можно использовать Markdown и накидать смайликов 🙂 Далее тыкаем по кнопке Добавить
.
Шаблоны сообщений также можно задавать непосредственно в действиях триггеров. У них будет больший приоритет, и можно задавать разные шаблоны для разных случаев.
Теперь можно тестить отправку алертов. Для этого тыкаем по Тест
в строке с новым способом оповещения:
В открывшемся окошке указываем свой ID или ID группы телеги (его можно узнать у бота zGetMyID_bot) и жмем на кнопку Тест
. Если все ок, то получим такое уведомление:
А в телегу от бота придет это тестовое сообщение:
А если отправка провалится, то вы где-то накосячили. В уведомлении увидим ошибку, а если ее нет, то смотрим в лог скрипта.
Отправка графиков
Для отправки графиков нам нужен юзер, который будет иметь доступ к API и к графикам нужных хостов в веб-интерфейсе. Скрипт авторизуется в API, получает данные о графике, который привязан к элементу данных в триггере. Если график есть, то авторизуется уже в веб-интерфейсе и дергает сам график. Для этого можно заюзать существующего супер-админа, он имеет доступ ко всему. Но теоретическим не очень безопасно, т.к. его данные для входа будут прописаны в скрипте, а они при определенных обстоятельствах могут утечь. Можно создать для этого обычного юзера с необходимыми правами, но нужно будет ему еще давать права на хосты и группы хостов, что неудобно. Проще всего создать юзера с новой супер-админской ролью, где будут минимальные права и доступ в API только к нужному методу (graph.get
). Например, так:
С юзером определились. Теперь нужно определить необходимые переменные в скрипте:
GRAPHS
— включение отправки графиков, тут ставим1
;GRAPHS_DIR
— полный путь к директории, куда временно будут сохранятся графики (по дефолту пусто, а графики будут сохраняться в директорию
; директория для графиков создается автоматически, если её нет; если юзер/tmp/zbx_graphs
zabbix
не сможет её создать, то получим ошибку при тесте отправки);ZABBIX_URL
— полная ссылка к веб-интерфейсу заббикса (например:https://zabbix.site.com
);ZABBIX_USER
— юзер с доступами к графикам;ZABBIX_PASS
— пароль юзера;ZABBIX_COOKIES_LIFETIME
— время жизни куки авторизации в заббиксе (время жизни куки устанавливается на 14 дней, но они могут истечь раньше этого времени, а без авторизации не получится дергать графики; по дефолту стоит 30 секунд, т.е. переавторизация будет только при простое получения графиков более 30 сек; можно так и оставить);ZABBIX_COOKIES_PATH
— полный путь к файлу куки (по дефолту пусто, а куки будут писаться в директорию скрипта в файл/usr/lib/zabbix/alertscripts/zbx_cookies
; файл с куками создается автоматически, если его нет; если юзерzabbix
не сможет его создать, то получим ошибку при тесте отправки).
Для отправки графиков необходимо добавить вот такую строчку в любое место текста сообщения в нужных шаблонах сообщений (обычно это только тип Проблема
):
<graph:{ITEM.ID1}:1h:900:300>
Где:
{ITEM.ID1}
— родной макрос, куда попадает ID первого итема из выражения триггера;1h
— период, за который нужно получить график относительно текущего времени (может быть числом в секундах либо в относительных величинах:m
— минуты,h
— часы,d
— дни,w
— недели,M
— месяцы,y
— года);900
— кастомная ширина графика;300
— кастомная высота графика.
Ширина и высота необязательны. Если не указывать вообще или указать 0, то размеры будут те, которые указаны в настройках графика в веб-интерфейсе.
Для проверки отправки графиков необходимо вызвать срабатывание любого триггера, где для элемента данных создан график. К примеру, возьмем триггер перегруза CPU. Для этого нагрузим все ядра любого хоста, где активен этот триггер:
openssl speed -multi $(grep -ci processor /proc/cpuinfo)
Через какое-то время (в зависимости от порогов срабатывания триггера) получим алерт с графиком:
Также можно тестить отправку во встроенном тесте способа оповещени. Для этого добавим строку с данными графика в окошко теста ({ITEM.ID1}
нужно будет сменить на реальный ID итема, его можно взять из адресной строки из истории или страницы настройки этого итема) и тыкнуть по кнопке Тест
:
В результате получим тестовое сообщение с графиком:
Для временного отключения графиков не нужно удалять строку с данными графика из шаблона оповещений. Достаточно только установить значение переменной GRAPHS
в 0
. Эта строка удаляется из текста сообщения в любом случае.
Другие переменные скрипта
Во многих триггерах в описании триггера вывожу дополнительные данные и значения итемов в конце сообщения. Бывает полезно получать оперативные данные прямо в алерте. В некоторых шаблонах эти описания могут быть очень длинными (например, ошибки в логах веб-сервера), а у телеги есть ограничения по длине текста в обычных сообщениях (4096 символов) и подписям к изображениям (1024 символа).
Пробовал разбивать сообщения на несколько, но ломается markdown разметка, появляется мешанина из кучи сообщений (особенно если параллельно срабатывают несколько подобных триггеров), да и не особо бывает нужно видеть весь текст. В итоге просто сделал обрезку сообщений. Если сообщение длиньше установленных лимитов, то текст обрезается, а в конце добавляется многоточие.
Максимальная длина текстов задается в переменных скрипта:
TELEGRAM_MESSAGE_LIMIT
— макисмальная длина текстовых сообщений (по дефолту4000
);TELEGRAM_CAPTION_LIMIT
— максимальная длина подписей к графикам (по дефолту900
);
Для лучшего восприятия сообщений описание чаще всего в шаблонах запихиваю в блоки кода (тройной апостроф по краям):
Started: {EVENT.TIME} {EVENT.DATE}
Severity: {EVENT.SEVERITY}
Original problem ID: {EVENT.ID}
```
{TRIGGER.DESCRIPTION}```
Но при обрезке такого сообщения вместе с текстом обрежутся еще и закрывающие апострофы, а телега ругнется на такое сообщение и не отправит его. Для такого случая добавил переменную MONOSPACED_DESCRIPTION
. Если она включена (значение 1
), а очень длинное описание запихнуто в блок кода, то скрипт обрежет текст и корректно завершит блок кода.