Добавить в корзинуПозвонить
Найти в Дзене
Записки сисадмина

Linux. Systemd timers. Сообщаем о сбоях через telegram.

Маниакальное желание держать все под контролем. Психологи называют это болезнью. Админы называют это профессиональной деформацией. Я хочу не только чтобы все механизмы работали как часы, но и мгновенно получать уведомления, если хоть одна из шестеренок моих часов дала сбой. Ведь как и с пожаром в здании, намного проще ликвидировать возгорание еще на начальном этапе, чем потом разгребать руины и подсчитывать убытки. Признаюсь, я до жути ленив, и не хочу тратить кучу времени и нервов на полное восстановление завалившихся систем. В прошлых статьях мы разбирались с таймерами systemd и настраивали свой собственный. Но если наш таймер не сможет отработать, мы ничего не узнаем об этом. Пока что не узнаем... В одной из статей мы делали скрипт для оповещений через telegram от zabbix. Используем наши наработки и создадим еще один скрипт. Скрипт будет принимать две переменные:
$1 - telegram id пользователя $2 - текст сообщения (в нашем случае будет передаваться имя сервиса) /etc/systemd/system/se

Маниакальное желание держать все под контролем. Психологи называют это болезнью. Админы называют это профессиональной деформацией. Я хочу не только чтобы все механизмы работали как часы, но и мгновенно получать уведомления, если хоть одна из шестеренок моих часов дала сбой. Ведь как и с пожаром в здании, намного проще ликвидировать возгорание еще на начальном этапе, чем потом разгребать руины и подсчитывать убытки. Признаюсь, я до жути ленив, и не хочу тратить кучу времени и нервов на полное восстановление завалившихся систем.

В прошлых статьях мы разбирались с таймерами systemd и настраивали свой собственный.

Но если наш таймер не сможет отработать, мы ничего не узнаем об этом. Пока что не узнаем...

Начинаем настройку

В одной из статей мы делали скрипт для оповещений через telegram от zabbix. Используем наши наработки и создадим еще один скрипт.

  • Создаем скрипт /usr/local/bin/tg_sender.sh

Скрипт будет принимать две переменные:
$1 - telegram id пользователя

$2 - текст сообщения (в нашем случае будет передаваться имя сервиса)

  • При вызове скрипта и передаче ему имени new_file.service, мы получим сообщение:
-2
  • Создадим сервис systemd, который будет отправлять нам сообщения:

/etc/systemd/system/send_tg_message_to_admin@.service

-3
[Unit]
Description=Send systemd status information via telegram for %i to admin
[Service]
Type=oneshot
ExecStart=/usr/local/bin/tg_sender.sh 111111111 %i
User=root
Group=systemd-journal

Важно:

- Имя "admin" в названии сервиса нужно для идентификации

- В поле ExecStart после вызова скрипта мы должны передать telegram id пользователя

- %i - это имя сервиса, подставится автоматически

Данный сервис вы впоследствии можете повторно использовать в других демонах, т.к. он служит для уведомлений конкретному пользователю.

Если захотите уведомлять другого пользователя, создайте отдельный сервис для этого.

  • Дорабатываем сервис, запускаемый таймером /etc/systemd/system/new_file.service
-4
[Unit]
Description="touch files service"
OnFailure=send_tg_message_to_admin@%n.service
[Service]
Type=oneshot
ExecStart=/root/worker.sh
RemainAfterExit=no
KillMode=process

Строка OnFailure указывает на то, что именно запустить при ошибке сервиса (state=failed), а %n передаст имя сервиса в переменную %i у send_tg_message_to_admin@.service

  • Уведомляем systemd о изменениях и запускаем наш таймер, который запускается раз в секунду:
systemctl daemon-reload
systemctl start new_file.timer
  • Видим, что нам начали приходить уведомления:
-5
  • Немного доработаем наш скрипт:

Во-первых, я хочу видеть время ошибки.

Во-вторых, я хочу краткую сводку от systemd, что именно случилось с сервисом.

-6
#!/bin/bash
token='7593376134:AAExPwpZwz72p2oJP1BM1gadLzpC_rOo-qw'
date=$(date '+%Y-%m-%d-%H:%M:%S')
chat="$1"
message="$(systemctl status --no-pager "$2")"
edited_message=$(echo $message | sed 's/\"/\ /g')
/usr/bin/curl -s --header 'Content-Type: application/json' --request 'POST' \
--data "{\"chat_id\":\"${chat}\",\"text\":\"$2 has failed at $date \n ${edited_message}\"}" "https://api.telegram.org/bot${token}/sendMessage"

"$2 has failed at $date" выдаст нам имя и дату падения сервиса

"${edited_message}" - это вывод статуса сервиса systemd с удаленными кавычками (иначе телеграм неправильно отправляет сообщение)

  • Проверяем, как это работает:
-7

Вывод сообщения вы можете модифицировать сами под свои нужды, при этом сервисы systemd менять уже не придется.

  • Если есть необходимость отправки сообщения нескольким пользователям:
  1. Создаем файл /etc/systemd/system/send_tg_message_to_user@.service
  2. В сервисе new_file.service прописываем:
OnFailure=send_email_to_admin@%n.service send_email_to_user@%n.service