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


8

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

它设置为在出现故障后立即重新启动。

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


2
我不知道如何使用systemd进行操作,但是使用monit可以监视进程,并且如果进程id更改,它可以发出通知。
Zoredache

Answers:


16

首先,您需要两个文件:一个用于发送邮件的可执行文件和一个用于启动该可执行文件的.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

无论您使用什么可执行文件,它都应该像该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

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

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

来源:archlinux Wiki:systemd计时器MAILTO


但是@Dave不需要其他服务。他希望自己已经使用的服务能够在每次启动/重新启动时发送邮件。为此,有ExecStartPost选项。
Jaroslav Kucera

@JaroslavKucera我认为这是要由OP决定的... :)另外,我不确定是否ExecStartPost是正确的选择:它还会在“正常”启动后触发,不仅在失败的情况下,对?
gf_

我很想知道为什么对此不赞成-请提高声音并说出来!
gf_

因为问题不在于其他服务,而在于对现有服务的修改。是的,即使在正常启动时,ExecStartPost也会触发邮件发送。我不知道只有重启才能正常工作。
Jaroslav Kucera

@JaroslavKucera好吧,OP似乎表示不同意,但是请保留您的意见。
gf_

2

@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. /superuser/1360346/how-to-send-an-email-alert-when-a-linux-service-has-stopped
  2. /unix/422933/confusing-systemd-behaviour-with-onfailure-and-restart
  3. /unix/197636/run-an-arbitrary-command-when-a-service-fails


-1

您可以创建一个Shell脚本来检查服务状态并在服务器启动时发送电子邮件。此链接可能对您有帮助

/ubuntu/814/how-to-run-scripts-on-start-up


1
这个问题不是关于引导,而是关于服务重新启动,这可能在引导后的相当一段时间内发生。因此,我不确定您的回答是否有帮助。
gf_
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.