magic-lamp

DSVR quota monitoring script

You can use the following script with www.DSVR.co.uk Virtual Servers to monitor user quota usage.

The script outputs a sorted percentage representation of the quota used by each user.

It can either display usage at the console, or it will email the quotas used.

To get started follow these instructions:

  1. Copy the script below and put it on your VS. I like to put it in ~/admin.
  2. Edit the variables for your own settings in the 'User configuration variables' part of the script.
  3. Test it by running it on the command line.
  4. Set up a cron job to run it as often as you want.

Disclaimer

The following document is offered in good faith as comprising only safe programming and procedures. No responsibility is accepted by the author for any loss or damage caused in any way to any person or equipment, as a direct or indirect consequence of following these instructions.


#!/usr/bin/php -q

<?
/**
 * repquota.php - check quotas and email a sorted percentage representation
 *
 * @author Jinn Koriech 
 * @created 2002
 * @copyright 2002 Magic-Lamp Digital
 * @version $Revision: 1.1 $
 * @date $Date: 2004/08/11 12:36:24 $
 *
 * ==========================================================================
 * Copyright (C)2002 - Jinn Koriech (www.magic-lamp.org)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
 * or visit http://www.gnu.org/copyleft/gpl.html
 * ==========================================================================
 */
 
// ===== User configurable variables ========================================
/**
 * @param string $action mail|display
 * @param string $to [email@address.net] Only used if $action = 'mail'
 * @param string $subject [email subject] Only used if $action = 'mail'
 */
$action = 'mail';
$to = "your@email-address.net";
$subject = "SysAdmin: your.domain.net - Quota Report";
 
/**
 * @param bool $quota_du TRUE|FALSE
 *
 * If set to TRUE then /etc/passwd will be used to find the corresponding
 * users home directory and get a realistic idea of disk usage even if
 * the web process owns some files.  In addition MySQL will be checked for
 * corresponding names and space usage will be included there also.
 */
$quota_du = TRUE;
 
/**
 * @param string $mysql_dir Location of MySQL databases
 * @param array $user_skip_list List of users in /etc/passwd to skip
 * @param array $db_skip_list List of directories in $mysql_dir to skip reporting
 */
$mysql_dir = '/var/lib/mysql'; // no trailing slash
$user_skip_list = Array('admin', 'bin', 'daemon', 'ftp', 'mail', 'nobody', 'root', 'sshd', 'web');
$db_skip_list = Array('.', '..', 'mysql');
 
/*============================================================================
      Don't change anthing below here unless you know what you're doing :)
=============================================================================*/
define('NL', chr(10));
$header = "Used(%)\tHome\tDB\tTotal\tUser\t\tHome directory";
$header.= "\n==============================================================";
$db_header = "\nDATABASES THAT WERE NOT ASSOCIATED WITH A USER";
$db_header.= "\n==============================================";
$license = "\n
=====================================================================
repquota.php, Copyright (C)2002 Jinn Koriech (www.magic-lamp.org)
repquota.php comes with ABSOLUTELY NO WARRANTY; for details see
http://www.gnu.org/copyleft/gpl.html.  This is free software, and
you are welcome to redistribute it under the terms of the
GNU General Public License.
";
 
// Get the output from repquota
$result = `/usr/sbin/repquota -a`; // GET THE QUOTA DATA
$repquota = explode("\n", $result);
unset($result);
 
// Get the list of users from /etc/passwd
$fp = fopen('/usr/local/etc/passwd', 'r');
while ( $line = fgetcsv($fp, 512, ":") ) {
    if ( !in_array($line[0], $user_skip_list) ) {
        $passwd[] = $line;
    }
}
fclose($fp);
 
// Get the database usage
$dh = opendir($mysql_dir);
while ( ($entry = readdir($dh)) !== FALSE ) {
    if ( is_dir($mysql_dir.'/'.$entry) && !in_array($entry, $db_skip_list) ) {
        exec('du -s '.$mysql_dir.'/'.$entry, $db_usage, $retval);
    }
}
 
// Go through the list from repquota
for ( $idx=5; $idx < count($repquota); $idx++ ) { // ITERATED THROUGH THE LINES
        $col = explode(" ", $repquota[$idx]);
        for ( $jdx=0; $jdx < count($col); $jdx++ ) { // ITERATE THROUGH THE COLUMNS
                if ( trim($col[$jdx]) != '' )
                        $row[$idx][] = trim($col[$jdx]);
        }
}
 
for ( $idx=0; $idx < count($row); $idx++ ) {
        $user = trim($row[$idx+5][0]);
        $used = trim($row[$idx+5][2]);
        $limit = trim($row[$idx+5][3]);
 
    // Iterate through the passwd file to get the users home directory and du
    for ( $pdx=0; $pdx < count($passwd); $pdx++ ) {
        if ( $user == $passwd[$pdx][0] ) {
            $home = $passwd[$pdx][5]; 
            exec('du -s '.$home.' 2>/dev/null', $output, $retval);
            $du = substr($output[0], 0, strpos($output[0], "\t"));
            unset($output); 
            break;
        }
    }
    // Iterate through the database info and extract the corresponding database
    for ( $dbx=0; $dbx < count($db_usage); $dbx++ ) {
        if ( strstr($home, 'vhtdocs') ) {
            $db_name = trim(str_replace($mysql_dir.'/', '', substr($db_usage[$dbx], strrpos($db_usage[$dbx], "\t"))));
            if ( strstr($home, $db_name) ) {
                $du_db = substr($db_usage[$dbx], 0, strpos($db_usage[$dbx], "\t"));
                $du_total = $du + $du_db;
                $db_usage[$dbx] .= "DONE";
                break;
            }
        }
    }
 
        if ( $limit != 0 ) {
                $percent_used = ($used / $limit) * 100;
                $lines[$idx] = number_format($percent_used,1) ."%\t". $du ."\t". $du_db . "\t" . $du_total . "\t" . str_pad($user, 16) . $home;
        } else {
                $percent_used = 'none';
                $lines[$idx] = "n/a\t". $du ."\t". $du_db . "\t" . $du_total . "\t" . str_pad($user, 16) . $home;
        }
 
        if ( $percent_used > 100 ) $lines[$idx-5] .= "\tOVER QUOTA!";
    unset($du, $du_db, $user, $home, $percent_used, $du_total);
}
 
rsort($lines, SORT_NUMERIC);
array_unshift($lines, $header);
array_unshift($lines, `df -h`);
 
// Check if there are any databases that haven't been reported
for ( $dbx=0; $dbx < count($db_usage); $dbx++ ) {
    if ( !strstr($db_usage[$dbx], DONE) ) {
        if ( !isset($db_header_complete) ) {
            $lines[] = $db_header;
            $db_header_complete = 'DONE';
        }
        $lines[] = $db_usage[$dbx];
    }
}
if ( $action == 'display' ) {
        foreach ( $lines as $line ) {
                echo $line."\n";
        }
} elseif ( $action == 'mail' ) {
        $message = implode("\n",$lines);
        $message .= "\n\n" . $license;
        //$message = `df -h` . "\n\n" . $message;
        mail ($to,$subject,$message);
}
 
// END OF THE SHOW
?>


Copyleft © 1998 - 2007 • Jinn Koriech