Skip to content

Cron Runner

Git tracked Crontab

Crontab needs to be version controlled for every project. So that we would be able to check what changes have been applied, and possibly rollback if necessary to any version of it.

# To export current crontab into a file
cd /to/web/root/directory
crontab -l > ./_crontab_temp

Next time you need to add some new cron schedules to the list, you modify the _crontab_temp file commit it, push it. And then load it on LIVE server by executing command crontab _crontab_temp

Warning

Do not edit crontab directly with crontab -e

Cron Runner

The cron runner features:

  • Running of cron tasks individually if they need to be broken out of another framework
  • Logging of output from the cron tasks
  • Preventing duplicate running of tasks
  • Emailing when an error occurs inside a cron task

Getting the cron runner

Clone the edmondscommerce-serversetup repo:

1
git clone gitBare:~/repos/edmondscommerce-serversetup

The cron runner is contained inside the cronscripts folder

Bash Cron Runner

Here is an example bash based cron running script

#!/usr/bin/env bash
readonly DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )";
cd $DIR;
source ./_cron_top.bash

###### VARIABLES #########
scriptToRun=$1

logFile=${scriptToRun/.bash/.log}

###### FUNCTIONS #########

function msg(){
    local msg=$1
    echo "MESSAGE: $msg" >> $logFile
    echo $msg
}

function dieAndSendEmail(){
    echo "Dying and sending email"
    sendEmail \
        "$(hostname) Cron Error on $scriptToRun" \
        "info+$(hostname | xargs echo)@edmondscommerce.co.uk" \
        "Error log attached" \
        $logFile
    echo "Log:"
    cat $logFile
    exit 1
}

###### PROCESS ###########
echo "Starting at $(date)" > $logFile
set +e
alreadyRunning=$(ps waux | grep -v cronRunner | grep -v 'grep' | grep $scriptToRun)
set -e
if [[ "" != "$alreadyRunning" ]]
then
    msg "Found already running version - aborting this process"
    dieAndSendEmail
fi

msg "Running $scriptToRun"
set +e
set -x
bash -${-//s} $DIR/$scriptToRun &>> $logFile
exitCode=$?
set +x
set -e

if [[ "$exitCode" != "0" ]]
then
    msg "Got non zero exit code of $exitCode"
    dieAndSendEmail
fi
msg "Process completed with success exit code of $exitCode at $(date)"

Cron runner folder structure

  • _crontab_temp: backed up version of the system crontab
  • backup_live.bash: Backs up the live database, and cleans up old backups (depends on the rest of the repo)
  • backup_live_important_tables.bash: Same as above, but only a subset of tables, for huge databases
  • cronRunner.php: The file intended to be run in the system's crontab. Checks for duplicates, logs output and handles errors
  • magento_crons.bash: Looks in /var/www/vhosts for any Magento cron files and outputs their paths
  • rsnapshot_daily.bash: backup utility?

Using the cron runner

In the system's crontab, add a line resembling:

1
*/5 * * * * /bin/bash /path/to/cronscripts/cronRunner.php cron_task

cron_task is a .bash file within the cron runner folder.

It looks like the cron runner can't handle running files outside of its own folder, but could be amended to do so.

Email Sending

The cron runner is set up to send an email to info@edmondscommerce.co.uk using PHP's mail() function whenever an error occurs in a cron script.

This might be really verbose. If so you can remove the send_email() call and associated logic