Lösung 1:
Zunächst benötigen Sie zwei Dateien:eine ausführbare Datei zum Versenden der Mail und eine .service zum Starten der ausführbaren Datei. In diesem Beispiel ist die ausführbare Datei nur ein Shell-Skript, das sendmail
verwendet :
/usr/local/bin/systemd-email:
#!/bin/bash
/usr/bin/sendmail -t <<ERRMAIL
To: $1
From: systemd <[email protected]$HOSTNAME>
Subject: $2
Content-Transfer-Encoding: 8bit
Content-Type: text/plain; charset=UTF-8
$(systemctl status --full "$2")
ERRMAIL
Welche ausführbare Datei Sie auch verwenden, sie sollte wahrscheinlich mindestens zwei Argumente haben, wie es dieses Shell-Skript tut:die Adresse, an die gesendet werden soll, und die Unit-Datei, von der der Status abgerufen werden soll. Die .service
we create wird diese Argumente übergeben:
/etc/systemd/system/[email protected]:
[Unit]
Description=status email for %i to user
[Service]
Type=oneshot
ExecStart=/usr/local/bin/systemd-email address %i
User=nobody
Group=systemd-journal
Wo Benutzer ist der Benutzer, dem eine E-Mail gesendet wird, und Adresse ist die E-Mail-Adresse dieses Benutzers. Obwohl der Empfänger fest codiert ist, wird die Unit-Datei, über die berichtet werden soll, als Instanzparameter übergeben, sodass dieser eine Dienst E-Mails für viele andere Units senden kann. An dieser Stelle können Sie [email protected]
starten um zu überprüfen, ob Sie die E-Mails empfangen können.
Bearbeiten Sie dann einfach den Dienst, für den Sie E-Mails erhalten möchten, und fügen Sie [email protected]%n.service
hinzu bis [Unit]
Sektion. %n
übergibt den Namen der Einheit an die Vorlage.
Quelle:Archlinux-Wiki:systemd timers MAILTO
Lösung 2:
Die von @gf_ vorgeschlagene Lösung hat für unsere Situation mit Clickhouse unter CentOS7 gut funktioniert. Clickhouse stürzt ziemlich regelmäßig bei uns ab, daher mussten wir es sowohl automatisch neu starten als auch benachrichtigen, wenn der Neustart erfolgte. Obwohl es ein wenig umständlich erscheint, systemd einen zweiten Dienst hinzuzufügen, ist dies aufgrund des Designs von systemd notwendig.
Abgesehen davon funktionierte diese Lösung in Kombination mit dem automatischen Neustart für uns nicht mehr, als wir auf CentOS8 umstellten. Dies liegt daran, dass systemd v239, das in C8 ausgeliefert wurde, eine Änderung an OnFailure=
einführte Semantik in Kombination mit einer nicht standardmäßigen Konfiguration von Restart=
(Restart=on-failure
in unserem Fall). Das neue OnFailure=
Verhalten löst den One-Shot-Dienst nur dann aus, wenn der Neustart vollständig fehlgeschlagen ist, nicht nur nach einem Absturz. Dieses neuere Verhalten würde den Dienst gerne neu starten, aber wir würden die E-Mail nicht als OnFailure=
erhalten wurde nicht mehr aufgerufen.
Beachten Sie unsere primäre Erwartung:Wir wollten, dass systemd den Prozess neu startet UND eine E-Mail-Benachrichtigung sendet. Das v239-Update hat dazu geführt, dass unsere vorherige Lösung, die von gf_ zitiert wurde, nicht mehr funktioniert. Glücklicherweise konnten wir das zum Laufen bringen.
Unsere Lösung ist die Verwendung von ExecStopPost
um das E-Mail-Benachrichtigungsskript aufzurufen. Das funktioniert gut, aber jetzt ist ein neues Problem aufgetreten:Eine E-Mail-Benachrichtigung wurde gesendet, wenn der Clickhouse-Dienst normal gestartet wurde, z. B. beim Serverstart. Obwohl es keine große Sache ist, wollten wir idealerweise nur E-Mail-Benachrichtigungen erhalten bei Abstürzen. Wir konnten dies erreichen, indem wir unserem E-Mail-Skript den folgenden Code hinzufügten:
# Don't do anything if the service intentionally stopped successfully.
if [ $SERVICE_RESULT == "success" ]; then
exit
fi
... $SERVICE_RESULT
ist eine Umgebungsvariable, die von systemd an den Zielprozess von ExecStopPost
geliefert wird . Indem Sie nach einem success
suchen Als Ergebnis nehmen wir an, dass dieser Aufruf von einem normalen Start oder Herunterfahren kam, und tun nichts. Bei jedem anderen Wert, z. B. signal
, würde das Skript mit dem Senden einer E-Mail fortfahren. Die möglichen Werte dieser Variable sind in der Dokumentation angegeben.
Danke an gf_ für die erste Lösung. Ich hoffe, dass die Leute mein Update für CentOS8 hilfreich finden. Einige weitere Links, die mir geholfen haben:
- https://superuser.com/questions/1360346/how-to-send-an-email-alert- when-a-linux-service-has-stopped
- https://unix.stackexchange.com/questions/422933/confusing-systemd-behaviour-with-onfailure-and-restart
- https://unix.stackexchange.com/questions/197636/run-an-arbitrary-command-when-a-service-fails