I have a systemd
service that runs a SQL script that refreshes a bunch of materialized views. The service runs every 5 minutes. The service is deployed by ansible. If the SQL script fails, I would like to send an email, which notifies us of failure. The current code (see the yml chunk below) will send the notification email every 5 min or so, until one of us fixes the problem or stops the service. This is too frequent: one email is enough, and is exactly what I need.
How can I send one and only one email, even if the script fails repeatedly?
I am considering using a wrapper script such as this pseudocode, but it looks ugly:
# Runs every 5 min:
psql -f refresh_matviews.sql || touch refresh_matviews.failed.log
if { exists refresh_matviews.failed.log }
and { not grep "seen" refresh_matviews.failed.log } then
echo "failed!" | mail admin@foo.com
echo "seen" > refresh_matviews.failed.log
If such a wrapper script is used, then whoever fixes the problem needs to also manually clear the (now outdated) failure file (rm refresh_matviews.failed.log
), so that any new failure triggers a new email.
The relevant chunk of the yml file for ansible
:
- name: Add systemd service that refreshes matviews
copy:
content: |
# This service unit refreshes matviews
#
[Unit]
Description=Refreshes matviews
Wants=refresh_matviews.timer
[Service]
User=galaxy
Type=oneshot
ExecStart=/bin/bash -c '/usr/bin/psql ... -f /path/to/refresh_matviews.sql || echo 'WARNING' | /usr/bin/mail -s "not ok: refresh matviews" admin@foo.com'
[Install]
WantedBy=multi-user.target
dest: /etc/systemd/system/refresh_matviews.service
owner: root
group: root
mode: 0644
- name: Add systemd timer that refreshes matviews
copy:
content: |
# This timer unit refreshes matviews
#
[Unit]
Description=Refreshes matviews
Requires=refresh_matviews.service
[Timer]
Unit=refresh_matviews.service
OnCalendar=*-*-* *:00/5:00
[Install]
WantedBy=timers.target
dest: /etc/systemd/system/refresh_matviews.timer
owner: root
group: root
mode: 0644
It seems that ansible
/systemd
should have something similar to what I need, but this is all I could find: