Monday, July 15, 2013

PHP - Log Maintenance

Running a PHP file from cron is easy enough, simply specify the PHP bin path, the path to the PHP script and where to send the output of the script. The issue comes with how to manage the size of the log file. You can set a job to truncate the file as opposed to append it but that means you loose any of the log lines that were in it. A better option is to use one of the cron jobs to rotate the logs into an archive of some sort.

This script first checks when it was last run, if it's under an hour ago, it skips to the remainder of the job.

We then check the file size, if it's over 1MB it starts the process of archiving it and creating a blank replacement. To be sure we can know when the archived log file was created, we put the epoch time that it was created in the file name.

Every time this portion of the job runs, it also checks to see if there are any log files that are older than seven days.  Because we put the epoch time that the archive was created, this is a simple matter of getting the epoch time back out of the file name and comparing it to our cutoff value. If the file is older than cutoff date, we simply delete it then log that we did so.

// only check log files for maintenance once an hour at most
if($process->lastRan < (time() - 3600)) {
    $logFile = LOG_PATH.'/cron.log';
    // if log file is over 1MB, archive it and create a new one
    if(filesize($logFile) > (1024 * 1024)) {
        // put the epoch time into the name so we can tell when it was archived
        $logFileBk = 'cron.'.time().'.log';
        // duplicate the file with the new name
        copy($logFile, LOG_PATH.'/'.$logFileBk);
        // create a blank 
        file_put_contents($logFile, date('M d, Y H:i:s')."\t[cron_controller]\tTruncated log file - $logFileBk\n");
    }
    // look for any log file that is oder than 7 days
    $end = strtotime('00:00:00 - 7 days');
    $list = scandir(LOG_PATH);
    foreach($list as $i) {
        // get the date date from the file name if it matches the correct form
        if(preg_match('/^cron\.([0-9]{10})\.log$/',$i,$matches) === 1) {
            // if the found date is older than 7 days ago
            if((int)$matches[1] < $end) {
                // delete the file
                unlink(LOG_PATH.'/'.$i);
                echo date('M d, Y H:i:s')."\t[cron_controller]\tDeleted log file - $i\n";
            }
        }
    }
}

This script could be put in either the beginning of the cron job or at the end. But if you are using the PHP Cron Controller that I outlined in this post, I highly recommend doing this log maintenance as early in the script as possible. If you do it at the end of the script, you could run into a situation where a job called from the PHP Cron Controller is working and writing lines when this maintenance is being done.

No comments:

Post a Comment