Get an email upon failed systemd services | Rida Ayed

Get an email upon failed systemd services

Only by chance, I noticed a failed systemd service. It’s a rather crucial
service, namely my backup.
I’ve decided to get notified by email in such circumstances.
The solution consists of three parts:

  1. The actual backup service unit
  2. A unit status mail service
  3. A python email script

On failure, the actual service triggers the email service which in turn triggers
the email script.

The %h in the highlighted line, refers to the User home directory as per systemd.unit

[Service]
Type=oneshot
ExecStart=/usr/bin/sh $h/bin/backup.sh

[Unit]
Description=Homefolder backup
OnFailure=unit-status-mail@%n.service

[Unit]
Description=Unit Status Mailer Service
After=network.target

[Service]
Type=simple
ExecStart=/home/ra/bin/unit-status-mail.py %I

#!/bin/python
import smtplib
import argparse
from subprocess import Popen, PIPE
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

parser = argparse.ArgumentParser()
parser.add_argument("unit")
args = parser.parse_args()
unit = args.unit

usr = 'foo@bar.com'
pwd = 'secretpassword'
host ='mail.host.com'
port = 465

msg = MIMEMultipart()
msg['From'] = usr
msg['To'] = usr
msg['Subject'] = f'Failed: {unit}'
cmd=f'systemctl status --user --full {unit}'
# Be aware of security issues when using shell=True
stdout = Popen(cmd, shell=True, stdout=PIPE)\
    .stdout.read().decode('utf-8')
msg.attach(MIMEText(stdout))

with smtplib.SMTP_SSL(host,port) as mail_server:
    mail_server.ehlo()
    mail_server.login(usr, pwd)
    mail_server.sendmail(usr, usr, msg.as_string())

I wrote this article while metaphorically standing on the shoulders of Laeffe
Furthermore I made slight changes according to this question