如果重新启动 systemd 服务,如何发送电子邮件?

Gre*_*reg 15 linux systemd

我有一个由 systemd 作为服务运行的关键应用程序。

它设置为一旦出现故障就重新启动。

如果应用程序重新启动,如何发送电子邮件?

gf_*_*gf_ 26

首先,您需要两个文件:一个用于发送邮件的可执行文件和一个用于启动可执行文件的 .service。对于此示例,可执行文件只是一个使用sendmail以下命令的 shell 脚本:

/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
Run Code Online (Sandbox Code Playgroud)

无论您使用什么可执行文件,它都应该像这个 shell 脚本一样至少使用两个参数:要发送到的地址和要获取状态的单元文件。在.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
Run Code Online (Sandbox Code Playgroud)

其中user是通过电子邮件发送的用户,address是该用户的电子邮件地址。尽管收件人是硬编码的,但要报告的单元文件作为实例参数传递,因此这一服务可以为许多其他单元发送电子邮件。此时,您可以开始status-email-user@dbus.service验证是否可以接收电子邮件。

然后只需编辑您想要为其发送电子邮件的服务并添加OnFailure=status-email-user@%n.service到该[Unit]部分。%n将单元的名称传递给模板。

来源:archlinux wiki:systemd timers MAILTO


Ant*_*yen 10

@gf_ 提出的解决方案适用于我们在 CentOS7 上运行 clickhouse 的情况。Clickhouse 经常在我们身上崩溃,所以我们需要让它自动重新启动并在重新启动时收到通知。虽然向 systemd 添加第二个服务似乎有点笨拙,但由于 systemd 的设计,这是必要的。

话虽如此,当我们部署到 CentOS8 时,这个解决方案与自动重启相结合,对我们不起作用。这是因为在 C8 中发布的 systemd v239 在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 有帮助。还有一些帮助我解决的链接:

  1. https://superuser.com/questions/1360346/how-to-send-an-email-alert-when-a-linux-service-has-stopped
  2. https://unix.stackexchange.com/questions/422933/confusing-systemd-behaviour-with-onfailure-and-restart
  3. https://unix.stackexchange.com/questions/197636/run-an-arbitrary-command-when-a-service-fails