monitor file and send alert mail on change/modify

For some reasons it can be very useful to be alerted on some specific file changes (for instance a database error log).

Using inotify-tools I wrote a script that can monitor a file sending alerts to an email address if that file is changed:


#!/bin/sh
#
# Monitor file $1 for changes
# Send an alert emai to $2 if file $1 changes
# usage: file_change_mail_alert.sh /var/log/messages your.name@domain.com
#

if [ -z "$2" ]; then
echo "Usage: file_change_mail_alert.sh "
exit 1
fi

#if a inotifywait for this file is already running
if [ $(ps aux | grep inotifywait | grep -c "$1" ) -gt '0' ]; then
echo "A process monitoring the file $1 is already running: $(ps aux | grep inotifywait | grep "$1" )";
exit 1;
fi

#if inotifywait exists
type -P inotifywait &>/dev/null || { echo "Error: This script requires inotifywait(http://wiki.github.com/rvoicilas/inotify-tools/) .... apt-get install inotify-tools ... " >&2; exit 1; }

#if the file exists
if [ -f $1 ]; then

echo "Monitoring file $1 for changes - sending alerts to $2"

while inotifywait -e modify $1; do
sleep 1
changes="$(tail -n5 $1)"
echo "The following change occured in the file $1 : $changes" | mail -s "Change in $1" $2
done
else
echo "Error: File $1 not found"
fi

This script can be started on server startup like this:
/path/to/file_change_mail_alert.sh /var/log/something.log your.email@domain.ro

Or put in in the crontab – once a day (it will exit if it detects that another instance of “itself” is already running)
0 6 * * * /path/to/file_change_mail_alert.sh /var/log/something.log your.email@domain.ro

3 thoughts on “monitor file and send alert mail on change/modify

  1. Hello,

    I have taken the idea of your script and rewrote it some so that:
    0. it works with any Bourne shell compatible shell [orig will only work on BASH]
    1. It takes an optional third arg – the dir to the commit file, for diffing purposes
    2. use FILENAME and MAILTO instead of $1 and $2

    I couldn;t find your mail addr so pasting it here in the hope that it will be useful.

    thanks,


    #!/bin/sh
    # Send an alert email to $2 if file $1 changes
    # usage: file_change_mail_alert.sh /file/to/probe/for changes your.name@domain.com
    # This script is based on the one here:
    # http://blog.brasov.cubus.ro/2010/05/monitor-file-and-send-alert-mail-on-changemodify/
    # Jess made it more generic and Bourne shell compatible.

    if [ -z "$2" ]; then
    echo "Usage: $0 "
    exit 1
    fi
    FILENAME=$1
    MAILTO=$2
    if [ -d "$3" ];then
    PATH_TO_COMMITTED_FILE=$3
    fi
    #if a inotifywait for this file is already running
    if ps aux | grep inotifywait | grep -c "$FILENAME" ;then
    echo "A process monitoring the file $1 is already running: `ps aux | grep inotifywait | grep "$1"`";
    # it would be more reasonable if we exited with something other than 0 but when we do, crond omits an alert by mail, even though it is not necessarily an error to have another inotifywait running..
    exit 0;
    fi

    #if inotifywait exists
    if [ ! -x `which inotifywait` ];then
    echo "Error: This script requires inotifywait(http://wiki.github.com/rvoicilas/inotify-tools/) ... install inotify-tools." >&2
    exit 3
    fi

    #if the file exists
    if [ -f $FILENAME ]; then

    echo "Monitoring file $FILENAME for changes - sending alerts to $MAILTO."
    while inotifywait -e move_self,modify $FILENAME; do
    sleep 1
    #changes="$(tail -n5 $FILENAME)"
    echo "The following change occured in the file $FILENAME:" > /tmp/$FILE.diff
    if [ -d "$PATH_TO_COMMITTED_FILE" ];then
    FILE=`basename $FILENAME`
    diff -u $PATH_TO_COMMITTED_FILE/$FILE $FILENAME >> /tmp/$FILE.diff
    fi
    mail -s "$FILENAME modified" $MAILTO < /tmp/$FILE.diff
    done
    else
    echo "Error: File $FILENAME not found."
    fi

  2. Thanks you A Philippi and Jess Portnoy for the info.

    I am new at this and picking up bit and pieces on how to do this on out SFTP server. If I want to monitor the /home/sfpusers folder, would I make the following change below in the script?

    /home/sfpusers=$3

    If I want crontab to check for the changes and send me the changes, would it be the syntax below?

    */5 * * * * /path/to/file_change_mail_alert.sh /var/log/something.log your.email@domain.ro

    Thank both in advance.

Leave a Reply

Your email address will not be published. Required fields are marked *