mirror of
https://github.com/Cacti/plugin_thold.git
synced 2026-10-23 03:27:05 +09:00
* Add PHPDoc blocks: small files batch (cli_import, poller_thold, includes/tab, includes/database, cli_thresholds, thold_notify, notify_queue) * Add PHPDoc blocks: includes/polling.php, includes/settings.php (WIP checkpoint) * Add PHPDoc blocks: thold_process.php, thold_daemon.php (WIP checkpoint) * Add PHPDoc blocks: thold_webapi.php (WIP checkpoint) * Add PHPDoc blocks: thold.php (WIP checkpoint) * Add PHPDoc blocks: thold_graph.php (WIP checkpoint) * Add PHPDoc blocks: notify_lists.php (WIP checkpoint) * Add PHPDoc blocks: thold_templates.php (WIP checkpoint) * Add PHPDoc blocks: setup.php batch 1-2 (WIP checkpoint) * Add PHPDoc blocks: setup.php batch 3-4 (WIP checkpoint) * Add PHPDoc blocks: setup.php batch 5 (WIP checkpoint) * Add PHPDoc blocks: setup.php batch 6-7 (WIP checkpoint) * Add PHPDoc blocks: setup.php complete * Address review feedback and refresh translation template - Fix thold_update_host_status() return type (int|null, since it falls through with no explicit return in the normal case) - Fix @global $device_change_fields description in thold_config_arrays() (appends this plugin's fields, not unused) - Fix @global $config description in thold_graph_button() (used to build the Create Threshold link's URL) - Fix thold_data_source_action_prepare()/thold_graphs_action_prepare() return types (array|void; only the non-plugin_thold_create branch returns $save) - Fix @global $timearray description in list_tholds() (used to render each baseline threshold's reference time range) - Fix @global $thold_types description in thold_show_log() (used to render each log row's type column) - Regenerate locales/po/cacti.pot (source line references only) - Fix .gitignore pattern for compiled .mo files (locales/LC_MESSAGES/, not locales/po/) * test(coverage): allowlist untestable entry points touched by PHPDoc pass This PR only adds PHPDoc blocks (no functional changes), but touching every file in the plugin newly triggers the 'Enforce coverage of changed lines' CI gate for files that were never require()'d by any test before now: - cli_import.php, cli_thresholds.php: CLI entry points (include cli_check.php / chdir + execute at the top level). - poller_thold.php: poller entry point, same category. - thold.php, thold_graph.php, thold_templates.php, notify_lists.php: authenticated web entry points (chdir + include(auth.php) at the top level), like notify_queue.php/thold_notify.php already allowlisted above. - thold_daemon.php: daemon entry point, same category as thold_process.php already allowlisted above. - includes/settings.php, includes/tab.php: Settings-page/header-tab-bar hook callbacks, only meaningful inside a live Cacti page render. - thold_webapi.php: web-page action handlers that read \ and the database directly. None of these can be require()'d into the isolated unit test process, matching the existing allowlist entries' precedent exactly. Verified locally: running patch-coverage.php against the PR's actual base ref confirms all 11 files are no longer reported as unexpected-unmeasured. * docs: add PHPDoc blocks to remaining thold_functions.php functions * chore: refresh translation template after PHPDoc line-number shifts
339 lines
10 KiB
PHP
339 lines
10 KiB
PHP
<?php
|
|
/*
|
|
+-------------------------------------------------------------------------+
|
|
| Copyright (C) 2004-2026 The Cacti Group |
|
|
| |
|
|
| 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. |
|
|
+-------------------------------------------------------------------------+
|
|
| Cacti: The Complete RRDtool-based Graphing Solution |
|
|
+-------------------------------------------------------------------------+
|
|
| This code is designed, written, and maintained by the Cacti Group. See |
|
|
| about.php and/or the AUTHORS file for specific developer information. |
|
|
+-------------------------------------------------------------------------+
|
|
| http://www.cacti.net/ |
|
|
+-------------------------------------------------------------------------+
|
|
*/
|
|
|
|
// let PHP run just as long as it has to and to chew up memory too
|
|
ini_set('max_execution_time', '0');
|
|
ini_set('memory_limit', '-1');
|
|
|
|
$dir = __DIR__;
|
|
chdir($dir);
|
|
|
|
if (strpos($dir, 'plugins') !== false) {
|
|
chdir('../../');
|
|
}
|
|
|
|
include('./include/cli_check.php');
|
|
include_once($config['base_path'] . '/plugins/thold/setup.php');
|
|
include_once($config['base_path'] . '/plugins/thold/thold_functions.php');
|
|
include_once($config['base_path'] . '/plugins/thold/includes/polling.php');
|
|
include_once($config['base_path'] . '/lib/rrd.php');
|
|
include_once($config['base_path'] . '/lib/poller.php');
|
|
|
|
// process calling arguments
|
|
$parms = $_SERVER['argv'];
|
|
array_shift($parms);
|
|
|
|
$debug = false;
|
|
$force = false;
|
|
$start = microtime(true);
|
|
|
|
global $debug;
|
|
|
|
$poller_id = $config['poller_id'];
|
|
|
|
if (cacti_sizeof($parms)) {
|
|
foreach ($parms as $parameter) {
|
|
if (strpos($parameter, '=')) {
|
|
[$arg, $value] = explode('=', $parameter);
|
|
} else {
|
|
$arg = $parameter;
|
|
$value = '';
|
|
}
|
|
|
|
switch ($arg) {
|
|
case '-f':
|
|
case '--force':
|
|
$force = true;
|
|
|
|
break;
|
|
case '-d':
|
|
case '--debug':
|
|
$debug = true;
|
|
|
|
break;
|
|
case '--version':
|
|
case '-V':
|
|
case '-v':
|
|
display_version();
|
|
exit;
|
|
case '--help':
|
|
case '-H':
|
|
case '-h':
|
|
display_help();
|
|
exit;
|
|
default:
|
|
print 'ERROR: Invalid Parameter ' . $parameter . "\n\n";
|
|
display_help();
|
|
exit;
|
|
}
|
|
}
|
|
}
|
|
|
|
print "Starting the Thold Poller Process\n";
|
|
|
|
// silently end if the registered process is still running, or process table missing
|
|
if (!register_process_start('thold', 'master', $config['poller_id'], read_config_option('poller_interval'))) {
|
|
exit(0);
|
|
}
|
|
|
|
// perform all key thold functions
|
|
perform_thold_processes();
|
|
|
|
unregister_process('thold', 'master', $config['poller_id']);
|
|
|
|
/**
|
|
* Main Thold poller routine: ensures a sane empty-interface-speed
|
|
* default, force-upgrades the database when a known-missing column is
|
|
* detected, prunes stale dead-host notification records, launches the
|
|
* background notification queue daemon if configured and not already
|
|
* running, then processes all configured thresholds.
|
|
*
|
|
* @return void
|
|
*
|
|
* @global array $config Cacti global configuration array; used to
|
|
* locate library files and build the
|
|
* notification daemon's command line.
|
|
*/
|
|
function perform_thold_processes() {
|
|
global $config;
|
|
|
|
// record the start time
|
|
$start = microtime(true);
|
|
|
|
if (read_config_option('thold_empty_if_speed_default') == '') {
|
|
set_config_option('thold_empty_if_speed_default', '10000');
|
|
$empty_value = read_config_option('thold_empty_if_speed_default', true);
|
|
}
|
|
|
|
// Force upgrade the database if there is a problem
|
|
if (!db_column_exists('thold_data', 'name_cache')) {
|
|
thold_debug('Upgrading Thold database now.');
|
|
|
|
include_once($config['base_path'] . '/plugins/thold/includes/database.php');
|
|
|
|
thold_upgrade_database(true);
|
|
} else {
|
|
thold_debug('Not upgrading Thold database.');
|
|
}
|
|
|
|
// handle changes in deadnotify
|
|
thold_debug('Pruning stale dead host notifications.');
|
|
|
|
$deadnotify = (read_config_option('alert_deadnotify') == 'on');
|
|
|
|
if (!$deadnotify) {
|
|
db_execute('TRUNCATE plugin_thold_host_failed');
|
|
} else {
|
|
db_execute('DELETE FROM plugin_thold_host_failed WHERE host_id NOT IN (SELECT id FROM host)');
|
|
}
|
|
|
|
// launch the notification background process if required
|
|
$notification_queue = read_config_option('thold_notification_queue');
|
|
$notification_daemon = read_config_option('thold_notification_daemon');
|
|
|
|
if ($notification_queue == 'on' && $notification_daemon == '') {
|
|
thold_debug('Launching Thold notification process.');
|
|
|
|
$command_string = cacti_escapeshellcmd(read_config_option('path_php_binary'));
|
|
$file_path = $config['base_path'] . '/plugins/thold/thold_notify.php';
|
|
|
|
if (file_exists($file_path)) {
|
|
exec_background($command_string, $file_path);
|
|
}
|
|
}
|
|
|
|
if (read_config_option('thold_daemon_enable') == '') {
|
|
thold_debug('Thold daemon not enabled. Preparing to perform checks.');
|
|
|
|
// perform all thold checks
|
|
thold_debug('Thold checks started.');
|
|
$tholds = thold_check_all_thresholds();
|
|
thold_debug('Thold checks finished.');
|
|
|
|
thold_debug('Down device checks started.');
|
|
$nhosts = thold_update_host_status();
|
|
thold_debug('Down device checks finished.');
|
|
|
|
thold_debug('Thold Log Cleanup started.');
|
|
thold_cleanup_log();
|
|
thold_debug('Thold Log Cleanup finished.');
|
|
|
|
if (read_config_option('remote_storage_method') == 1) {
|
|
$total_hosts = db_fetch_cell_prepared('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE disabled = ""
|
|
AND poller_id = ?',
|
|
[$config['poller_id']]);
|
|
|
|
$down_hosts = db_fetch_cell_prepared('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE status = 1
|
|
AND disabled = ""
|
|
AND poller_id = ?',
|
|
[$config['poller_id']]);
|
|
} else {
|
|
$total_hosts = db_fetch_cell('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE disabled = ""');
|
|
|
|
$down_hosts = db_fetch_cell('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE status = 1
|
|
AND disabled = ""');
|
|
}
|
|
|
|
thold_debug('Prune old data started.');
|
|
thold_prune_old_data();
|
|
thold_debug('Prune old data finished.');
|
|
|
|
// record the end time
|
|
$end = microtime(true);
|
|
|
|
// log statistics
|
|
$thold_stats = sprintf('Time:%0.2f Tholds:%d TotalDevices:%d DownDevices:%d NewDownDevices:%d', $end - $start, $tholds, $total_hosts, $down_hosts, $nhosts);
|
|
|
|
cacti_log('THOLD STATS: ' . $thold_stats, false, 'SYSTEM');
|
|
|
|
set_config_option('stats_thold', $thold_stats);
|
|
} else {
|
|
// collect some stats
|
|
$now = microtime(true);
|
|
|
|
// get the last update from the daemon
|
|
$heartbeat = read_config_option('thold_daemon_heartbeat');
|
|
$poller_interval = read_config_option('poller_interval');
|
|
$curtime = time();
|
|
$frequency = read_config_option('thold_daemon_dead_notification');
|
|
|
|
if ($frequency > 0) {
|
|
if (empty($heartbeat)) {
|
|
$last_notification = read_config_option('thold_daemon_down_notify_time');
|
|
|
|
if ($curtime - $last_notification > $frequency) {
|
|
admin_email('Thold Daemon Not Started', 'WARNING: You have elected to use the Thold Daemon, but it appears not to be running. Please correct this right away');
|
|
set_config_option('thold_daemon_down_notify_time', $curtime);
|
|
}
|
|
} elseif ($now - $heartbeat > 3 * $poller_interval) {
|
|
$last_notification = read_config_option('thold_daemon_down_notify_time');
|
|
|
|
if ($curtime - $last_notification > $frequency) {
|
|
admin_email('Thold Daemon Down', 'WARNING: You have elected to use the Thold Daemon, but it appears have stopped running. Please correct this right away');
|
|
set_config_option('thold_daemon_down_notify_time', $curtime);
|
|
}
|
|
}
|
|
}
|
|
|
|
$threads = read_config_option('thold_max_concurrent_processes');
|
|
|
|
if (read_config_option('remote_storage_method') == 1) {
|
|
// host_status processed by thold server
|
|
$nhosts = thold_update_host_status();
|
|
|
|
thold_cleanup_log();
|
|
|
|
$total_hosts = db_fetch_cell_prepared('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE disabled = ""
|
|
AND poller_id = ?',
|
|
[$config['poller_id']]);
|
|
|
|
$down_hosts = db_fetch_cell_prepared('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE status = 1
|
|
AND disabled = ""
|
|
AND poller_id = ?',
|
|
[$config['poller_id']]);
|
|
|
|
$thresholds = db_fetch_cell_prepared('SELECT COUNT(*)
|
|
FROM thold_data
|
|
INNER JOIN host
|
|
ON host.id = thold_data.host_id
|
|
WHERE poller_id = ?
|
|
AND disabled = ""',
|
|
[$config['poller_id']]);
|
|
} else {
|
|
// host_status processed by thold server
|
|
$nhosts = thold_update_host_status();
|
|
|
|
thold_cleanup_log();
|
|
|
|
$total_hosts = db_fetch_cell('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE disabled=""');
|
|
|
|
$down_hosts = db_fetch_cell('SELECT COUNT(*)
|
|
FROM host
|
|
WHERE status = 1
|
|
AND disabled = ""');
|
|
|
|
$thresholds = db_fetch_cell('SELECT COUNT(*)
|
|
FROM thold_data
|
|
INNER JOIN host
|
|
ON host.id = thold_data.host_id
|
|
WHERE disabled = ""');
|
|
}
|
|
|
|
thold_prune_old_data();
|
|
|
|
// record the end time
|
|
$end = microtime(true);
|
|
|
|
// log statistics
|
|
$thold_stats = sprintf('Time:%0.2f TotalDevices:%u DownDevices:%u NewDownDevices:%u Threads:%u Thresholds:%u',
|
|
$end - $start, $total_hosts, $down_hosts, $nhosts, $threads, $thresholds);
|
|
|
|
cacti_log('THOLD POLLER STATS: ' . $thold_stats, false, 'SYSTEM');
|
|
|
|
set_config_option('stats_thold_' . $config['poller_id'], $thold_stats);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* display_version - displays version information
|
|
*/
|
|
function display_version() {
|
|
global $config;
|
|
|
|
if (!function_exists('plugin_thold_version')) {
|
|
include_once($config['base_path'] . '/plugins/thold/setup.php');
|
|
}
|
|
|
|
$info = plugin_thold_version();
|
|
|
|
print 'Cacti Thold Master Process, Version ' . $info['version'] . ', ' . COPYRIGHT_YEARS . "\n";
|
|
}
|
|
|
|
/**
|
|
* display_help - displays the usage of the function
|
|
*/
|
|
function display_help() {
|
|
display_version();
|
|
|
|
print "\nusage: poller_thold.php [--debug] [--force]\n\n";
|
|
print "This binary run various Threshold data collection and\n";
|
|
print "Management function.\n\n";
|
|
print "--force - Force all the service checks to run now\n";
|
|
print "--debug - Display verbose output during execution\n\n";
|
|
}
|