Article Listing 1 Listing 2 Listing 3 Listing 4
Sidebar jun2004.tar

Listing 1 check_cron

#!/bin/ksh
# Listing 1: check_cron
#
# This shell script processes the cron log entries located in the
# /var/cron/log file completed within a certain time interval.
# After the entries have been processed, the script prints a message
# indicating whether or not all jobs completed with a return code of zero.

trap "clean_up" 2 3

. /etc/setenv_path
TRUE=0
FALSE=1

readonly TEMP_DIR=/tmp
readonly TEMP_START=$TEMP_DIR/.check_cron.start.$$
readonly TEMP_FINISH=$TEMP_DIR/.check_cron.finish.$$
readonly TEMP_ALERTS=$TEMP_DIR/.check_cron.alerts.$$
readonly DEFAULT_WINDOW=3600

recent=$FALSE
alert=$FALSE
verbose=$FALSE
users=""
minutes=0
hours=0

clean_up()
{
    rm -f $TEMP_START $TEMP_FINISH $TEMP_ALERTS $TEMP_DIR/.check_cron.*.$$
    exit
}

while getopts ah:m:ru:v OPTION
do
    case "$OPTION"
    in
        a) alert=$TRUE ;;
        h) hours=$OPTARG ;;
        m) minutes=$OPTARG ;;
        r) recent=$TRUE ;;
        u) users=$OPTARG ;;
        v) verbose=$TRUE ;;
    esac
done

if (( $minutes == 0 )) && (( $hours == 0 )) 
then
    window=$DEFAULT_WINDOW
else
    window=$(( ($minutes*60) + ($hours*3600) ))
fi

rm -f $TEMP_ALERTS $TEMP_DIR/.check_cron.*

> $TEMP_FINISH
> $TEMP_START

if [[ -z $users ]]
then
    grep "^<" /var/cron/log | tail -r > $TEMP_FINISH
    grep "^>" /var/cron/log | tail -r > $TEMP_START
else
    grep "^<" /var/cron/log | tail -r | \
    while read char user rest_of_line
    do
        if (( $(echo $users | grep -c -w $user) > 0 ))
        then
            echo $char $user $rest_of_line >> $TEMP_FINISH
        fi
    done

    grep "^>" /var/cron/log | tail -r | \
    while read char user rest_of_line
    do
        if (( $(echo $users | grep -c -w $user) > 0 ))
        then
            echo $char $user $rest_of_line >> $TEMP_START
            read next_line
            echo $next_line >> $TEMP_START
        fi
    done
fi

date | read c_weekday c_month c_day c_time c_timezone c_year

while read \
f_char1 f_user f_pid f_char2 \
f_weekday f_month f_day f_time f_year f_return_string
do
    if [[ -n $f_return_string ]]
    then
        f_return_code=$(echo $f_return_string | cut -d= -f2)
    else
        f_return_code=0
    fi
    age=$(datediff $f_year/$f_month/$f_day $f_time \
      $c_year/$c_month/$c_day $c_time)
    if (( $age > $window ))
    then
        break
    fi
    while read \
    s_char1 s_user s_pid s_char2 \
    s_weekday s_month s_day s_time s_year
    do
        read s_char3 s_cmd_tag s_command
        if [[ $f_pid = $s_pid ]] && [[ $f_user = $s_user ]]
        then

            command_fingerprint=$(echo $s_command | md5)
            command_file=$TEMP_DIR/.check_cron.$command_fingerprint.$$

            if (( $recent == $TRUE )) && [[ -f $command_file ]]
            then
                break
            fi

            duration=$(datediff \
            $s_year/$s_month/$s_day $s_time \
            $f_year/$f_month/$f_day $f_time)

            cat > $command_file << EOF
user=$s_user
command=$s_command
start=$s_time $s_day $s_month $s_year $s_weekday
duration=$duration sec
rc=$f_return_code

EOF
            if (( $verbose == $TRUE ))
            then
                cat $command_file
            fi

            if (( $f_return_code != 0 ))
            then
                cat $command_file >> $TEMP_ALERTS
            fi
            break
        fi
    done < $TEMP_START
done < $TEMP_FINISH

window_dhms=$(echo $window | secs2dhms)

if [[ -f $TEMP_ALERTS ]]
then
    echo \
"Some cron jobs that completed in the past ${window_dhms} did not return 0!"
    cat $TEMP_ALERTS | sudo -u monitor \
    /opt/monitor/bin/create_alert_file \
    -p medium \
    -c $(basename $0) \
    -s "possible cron problem"
else
    echo "All cron jobs that \c"
    if (( $recent == $TRUE ))
    then
        echo "recently \c"
    fi
    echo "completed in the past ${window_dhms} returned 0."
fi

clean_up