У меня есть критическое приложение, которое запускается как служба systemd.
Он настроен на перезагрузку при возникновении сбоя.
Как отправить электронное письмо, если приложение перезапустится?
У меня есть критическое приложение, которое запускается как служба systemd.
Он настроен на перезагрузку при возникновении сбоя.
Как отправить электронное письмо, если приложение перезапустится?
Ответы:
Для начала вам понадобятся два файла: исполняемый файл для отправки почты и .service для запуска исполняемого файла. В этом примере исполняемый файл - это просто скрипт оболочки, использующий sendmail
:
/usr/local/bin/systemd-email:
#!/bin/bash
/usr/bin/sendmail -t <<ERRMAIL
To: $1
From: systemd <root@$HOSTNAME>
Subject: $2
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8
$(systemctl status --full "$2")
ERRMAIL
Какой бы исполняемый файл вы не использовали, он, вероятно, должен принимать как минимум два аргумента, как это делает скрипт оболочки: адрес для отправки и файл модуля для получения статуса. .service
Мы создаем передадим эти аргументы:
/etc/systemd/system/status-email-user@.service:
[Unit]
Description=status email for %i to user
[Service]
Type=oneshot
ExecStart=/usr/local/bin/systemd-email address %i
User=nobody
Group=systemd-journal
Где пользователь - это адрес электронной почты, а адрес - адрес электронной почты этого пользователя. Несмотря на то, что получатель жестко запрограммирован, файл модуля, для которого передается отчет, передается в качестве параметра экземпляра, поэтому эта одна служба может отправлять электронную почту для многих других модулей. На этом этапе вы можете начать status-email-user@dbus.service
проверять, можете ли вы получать электронные письма.
Затем просто отредактируйте сервис, для которого вы хотите получать электронные письма, и добавьте OnFailure=status-email-user@%n.service
его в [Unit]
раздел. %n
передает имя устройства в шаблон.
Источник: archlinux wiki: системные таймеры MAILTO
ExecStartPost
это правильный выбор: он также будет срабатывать после "нормального" запуска, не только в случае сбоя, верно ?
Решение, предложенное @gf_, хорошо сработало для нашей ситуации при использовании clickhouse на CentOS7. Clickhouse несколько регулярно падает на нас, поэтому нам нужно было как перезапустить его автоматически, так и получать уведомления о перезапуске. Хотя добавление второго сервиса в systemd кажется немного неуклюжим, это необходимо из-за дизайна systemd.
При этом это решение в сочетании с автоматическим перезапуском перестало работать для нас, когда мы развернули CentOS8. Это связано с тем, что systemd v239, поставляемый в C8, внес изменение в OnFailure=
семантику в сочетании с нестандартной конфигурацией Restart=
( Restart=on-failure
в нашем случае). Новое OnFailure=
поведение запускает однократную службу только в случае полной перезагрузки, а не только после сбоя. Это более новое поведение с радостью перезапустило бы службу, но мы не получили бы электронное письмо, поскольку OnFailure=
больше не вызывалось.
Обратите внимание на наше основное ожидание: мы хотели, чтобы systemd перезапустил процесс и отправил уведомление по электронной почте. В результате обновления v239 наше предыдущее решение, на которое ссылается gf_, больше не работает. К счастью, мы смогли заставить это работать.
Наше решение - использовать ExecStopPost
для вызова скрипта уведомления по электронной почте. Это работает нормально, но теперь возникла новая проблема: уведомление по электронной почте было отправлено, когда служба clickhouse запускается нормально, например, при запуске сервера. Хотя это и не имеет большого значения, в идеале мы хотели получать уведомления по электронной почте только о сбоях. Мы смогли добиться этого, добавив следующий код в наш почтовый скрипт:
# Don't do anything if the service intentionally stopped successfully.
if [ $SERVICE_RESULT == "success" ]; then
exit
fi
... $SERVICE_RESULT
это переменная окружения, предоставляемая systemd целевому процессу ExecStopPost
. Проверяя success
результат, мы предполагаем, что этот вызов произошел при обычном запуске или завершении работы, и ничего не делаем. При любом другом значении, например signal
, скрипт продолжит отправку электронного письма. Возможные значения этой переменной указаны в документации .
Спасибо gf_ за первоначальное решение. Я надеюсь, что люди найдут мое обновление полезным для CentOS8. Еще несколько ссылок, которые помогли мне:
Вы можете попытаться использовать системную опцию сервиса ExecStartPost.
Описание доступно здесь:
https://www.freedesktop.org/software/systemd/man/systemd.service.html
В файле определения сервиса может быть больше объявлений этой опции. Это срабатывает один за другим.
У вас также будет несколько примеров в вашей системе.
Вы можете создать сценарий оболочки для проверки состояния службы и отправки электронной почты во время загрузки сервера. Эта ссылка может помочь вам