Skip to content

Instantly share code, notes, and snippets.

Last active April 2, 2017 11:24
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save massenz/5b82be8667d38f7b52e4 to your computer and use it in GitHub Desktop.
Save massenz/5b82be8667d38f7b52e4 to your computer and use it in GitHub Desktop.
Originally written for Mandrill (screw them), this script can send an email alert, for example, when a remote job fails or some other unexpected event happens: I'm using it on my QNAP TS-212 NAS to alert me about backup jobs failures and other abnormal events.
# Failure reporter, logs to a well-known log file failure messages
# Created 2014-04-30, M. Massenzio (
declare -r LOGFILE="/var/log/fail.log"
declare -r ALERT_ICON="/usr/share/icons/ubudao-style/actions/dialog-warning.png"
declare -r ERROR_ICON="/usr/share/icons/ubudao-style/actions/stock_dialog-error.png"
echo "[ERROR] `date` -- $1" >> ${LOGFILE}
notify-send -i ${ALERT_ICON} "Failure Alert" "$1" -f ${HOME}/.yagmail -m "$1" -s "Failure Alert from `hostname`" \
-d >> ${LOGFILE} 2>&1
if [ $? != 0 ]; then
echo "[ERROR] `date` -- Failed to send email alert" >> ${LOGFILE}
notify-send -i ${ERROR_ICON} "Cannot Send Email" "Failed to send email alert, see log at ${LOGFILE}"
#!/usr/bin/env python
# Copyright (c) 2016. All rights reserved.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# See the License for the specific language governing permissions and
# limitations under the License.
# Created by M. Massenzio (, 2016-05-14
import argparse
import logging
import socket
# See:
import yagmail
FORMAT = '%(asctime)-15s [%(levelname)s] %(message)s'
DATE_FMT = '%m/%d/%Y %H:%M:%S'
def parse_args():
""" Parse command line arguments and returns a configuration object
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--api-key-file', required=True,
help="The file containing the API key")
parser.add_argument('-m', dest='msg', required=True, help="The body of the message")
parser.add_argument('-d', dest='dest', help="The recipient of the email")
parser.add_argument('-s', dest='subject', help='The subject for the email',
default='Alert from {hostname}'.format(hostname=socket.gethostname()))
parser.add_argument('-v', dest='verbose', action='store_true', help='Enables debug logging')
return parser.parse_args()
def post_mail(to, subj, msg, **kwargs):
""" Sends the ``msg`` via email to the specified recipient.
@param to: the recipient for the message
@type to: str
@param subj: the subject for the email
@type subj: str
@param msg: the body of the message, in plain text
@type msg: str
contents = """<h3>Automated Alert</h3>
<h6>Sent via yagmail, using &copy; 2016 M. Massenzio, all rights reserved.<br>
with yagmail.SMTP(kwargs.get('username'), kwargs.get('api_key')) as yag:
yag.send(to, subj, contents)'Message "{subj}" sent to {to}'.format(to=to, subj=subj))
def read_api_key(filename):
with open(filename, 'r') as key_file:
username = key_file.readline().rstrip('\n')
api_key = key_file.readline().rstrip('\n')
return {'username': username, 'api_key': api_key}
def main():
config = parse_args()
loglevel = logging.DEBUG if config.verbose else logging.INFO
logging.basicConfig(format=FORMAT, datefmt=DATE_FMT, level=loglevel)'Mailer Auto Script starting...')
kwargs = read_api_key(config.api_key_file)
except Exception as ex:
logging.error("Could not read the API Key ({}), aborting", ex)
logging.debug('API key retrieved')
post_mail(to=config.dest, msg=config.msg, subj=config.subject, **kwargs)
if __name__ == "__main__":

Email Alerts via Yagmail API


Marco Massenzio






This script sends an email alert to the specified recipient.


[~] # ./ -f ./.secret -m "This is a test" -d -s "Test Test Test" -v                   

For a full explanation of the command-line options run with --help.

Note with the --verbose option specified, the API key will be logged to stdout (typically, console): don't do this unless you run this in a trusted environment.

For more details, please see my blog entry or the yagmail documentation

#!/usr/bin/env python
# Checks for remaining space in /boot and alerts if above a threshold.
# The threshold above which to alert can be passed in as the first CLI argument,
# or the default value will be used.
# Created by M. Massenzio, 2017-03-29
from sh import df, alert
import sys
threshold = 70
if len(sys.argv) > 1:
threshold = int(sys.argv[1])
alert("Program option should be a numeric value (threshold % above which to alert). "
"Was: {}".format(sys.argv[1]))
disk_space = df("-h")
for line in disk_space.split('\n'):
if line.endswith('/boot'):
items = line.split()
use_pct = items[-2]
assert use_pct.endswith('%')
used_space = int(use_pct[:-1])
if used_space > threshold:
alert("/boot is running out of space: {} used`({} bytes left)".format(use_pct, items[-3]))
# If we got here, we didn't find the /boot partition mount.
alert("Could not find the /boot partition, running `df`:\n{}".format(disk_space))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment