Example #1
0
function process_hosts()
{
    global $start, $seed;
    echo "NOTE: Processing Hosts Begins\n";
    /* All time/dates will be stored in timestamps
     * Get Autodiscovery Lastrun Information
     */
    $auto_discovery_lastrun = read_config_option("hmib_autodiscovery_lastrun");
    /* Get Collection Frequencies (in seconds) */
    $auto_discovery_freq = read_config_option("hmib_autodiscovery_freq");
    /* Set the booleans based upon current times */
    if (read_config_option("hmib_autodiscovery") == "on") {
        echo "NOTE: Auto Discovery Starting\n";
        if (runCollector($start, $auto_discovery_lastrun, $auto_discovery_freq)) {
            autoDiscoverHosts();
        }
        echo "NOTE: Auto Discovery Complete\n";
    }
    /* Purge collectors that run longer than 10 minutes */
    db_execute("DELETE FROM plugin_hmib_processes WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(started)) > 600");
    /* Do not process collectors are still running */
    if (db_fetch_cell("SELECT count(*) FROM plugin_hmib_processes") > 0) {
        echo "WARNING: Another Host Mib Collector is still running!  Exiting\n";
        exit(0);
    }
    /* The hosts to scan will
     *  1) Not be disabled,
     *  2) Be linked to the host table
     *  3) Be up and operational
     */
    $hosts = db_fetch_assoc("SELECT hm.host_id, host.description, host.hostname FROM plugin_hmib_hrSystem AS hm\n\t\tINNER JOIN host\n\t\tON host.id=hm.host_id\n\t\tWHERE host.disabled!='on'\n\t\tAND host.status!=1");
    /* Remove entries from  down and disabled hosts */
    db_execute("DELETE FROM plugin_hmib_hrSWRun WHERE host_id IN(SELECT id FROM host WHERE disabled='on' OR host.status=1)");
    db_execute("DELETE FROM plugin_hmib_hrDevices WHERE host_id IN(SELECT id FROM host WHERE disabled='on' OR host.status=1)");
    db_execute("DELETE FROM plugin_hmib_hrStorage WHERE host_id IN(SELECT id FROM host WHERE disabled='on' OR host.status=1)");
    db_execute("DELETE FROM plugin_hmib_hrProcessor WHERE host_id IN(SELECT id FROM host WHERE disabled='on' OR host.status=1)");
    $concurrent_processes = read_config_option("hmib_concurrent_processes");
    echo "NOTE: Launching Collectors Starting\n";
    $i = 0;
    if (sizeof($hosts)) {
        foreach ($hosts as $host) {
            while (true) {
                $processes = db_fetch_cell("SELECT COUNT(*) FROM plugin_hmib_processes");
                if ($processes < $concurrent_processes) {
                    /* put a placeholder in place to prevent overloads on slow systems */
                    $key = rand();
                    db_execute("INSERT INTO plugin_hmib_processes (pid, taskid, started) VALUES ({$key}, {$seed}, NOW())");
                    echo "NOTE: Launching Host Collector For: '" . $host["description"] . "[" . $host["hostname"] . "]'\n";
                    process_host($host["host_id"], $seed, $key);
                    usleep(10000);
                    break;
                } else {
                    sleep(1);
                }
            }
        }
    }
    /* taking a break cause for slow systems slow */
    sleep(5);
    echo "NOTE: All Hosts Launched, proceeding to wait for completion\n";
    /* wait for all processes to end or max run time */
    while (true) {
        $processes_left = db_fetch_cell("SELECT count(*) FROM plugin_hmib_processes WHERE taskid={$seed}");
        $pl = db_fetch_cell("SELECT count(*) FROM plugin_hmib_processes");
        if ($processes_left == 0) {
            echo "NOTE: All Processees Complete, Exiting\n";
            break;
        } else {
            echo "NOTE: Waiting on '{$processes_left}' Processes\n";
            sleep(2);
        }
    }
    echo "NOTE: Updating Last Run Statistics\n";
    // Update the last runtimes
    // All time/dates will be stored in timestamps;
    // Get Collector Lastrun Information
    $hrDevices_lastrun = read_config_option("hmib_hrDevices_lastrun");
    $hrSWRun_lastrun = read_config_option("hmib_hrSWRun_lastrun");
    $hrSWRunPerf_lastrun = read_config_option("hmib_hrSWRunPerf_lastrun");
    $hrSWInstalled_lastrun = read_config_option("hmib_hrSWInstalled_lastrun");
    $hrStorage_lastrun = read_config_option("hmib_hrStorage_lastrun");
    $hrProcessor_lastrun = read_config_option("hmib_hrProcessor_lastrun");
    // Get Collection Frequencies (in seconds)
    $hrDevices_freq = read_config_option("hmib_hrDevices_freq");
    $hrSWRun_freq = read_config_option("hmib_hrSWRun_freq");
    $hrSWRunPerf_freq = read_config_option("hmib_hrSWRunPerf_freq");
    $hrSWInstalled_freq = read_config_option("hmib_hrSWInstalled_freq");
    $hrStorage_freq = read_config_option("hmib_hrStorage_freq");
    $hrProcessor_freq = read_config_option("hmib_hrProcessor_freq");
    /* set the collector statistics */
    if (runCollector($start, $hrDevices_lastrun, $hrDevices_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('hmib_hrDevices_lastrun', '{$start}')");
    }
    if (runCollector($start, $hrSWRun_lastrun, $hrSWRun_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('hmib_hrSWRun_lastrun', '{$start}')");
    }
    if (runCollector($start, $hrSWRunPerf_lastrun, $hrSWRunPerf_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('hmib_hrSWRunPerf_lastrun', '{$start}')");
    }
    if (runCollector($start, $hrSWInstalled_lastrun, $hrSWInstalled_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('hmib_hrSWInstalled_lastrun', '{$start}')");
    }
    if (runCollector($start, $hrStorage_lastrun, $hrStorage_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('hmib_hrStorage_lastrun', '{$start}')");
    }
    if (runCollector($start, $hrProcessor_lastrun, $hrProcessor_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('hmib_hrProcessor_lastrun', '{$start}')");
    }
    if (read_config_option("hmib_autopurge") == "on") {
        echo "NOTE: Auto Purging Hosts\n";
        $dead_hosts = db_fetch_assoc("SELECT host_id FROM plugin_hmib_hrSystem AS hr\n\t\t\tLEFT JOIN host\n\t\t\tON host.id=hr.host_id\n\t\t\tWHERE host.id IS NULL");
        if (sizeof($dead_hosts)) {
            foreach ($dead_hosts as $host) {
                db_execute("DELETE FROM plugin_hmib_hrSystem WHERE host_id=" . $host["host_id"]);
                db_execute("DELETE FROM plugin_hmib_hrSWRun WHERE host_id=" . $host["host_id"]);
                db_execute("DELETE FROM plugin_hmib_hrSWRun_last_seen WHERE host_id=" . $host["host_id"]);
                db_execute("DELETE FROM plugin_hmib_hrDevices WHERE host_id=" . $host["host_id"]);
                db_execute("DELETE FROM plugin_hmib_hrStorage WHERE host_id=" . $host["host_id"]);
                db_execute("DELETE FROM plugin_hmib_hrProcessor WHERE host_id=" . $host["host_id"]);
                db_execute("DELETE FROM plugin_hmib_hrSWInstalled WHERE host_id=" . $host["host_id"]);
                echo "Purging Host with ID '" . $host["host_id"] . "'\n";
            }
        }
    }
    echo "NOTE: Updating Summary Statistics for Each Host\n";
    /* update some statistics in hrSystem */
    $stats = db_fetch_assoc("SELECT\n\t\thost.id AS host_id,\n\t\thost.status AS host_status,\n\t\tAVG(`load`) AS cpuPercent,\n\t\tCOUNT(`load`) AS numCpus\n\t\tFROM host\n\t\tINNER JOIN plugin_hmib_hrSystem AS hrs\n\t\tON host.id=hrs.host_id\n\t\tLEFT JOIN plugin_hmib_hrProcessor AS hrp\n\t\tON hrp.host_id=hrs.host_id\n\t\tGROUP BY host.id, host.status");
    if (sizeof($stats)) {
        $sql_insert = "";
        $sql_prefix = "INSERT INTO plugin_hmib_hrSystem\n\t\t\t(host_id, host_status, cpuPercent, numCpus) VALUES ";
        $sql_suffix = " ON DUPLICATE KEY UPDATE\n\t\t\thost_status=VALUES(host_status),\n\t\t\tcpuPercent=VALUES(cpuPercent),\n\t\t\tnumCpus=VALUES(numCpus)";
        $j = 0;
        foreach ($stats as $s) {
            $sql_insert .= (strlen($sql_insert) ? ", " : "") . "(" . $s["host_id"] . ", " . $s["host_status"] . ", " . (!empty($s["cpuPercent"]) ? $s["cpuPercent"] : "0") . ", " . (!empty($s["numCpus"]) ? $s["numCpus"] : "0") . ")";
            $j++;
            if ($j % 200 == 0) {
                db_execute($sql_prefix . $sql_insert . $sql_suffix);
                $sql_insert = "";
            }
        }
        if (strlen($sql_insert)) {
            db_execute($sql_prefix . $sql_insert . $sql_suffix);
        }
    }
    /* update the memory information */
    db_execute("INSERT INTO plugin_hmib_hrSystem\n\t\t(host_id, memSize, memUsed, swapSize, swapUsed)\n\t\tSELECT host_id,\n\t\tSUM(CASE WHEN type=12 THEN size * allocationUnits ELSE 0 END) AS memSize,\n\t\tSUM(CASE WHEN type=12 THEN (used / size) * 100 ELSE 0 END) AS memUsed,\n\t\tSUM(CASE WHEN type=13 THEN size * allocationUnits ELSE 0 END) AS swapSize,\n\t\tSUM(CASE WHEN type=13 THEN (used / size) * 100 ELSE 0 END) AS swapUsed\n\t\tFROM plugin_hmib_hrStorage\n\t\tWHERE type IN(12,13)\n\t\tGROUP BY host_id\n\t\tON DUPLICATE KEY UPDATE\n\t\t\tmemSize=VALUES(memSize),\n\t\t\tmemUsed=VALUES(memUsed),\n\t\t\tswapSize=VALUES(swapSize),\n\t\t\tswapUsed=VALUES(swapUsed)");
    echo "NOTE: Detecting Host Types Based Upon Host Types Table\n";
    $types = db_fetch_assoc("SELECT * FROM plugin_hmib_hrSystemTypes");
    if (sizeof($types)) {
        foreach ($types as $t) {
            db_execute("UPDATE plugin_hmib_hrSystem AS hrs SET host_type=" . $t["id"] . "\n\t\t\tWHERE hrs.sysDescr REGEXP '" . $t["sysDescrMatch"] . "'\n\t\t\tAND hrs.sysObjectID='" . $t["sysObjectID"] . "'");
        }
    }
    /* for hosts that are down, clear information */
    db_execute("UPDATE plugin_hmib_hrSystem\n\t\tSET users=0, cpuPercent=0, processes=0, memUsed=0, swapUsed=0, uptime=0, sysUptime=0\n\t\tWHERE host_status IN (0,1)");
    /* take time and log performance data */
    list($micro, $seconds) = explode(" ", microtime());
    $end = $seconds + $micro;
    $cacti_stats = sprintf("time:%01.4f " . "processes:%s " . "hosts:%s", round($end - $start, 2), $concurrent_processes, sizeof($hosts));
    /* log to the database */
    db_execute("REPLACE INTO settings (name,value) VALUES ('stats_hmib', '" . $cacti_stats . "')");
    /* log to the logfile */
    cacti_log("HMIB STATS: " . $cacti_stats, TRUE, "SYSTEM");
    echo "NOTE: Host Mib Polling Completed, {$cacti_stats}\n";
    /* launch the graph creation process */
    process_graphs();
}
function process_hosts()
{
    global $start, $seed, $key;
    echo "NOTE: Processing Hosts Begins\n";
    /* All time/dates will be stored in timestamps
     * Get Autodiscovery Lastrun Information
     */
    $auto_discovery_lastrun = read_config_option('mikrotik_autodiscovery_lastrun');
    /* Get Collection Frequencies (in seconds) */
    $auto_discovery_freq = read_config_option('mikrotik_autodiscovery_freq');
    /* Set the booleans based upon current times */
    if (read_config_option('mikrotik_autodiscovery') == 'on') {
        echo "NOTE: Auto Discovery Starting\n";
        if (runCollector($start, $auto_discovery_lastrun, $auto_discovery_freq)) {
            autoDiscoverHosts();
        }
        echo "NOTE: Auto Discovery Complete\n";
    }
    /* Purge collectors that run longer than 10 minutes */
    db_execute('DELETE FROM plugin_mikrotik_processes WHERE (UNIX_TIMESTAMP() - UNIX_TIMESTAMP(started)) > 600');
    /* Do not process collectors are still running */
    if (db_fetch_cell('SELECT count(*) FROM plugin_mikrotik_processes') > 0) {
        echo "WARNING: Another MikroTik Collector is still running!  Exiting\n";
        exit(0);
    }
    $types = array('storage', 'trees', 'users', 'queues', 'interfaces', 'wireless_aps', 'wireless_reg');
    $run = false;
    foreach ($types as $t) {
        $lastrun = read_config_option('mikrotik_' . $t . '_lastrun');
        $freq = read_config_option('mikrotik_' . $t . '_freq');
        if (runCollector($start, $lastrun, $freq)) {
            $run = true;
        }
    }
    if (!$run) {
        print "No collectors scheduled for this run, exiting\n";
        exit;
    }
    /* The hosts to scan will
     *  1) Not be disabled,
     *  2) Be linked to the host table
     *  3) Be up and operational
     */
    $hosts = db_fetch_assoc("SELECT hm.host_id, h.description, h.hostname \n\t\tFROM plugin_mikrotik_system AS hm\n\t\tINNER JOIN host AS h\n\t\tON h.id=hm.host_id\n\t\tWHERE h.disabled!='on'\n\t\tAND h.status!=1");
    /* Remove entries from  down and disabled hosts */
    db_execute("DELETE FROM plugin_mikrotik_processor \n\t\tWHERE host_id IN(SELECT id FROM host AS h WHERE disabled='on' OR h.status=1)");
    $concurrent_processes = read_config_option('mikrotik_concurrent_processes');
    echo "NOTE: Launching Collectors Starting\n";
    $i = 0;
    if (sizeof($hosts)) {
        foreach ($hosts as $host) {
            while (true) {
                $processes = db_fetch_cell('SELECT COUNT(*) FROM plugin_mikrotik_processes');
                if ($processes < $concurrent_processes) {
                    /* put a placeholder in place to prevent overloads on slow systems */
                    $key = rand();
                    db_execute("INSERT INTO plugin_mikrotik_processes (pid, taskid, started) VALUES ({$key}, {$seed}, NOW())");
                    echo "NOTE: Launching Host Collector For: '" . $host['description'] . '[' . $host['hostname'] . "]'\n";
                    process_host($host['host_id'], $seed, $key);
                    usleep(10000);
                    break;
                } else {
                    sleep(1);
                }
            }
        }
    }
    /* taking a break cause for slow systems slow */
    sleep(5);
    echo "NOTE: All Hosts Launched, proceeding to wait for completion\n";
    /* wait for all processes to end or max run time */
    while (true) {
        $processes_left = db_fetch_cell("SELECT count(*) FROM plugin_mikrotik_processes WHERE taskid={$seed}");
        $pl = db_fetch_cell('SELECT count(*) FROM plugin_mikrotik_processes');
        if ($processes_left == 0) {
            echo "NOTE: All Processees Complete, Exiting\n";
            break;
        } else {
            echo "NOTE: Waiting on '{$processes_left}' Processes\n";
            sleep(2);
        }
    }
    echo "NOTE: Updating Last Run Statistics\n";
    // Update the last runtimes
    // All time/dates will be stored in timestamps;
    // Get Collector Lastrun Information
    $storage_lastrun = read_config_option('mikrotik_storage_lastrun');
    $trees_lastrun = read_config_option('mikrotik_trees_lastrun');
    $users_lastrun = read_config_option('mikrotik_users_lastrun');
    $queues_lastrun = read_config_option('mikrotik_queues_lastrun');
    $interfaces_lastrun = read_config_option('mikrotik_interfaces_lastrun');
    $processor_lastrun = read_config_option('mikrotik_processor_lastrun');
    $wireless_reg_lastrun = read_config_option('mikrotik_wireless_reg_lastrun');
    // Get Collection Frequencies (in seconds)
    $storage_freq = read_config_option('mikrotik_storage_freq');
    $processor_freq = read_config_option('mikrotik_processor_freq');
    $trees_freq = read_config_option('mikrotik_trees_freq');
    $users_freq = read_config_option('mikrotik_users_freq');
    $queues_freq = read_config_option('mikrotik_queues_freq');
    $interfaces_freq = read_config_option('mikrotik_interfaces_freq');
    $wireless_reg_freq = read_config_option('mikrotik_wireless_reg_freq');
    /* set the collector statistics */
    if (runCollector($start, $storage_lastrun, $storage_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('mikrotik_storage_lastrun', '{$start}')");
    }
    if (runCollector($start, $trees_lastrun, $trees_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('mikrotik_trees_lastrun', '{$start}')");
        /* for users that are active, increment data */
        db_execute("UPDATE plugin_mikrotik_trees\n\t\t\tSET curBytes=IF(prevBytes>0 AND bytes>prevBytes,(bytes-prevBytes)/{$trees_freq},0),\n\t\t\tcurPackets=IF(prevPackets>0 AND packets>prevPackets,(packets-prevPackets)/{$trees_freq},0),\n\t\t\tcurHCBytes=IF(prevHCBytes>0 AND HCBytes>prevHCBytes,(HCBytes-prevHCBytes)/{$trees_freq},0)\n\t\t\tWHERE present=1");
        /* for users that are active, store previous data */
        db_execute('UPDATE plugin_mikrotik_trees
			SET prevBytes=bytes,
			prevPackets=packets,
			prevHCBytes=HCBytes
			WHERE present=1');
        /* for users that are inactive, clear information */
        db_execute('UPDATE plugin_mikrotik_trees
			SET bytes=0, packets=0, HCBytes=0, 
			curBytes=0, curPackets=0, curHCBytes=0, 
			prevBytes=0, prevPackets=0, prevHCBytes=0
			WHERE present=0');
    }
    if (runCollector($start, $users_lastrun, $users_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('mikrotik_users_lastrun', '{$start}')");
        /* for users that are active, increment data */
        db_execute("UPDATE plugin_mikrotik_users\n\t\t\tSET curBytesIn=IF(prevBytesIn>0 AND bytesIn>prevBytesIn,(bytesIn-prevBytesIn)/{$users_freq},0),\n\t\t\tcurBytesOut=IF(prevBytesIn>0 AND bytesOut>prevBytesOut,(bytesOut-prevBytesOut)/{$users_freq},0),\n\t\t\tcurPacketsIn=IF(prevPacketsIn>0 AND packetsIn>prevPacketsIn,(packetsIn-prevPacketsIn)/{$users_freq},0),\n\t\t\tcurPacketsOut=IF(prevPacketsOut>0 AND packetsOut>prevPacketsOut,(packetsOut-prevPacketsOut)/{$users_freq},0)\n\t\t\tWHERE present=1");
        /* for users that are active, store previous data */
        db_execute('UPDATE plugin_mikrotik_users
			SET prevBytesIn=bytesIn,
			prevBytesOut=bytesOut,
			prevPacketsIn=packetsIn,
			prevPacketsOut=packetsOut
			WHERE present=1');
        /* for users that are inactive, clear information */
        db_execute('UPDATE plugin_mikrotik_users
			SET bytesIn=0, bytesOut=0, packetsIn=0, packetsOut=0, 
			curBytesIn=0, curBytesOut=0, curPacketsIn=0, curPacketsOut=0, 
			prevBytesIn=0, prevBytesOut=0, prevPacketsIn=0, prevPacketsOut=0, 
			connectTime=0
			WHERE present=0 AND userType=0');
    }
    if (runCollector($start, $wireless_reg_lastrun, $wireless_reg_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('mikrotik_wireless_reg_lastrun', '{$start}')");
        /* for users that are active, increment data */
        db_execute("UPDATE plugin_mikrotik_wireless_registrations\n\t\t\tSET curTxBytes=IF(prevTxBytes>0 AND TxBytes>prevTxBytes,(TxBytes-prevTxBytes)/{$wireless_reg_freq},0),\n\t\t\tcurRxBytes=IF(prevRxBytes>0 AND RxBytes>prevRxBytes,(RxBytes-prevRxBytes)/{$wireless_reg_freq},0),\n\t\t\tcurTxPackets=IF(prevTxPackets>0 AND TxPackets>prevTxPackets,(TxPackets-prevTxPackets)/{$wireless_reg_freq},0),\n\t\t\tcurRxPackets=IF(prevRxPackets>0 AND RxPackets>prevRxPackets,(RxPackets-prevRxPackets)/{$wireless_reg_freq},0)\n\t\t\tWHERE present=1");
        /* for users that are active, store previous data */
        db_execute('UPDATE plugin_mikrotik_wireless_registrations
			SET prevTxBytes=TxBytes,
			prevRxBytes=RxBytes,
			prevTxPackets=TxPackets,
			prevRxPackets=RxPackets
			WHERE present=1');
        /* for users that are inactive, clear information */
        db_execute('UPDATE plugin_mikrotik_wireless_registrations
			SET TxBytes=0, TxPackets=0, RxBytes=0, RxPackets=0,
			curTxBytes=0, curTxPackets=0, curRxBytes=0, curRxPackets=0,
			prevTxBytes=0, prevTxPackets=0, prevRxBytes=0, prevRxPackets=0,
			Uptime=0
			WHERE present=0');
    }
    if (runCollector($start, $processor_lastrun, $processor_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('mikrotik_processor_lastrun', '{$start}')");
    }
    if (runCollector($start, $interfaces_lastrun, $interfaces_freq)) {
        global $mikrotikInterfaces;
        db_execute("REPLACE INTO settings (name,value) VALUES ('mikrotik_interfaces_lastrun', '{$start}')");
        $sql = '';
        foreach ($mikrotikInterfaces as $key => $oid) {
            if ($key == 'index') {
                continue;
            }
            if ($key == 'name') {
                continue;
            }
            $sql .= (strlen($sql) ? ',' : '') . 'cur' . $key . '=IF(prev' . $key . '>0 AND ' . $key . '>prev' . $key . ',(' . $key . '-prev' . $key . ')/' . $interfaces_freq . ',0)';
        }
        /* for users that are active, increment data */
        db_execute("UPDATE plugin_mikrotik_interfaces SET {$sql} WHERE present=1");
        $sql = '';
        foreach ($mikrotikInterfaces as $key => $oid) {
            if ($key == 'index') {
                continue;
            }
            if ($key == 'name') {
                continue;
            }
            $sql .= (strlen($sql) ? ',' : '') . 'prev' . $key . '=' . $key;
        }
        /* for users that are active, store previous data */
        db_execute("UPDATE plugin_mikrotik_interfaces SET {$sql} WHERE present=1");
        $sql = '';
        foreach ($mikrotikInterfaces as $key => $oid) {
            if ($key == 'index') {
                continue;
            }
            if ($key == 'name') {
                continue;
            }
            $sql .= (strlen($sql) ? ',' : '') . $key . '=0, cur' . $key . '=0, prev' . $key . '=0';
        }
        /* for users that are inactive, clear information */
        db_execute("UPDATE plugin_mikrotik_interfaces SET {$sql} WHERE present=0");
    }
    if (runCollector($start, $queues_lastrun, $queues_freq)) {
        db_execute("REPLACE INTO settings (name,value) VALUES ('mikrotik_queues_lastrun', '{$start}')");
        /* for users that are active, increment data */
        db_execute("UPDATE plugin_mikrotik_queues\n\t\t\tSET curBytesIn=IF(prevBytesIn>0 AND bytesIn>prevBytesIn,(bytesIn-prevBytesIn)/{$queues_freq},0),\n\t\t\tcurBytesOut=IF(prevBytesIn>0 AND bytesOut>prevBytesOut,(bytesOut-prevBytesOut)/{$queues_freq},0),\n\t\t\tcurPacketsIn=IF(prevPacketsIn>0 AND packetsIn>prevPacketsIn,(packetsIn-prevPacketsIn)/{$queues_freq},0),\n\t\t\tcurPacketsOut=IF(prevPacketsOut>0 AND packetsOut>prevPacketsOut,(packetsOut-prevPacketsOut)/{$queues_freq},0),\n\t\t\tcurQueuesIn=IF(prevQueuesIn>0 AND queuesIn>prevQueuesIn,(queuesIn-prevQueuesIn)/{$queues_freq},0),\n\t\t\tcurQueuesOut=IF(prevQueuesOut>0 AND queuesOut>prevQueuesOut,(queuesOut-prevQueuesOut)/{$queues_freq},0),\n\t\t\tcurDroppedIn=IF(prevDroppedIn>0 AND droppedIn>prevDroppedIn,(droppedIn-prevDroppedIn)/{$queues_freq},0),\n\t\t\tcurDroppedOut=IF(prevDroppedOut>0 AND droppedOut>prevDroppedOut,(droppedOut-prevDroppedOut)/{$queues_freq},0)\n\t\t\tWHERE present=1");
        /* for users that are active, store previous data */
        db_execute('UPDATE plugin_mikrotik_queues
			SET prevBytesIn=bytesIn,
			prevBytesOut=bytesOut,
			prevPacketsIn=packetsIn,
			prevPacketsOut=packetsOut,
			prevQueuesIn=QueuesIn,
			prevQueuesOut=QueuesOut,
			prevDroppedIn=DroppedIn,
			prevDroppedOut=DroppedOut
			WHERE present=1');
        /* for users that are inactive, clear information */
        db_execute('UPDATE plugin_mikrotik_queues
			SET bytesIn=0, bytesOut=0, packetsIn=0, packetsOut=0, queuesIn=0, queuesOut=0, droppedIn=0, droppedOut=0,
			curBytesIn=0, curBytesOut=0, curPacketsIn=0, curPacketsOut=0, curQueuesIn=0, curQueuesOut=0, curDroppedIn=0, curDroppedOut=0,
			prevBytesIn=0, prevBytesOut=0, prevPacketsIn=0, prevPacketsOut=0, prevQueuesIn=0, prevQueuesOut=0, prevDroppedIn=0, prevDroppedOut=0
			WHERE present=0');
    }
    if (read_config_option('mikrotik_autopurge') == 'on') {
        echo "NOTE: Auto Purging Hosts\n";
        $dead_hosts = db_fetch_assoc("SELECT host_id FROM plugin_mikrotik_system AS hr\n\t\t\tLEFT JOIN host AS h\n\t\t\tON h.id=hr.host_id\n\t\t\tWHERE h.id IS NULL");
        if (sizeof($dead_hosts)) {
            foreach ($dead_hosts as $host) {
                db_execute('DELETE FROM plugin_mikrotik_processor WHERE host_id=' . $host['host_id']);
                db_execute('DELETE FROM plugin_mikrotik_system WHERE host_id=' . $host['host_id']);
                db_execute('DELETE FROM plugin_mikrotik_trees WHERE host_id=' . $host['host_id']);
                db_execute('DELETE FROM plugin_mikrotik_users WHERE host_id=' . $host['host_id']);
                db_execute('DELETE FROM plugin_mikrotik_queues WHERE host_id=' . $host['host_id']);
                echo "Purging Host with ID '" . $host['host_id'] . "'\n";
            }
        }
    }
    echo "NOTE: Updating Summary Statistics for Each Host\n";
    /* update some statistics in system */
    $stats = db_fetch_assoc('SELECT h.id AS host_id,
		h.status AS host_status,
		AVG(`load`) AS cpuPercent,
		COUNT(`load`) AS numCpus
		FROM host AS h
		INNER JOIN plugin_mikrotik_system AS hrs
		ON h.id=hrs.host_id
		LEFT JOIN plugin_mikrotik_processor AS hrp
		ON hrp.host_id=hrs.host_id
		GROUP BY h.id, h.status');
    if (sizeof($stats)) {
        $sql_insert = '';
        $sql_prefix = 'INSERT INTO plugin_mikrotik_system
			(host_id, host_status, cpuPercent, numCpus) VALUES ';
        $sql_suffix = ' ON DUPLICATE KEY UPDATE
			host_status=VALUES(host_status),
			cpuPercent=VALUES(cpuPercent),
			numCpus=VALUES(numCpus)';
        $j = 0;
        foreach ($stats as $s) {
            $sql_insert .= (strlen($sql_insert) ? ', ' : '') . '(' . $s['host_id'] . ', ' . $s['host_status'] . ', ' . (!empty($s['cpuPercent']) ? $s['cpuPercent'] : '0') . ', ' . (!empty($s['numCpus']) ? $s['numCpus'] : '0') . ')';
            $j++;
            if ($j % 200 == 0) {
                db_execute($sql_prefix . $sql_insert . $sql_suffix);
                $sql_insert = '';
            }
        }
        if (strlen($sql_insert)) {
            db_execute($sql_prefix . $sql_insert . $sql_suffix);
        }
    }
    /* update the memory information */
    db_execute('INSERT INTO plugin_mikrotik_system
		(host_id, memSize, memUsed, diskSize, diskUsed)
		SELECT host_id,
		SUM(CASE WHEN type=11 THEN size * allocationUnits ELSE 0 END) AS memSize,
		SUM(CASE WHEN type=11 THEN (used / size) * 100 ELSE 0 END) AS memUsed,
		SUM(CASE WHEN type=14 THEN size * allocationUnits ELSE 0 END) AS diskSize,
		SUM(CASE WHEN type=14 THEN (used / size) * 100 ELSE 0 END) AS diskUsed
		FROM plugin_mikrotik_storage
		WHERE type IN(11,14)
		GROUP BY host_id
		ON DUPLICATE KEY UPDATE
			memSize=VALUES(memSize),
			memUsed=VALUES(memUsed),
			diskSize=VALUES(diskSize),
			diskUsed=VALUES(diskUsed)');
    /* update the user information */
    db_execute('INSERT INTO plugin_mikrotik_system
		(host_id, users)
		SELECT host_id,
		COUNT(name) AS users
		FROM plugin_mikrotik_users
		WHERE present=1
		GROUP BY host_id
		ON DUPLICATE KEY UPDATE
			users=VALUES(users)');
    /* update the maxProcesses information */
    db_execute('UPDATE plugin_mikrotik_system SET maxProcesses=processes WHERE processes>maxProcesses');
    echo "NOTE: Detecting Host Types Based Upon Host Types Table\n";
    /* for hosts that are down, clear information */
    db_execute('UPDATE plugin_mikrotik_system
		SET users=0, cpuPercent=0, processes=0, memUsed=0, diskUsed=0, uptime=0, sysUptime=0
		WHERE host_status IN (0,1)');
    // Clear tables when disabled
    if ($storage_freq == -1) {
        db_execute("TRUNCATE plugin_mikrotik_storage");
    } else {
        db_execute("DELETE FROM plugin_mikrotik_storage WHERE host_id NOT IN (SELECT id FROM host)");
    }
    if ($processor_freq == -1) {
        db_execute("TRUNCATE plugin_mikrotik_processor");
    } else {
        db_execute("DELETE FROM plugin_mikrotik_processor WHERE host_id NOT IN (SELECT id FROM host)");
    }
    if ($trees_freq == -1) {
        db_execute("TRUNCATE plugin_mikrotik_trees");
    } else {
        db_execute("DELETE FROM plugin_mikrotik_trees WHERE host_id NOT IN (SELECT id FROM host)");
    }
    if ($users_freq == -1) {
        db_execute("TRUNCATE plugin_mikrotik_users");
    } else {
        db_execute("DELETE FROM plugin_mikrotik_users WHERE host_id NOT IN (SELECT id FROM host)");
    }
    if ($queues_freq == -1) {
        db_execute("TRUNCATE plugin_mikrotik_queues");
    } else {
        db_execute("DELETE FROM plugin_mikrotik_queues WHERE host_id NOT IN (SELECT id FROM host)");
    }
    if ($interfaces_freq == -1) {
        db_execute("TRUNCATE plugin_mikrotik_interfaces");
    } else {
        db_execute("DELETE FROM plugin_mikrotik_interfaces WHERE host_id NOT IN (SELECT id FROM host)");
    }
    /* prune old tables of orphan hosts */
    db_execute("DELETE FROM plugin_mikrotik_system WHERE host_id NOT IN (SELECT id FROM host)");
    db_execute("DELETE FROM plugin_mikrotik_system_health WHERE host_id NOT IN (SELECT id FROM host)");
    /* take time and log performance data */
    list($micro, $seconds) = explode(' ', microtime());
    $end = $seconds + $micro;
    $interfaces = db_fetch_cell("SELECT count(*) FROM plugin_mikrotik_interfaces WHERE present=1");
    $queues = db_fetch_cell("SELECT count(*) FROM plugin_mikrotik_queues WHERE present=1");
    $users = db_fetch_cell("SELECT count(*) FROM plugin_mikrotik_users WHERE present=1");
    $trees = db_fetch_cell("SELECT count(*) FROM plugin_mikrotik_trees WHERE present=1");
    $waps = db_fetch_cell("SELECT count(*) FROM plugin_mikrotik_wireless_aps WHERE present=1");
    $wreg = db_fetch_cell("SELECT count(*) FROM plugin_mikrotik_wireless_registrations WHERE present=1");
    $cacti_stats = sprintf('Time:%01.4f Processes:%s Hosts:%s Interfaces:%s Queues:%s Users:%s Trees:%s Waps:%s Wreg:%s', round($end - $start, 2), $concurrent_processes, sizeof($hosts), $interfaces, $queues, $users, $trees, $waps, $wreg);
    /* log to the database */
    db_execute("REPLACE INTO settings (name,value) VALUES ('stats_mikrotik', '" . $cacti_stats . "')");
    /* log to the logfile */
    cacti_log('MIKROTIK STATS: ' . $cacti_stats, TRUE, 'SYSTEM');
    echo "NOTE: MikroTik Polling Completed, {$cacti_stats}\n";
    /* launch the graph creation process */
    process_graphs();
}