Add PHPDoc blocks to undocumented functions (partial - thold_functions.php follow-up owed) (#828)

* 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
This commit is contained in:
TheWitness authored and GitHub committed 2026-09-25 12:30:04 -04:00
1 parent 38ea27b74e
commit 41dc700357
21 files changed
+3754 -938

No files matched your search

+1
View File
@@ -20,6 +20,7 @@
# +-------------------------------------------------------------------------+
locales/po/*.mo
locales/LC_MESSAGES/*.mo
/.phpunit.cache/
/coverage/
+15 -1
View File
@@ -151,6 +151,15 @@ if ($errors == 0) {
exit(1);
}
/**
* Prints this script's name, version, and copyright banner to stdout.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate setup.php when plugin_thold_version()
* isn't already loaded.
*/
function display_version() {
global $config;
@@ -162,7 +171,12 @@ function display_version() {
print 'Threshold Template Import Utility, Version ' . $info['version'] . ', ' . COPYRIGHT_YEARS . PHP_EOL;
}
// display_help - displays the usage of the function
/**
* Prints this script's version banner followed by its command-line
* usage instructions to stdout.
*
* @return void
*/
function display_help() {
display_version();
+31 -1
View File
@@ -166,6 +166,22 @@ if ($ttemplate == 0 && $gtemplate == 0 && $hids == '' && $gids == '') {
thold_cli_autocreate($hids, $gids, $gtemplate, $ttemplate);
/**
* Auto-creates thresholds for the given devices/graphs by delegating
* to autocreate(), then prints any resulting session flash messages
* (stripped of HTML) to stdout.
*
* @param string $hids Space-delimited host ids to create
* thresholds for (default '').
* @param string $gids Space-delimited graph ids to create
* thresholds for (default '').
* @param int $gtemplate The graph template id to filter by (default
* 0).
* @param int $ttemplate The threshold template id to apply (default
* 0).
*
* @return void
*/
function thold_cli_autocreate($hids = '', $gids = '', $gtemplate = 0, $ttemplate = 0) {
print 'Auto Creating Thresholds' . PHP_EOL;
@@ -180,6 +196,15 @@ function thold_cli_autocreate($hids = '', $gids = '', $gtemplate = 0, $ttemplate
}
}
/**
* Prints this script's name, version, and copyright banner to stdout.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate setup.php when plugin_thold_version()
* isn't already loaded.
*/
function display_version() {
global $config;
@@ -191,7 +216,12 @@ function display_version() {
print 'Threshold Command Line Interface, Version ' . $info['version'] . ', ' . COPYRIGHT_YEARS . PHP_EOL;
}
// display_help - displays the usage of the function
/**
* Prints this script's version banner followed by its command-line
* usage instructions to stdout.
*
* @return void
*/
function display_help() {
display_version();
+29
View File
@@ -22,6 +22,27 @@
+-------------------------------------------------------------------------+
*/
/**
* Runs the plugin's incremental version-to-version schema and settings
* migrations, comparing the currently installed plugin_config version
* against the running code's version and applying each intervening
* upgrade step. Also (re-)creates the full expected schema via
* thold_setup_database() first, so this is safe to call for both
* fresh installs and upgrades.
*
* @param bool $force Whether to force re-running every migration step
* regardless of the recorded installed version
* (default false).
*
* @return void
*
* @global array $config Cacti global configuration array;
* used to locate library/plugin files
* to include.
* @global string $database_default Reserved/declared for parity with
* other functions in this file; not
* used directly here.
*/
function thold_upgrade_database($force = false) {
global $config, $database_default;
include_once($config['library_path'] . '/database.php');
@@ -1811,6 +1832,14 @@ function thold_upgrade_database($force = false) {
}
}
/**
* Creates (or updates, via Cacti's schema installer) all of this
* plugin's database tables and their columns/keys. Invoked during
* plugin installation and as the first step of
* thold_upgrade_database().
*
* @return void
*/
function thold_setup_database() {
$data = [];
$data['columns'][] = ['name' => 'id', 'type' => 'int(11)', 'NULL' => false, 'auto_increment' => true];
+83
View File
@@ -22,6 +22,39 @@
+-------------------------------------------------------------------------+
*/
/**
* Launches the Thold poller script (poller_thold.php) as a background
* process, logging a fatal error instead if the script file is
* missing. Registered as the 'poller_bottom' Cacti hook, invoked at
* the end of each Cacti poller cycle.
*
* @return void
*
* @global array $config Cacti global configuration array;
* used to build the poller script's
* path and command line.
* @global string $database_type Reserved/declared for parity with
* other functions in this file; not
* used directly here.
* @global string $database_default Reserved/declared for parity with
* other functions in this file; not
* used directly here.
* @global string $database_hostname Reserved/declared for parity with
* other functions in this file; not
* used directly here.
* @global string $database_username Reserved/declared for parity with
* other functions in this file; not
* used directly here.
* @global string $database_password Reserved/declared for parity with
* other functions in this file; not
* used directly here.
* @global int $database_port Reserved/declared for parity with
* other functions in this file; not
* used directly here.
* @global bool $database_ssl Reserved/declared for parity with
* other functions in this file; not
* used directly here.
*/
function thold_poller_bottom() {
global $config, $database_type, $database_default, $database_hostname;
global $database_username, $database_password, $database_port, $database_ssl;
@@ -36,6 +69,14 @@ function thold_poller_bottom() {
}
}
/**
* Deletes plugin_thold_log entries older than the configured retention
* period (thold_log_storage days, defaulting to and persisting 31 if
* unset), and updates the last-change timestamp setting when any rows
* were actually removed.
*
* @return void
*/
function thold_cleanup_log() {
$daysToStoreLogs = read_config_option('thold_log_storage');
@@ -55,6 +96,23 @@ function thold_cleanup_log() {
}
}
/**
* Cacti poller output-processing hook: intercepts newly collected RRD
* data source values, re-indexes them by data source id for threshold
* evaluation, and hands them off to the threshold-checking logic
* before/alongside the normal RRD update flow. Registered as a Cacti
* poller output hook.
*
* @param array &$rrd_update_array The newly collected poller output
* data, keyed by local_data_id.
*
* @return array The (possibly filtered/annotated) $rrd_update_array,
* for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate library files to include.
* @global bool $debug Whether debug output is enabled.
*/
function thold_poller_output(&$rrd_update_array) {
global $config, $debug;
@@ -264,6 +322,18 @@ function thold_poller_output(&$rrd_update_array) {
return $rrd_update_array;
}
/**
* Evaluates every configured threshold against its data source's
* current/historical values (fetching remote-poller data directly from
* the remote database when remote storage is configured), triggering
* notifications/alerts for thresholds that have tripped or recovered.
* Invoked once per poller cycle from the main threshold-checking flow.
*
* @return int The total number of thresholds evaluated.
*
* @global array $config Cacti global configuration array; used to
* locate library files to include.
*/
function thold_check_all_thresholds() {
global $config;
@@ -368,6 +438,19 @@ function thold_check_all_thresholds() {
return $total_tholds;
}
/**
* Checks each monitored host's reachability status (including hosts
* managed by the Maint plugin, when enabled) and records/clears dead-
* host notification tracking rows, when the alert_deadnotify setting
* is enabled; a no-op otherwise.
*
* @return int|null 0 immediately if dead-host notifications are
* disabled; otherwise no explicit return value
* (null).
*
* @global array $config Cacti global configuration array; used to
* locate library files to include.
*/
function thold_update_host_status() {
global $config;
+83
View File
@@ -22,6 +22,21 @@
+-------------------------------------------------------------------------+
*/
/**
* Registers this plugin's pages (thresholds, threshold graphs/failure
* views, templates, notification lists/queue) and their sub-
* actions/edit views into Cacti's breadcrumb navigation array.
* Registered as the 'draw_navigation_text' Cacti hook.
*
* @param array $nav The existing navigation entries array, keyed by
* "file.php:action".
*
* @return array The navigation entries array with this plugin's pages
* added.
*
* @global array $config Cacti global configuration array (declared but
* not used directly here).
*/
function thold_draw_navigation_text($nav) {
global $config;
@@ -215,6 +230,18 @@ function thold_draw_navigation_text($nav) {
return $nav;
}
/**
* Registers this plugin's Console menu entries, applies the current
* session's threshold-vertical-rule display preference (and
* corresponding BoostFS PNG cache trade-off), and defines this
* plugin's global status/severity/message-level constants (guarded so
* they're only defined once). Invoked early in plugin initialization.
*
* @return void
*
* @global array $menu Cacti Console menu registry; this plugin's
* entries are added.
*/
function thold_config_insert() {
global $menu;
@@ -269,6 +296,24 @@ function thold_config_insert() {
}
}
/**
* Registers this plugin's flash-message templates, surfaces any
* pending session-stored message, and (when installed as a fresh
* plugin) augments Cacti's built-in user roles with permissions for
* this plugin's pages. Registered as the 'config_arrays' Cacti hook.
*
* @return void
*
* @global array $config Cacti global configuration
* array.
* @global array $messages Cacti flash-message registry;
* this plugin's messages are
* added.
* @global array $device_change_fields Registry of per-device change
* tracking fields; this plugin's
* fields are appended to
* 'match_field'.
*/
function thold_config_arrays() {
global $config, $messages, $device_change_fields;
@@ -305,6 +350,19 @@ function thold_config_arrays() {
kill_session_var('thold_message');
}
/**
* Injects this plugin's device up/down notification settings fields
* (notification list selection, email notification mode, failure
* count threshold) into the Cacti device edit form's field list,
* positioned after the bulk walk size (or disabled) field. Registered
* as the 'config_form' Cacti hook.
*
* @return void
*
* @global array $fields_host_edit The Cacti device edit form's field
* definitions; updated in place with
* this plugin's fields inserted.
*/
function thold_config_form() {
global $fields_host_edit;
@@ -374,6 +432,31 @@ function thold_config_form() {
$fields_host_edit = $fields_host_edit3;
}
/**
* Builds this plugin's Console "Settings > Alerting/Thold" tab's field
* definitions (thresholds behavior, notification settings, syslog
* options, etc.), running any pending plugin upgrade first. Registered
* as the 'config_settings' Cacti hook; a no-op outside of settings.php.
*
* @return void
*
* @global array $tabs Cacti settings tabs registry;
* an 'alerts' entry is added.
* @global array $settings Cacti settings field registry;
* an 'alerts' section is added.
* @global array $item_rows Reserved/declared for parity
* with other functions in this
* file; not used directly here.
* @global array $config Cacti global configuration
* array; used to locate library
* files to include.
* @global array $syslog_facil_array Syslog facility option list
* used by syslog-related settings
* fields.
* @global array $syslog_priority_array Syslog priority option list
* used by syslog-related settings
* fields.
*/
function thold_config_settings() {
global $tabs, $settings, $item_rows, $config, $syslog_facil_array, $syslog_priority_array;
+11
View File
@@ -22,6 +22,17 @@
+-------------------------------------------------------------------------+
*/
/**
* Renders this plugin's tab icon/link in the graph/console header tab
* bar, highlighted when the current page is one of this plugin's
* views. Shown only to users with view permission. Registered as a
* Cacti header-tabs hook.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* build asset and page URLs.
*/
function thold_show_tab() {
global $config;
+906 -906
View File
File diff suppressed because it is too large. Load diff
+118
View File
@@ -77,6 +77,15 @@ switch (get_request_var('action')) {
The Save Function
-------------------------- */
/**
* Validates and saves the notification list edit form's submitted
* fields, rejecting the save if the same email address appears in both
* the To and BCC lists, then redirects back to the edit form for the
* saved (or original) list id. Called from this script's main
* request-dispatch switch when action=save.
*
* @return void
*/
function form_save() {
if (isset_request_var('save_component')) {
$save['id'] = get_filter_request_var('id');
@@ -142,6 +151,22 @@ function form_save() {
The 'actions' function
------------------------ */
/**
* Handles the bulk-action confirmation page/submission for the
* notification lists view and its host/threshold/template association
* sub-views, validating the requested action against the combined set
* of list-level and association-level allowed actions before
* dispatching. Called from this script's main request-dispatch switch
* when action=actions.
*
* @return void
*
* @global array $actions Map of drp_action value => action label
* for list-level bulk actions.
* @global array $assoc_actions Map of drp_action value => action label
* for host/threshold/template association
* bulk actions.
*/
function form_actions() {
global $actions, $assoc_actions;
@@ -979,6 +1004,13 @@ function form_actions() {
Notification List Edit
---------------------------- */
/**
* Builds the "[edit: name]" or "[new]" header suffix label for the
* notification list edit page, based on whether an existing list id
* request variable is present.
*
* @return string The escaped header label suffix.
*/
function get_notification_header_label() {
if (!isempty_request_var('id')) {
$list = db_fetch_row_prepared('SELECT *
@@ -994,6 +1026,21 @@ function get_notification_header_label() {
return $header_label;
}
/**
* Renders the tabbed add/edit page for a notification list: displays
* the tab bar (General, Devices, Thresholds, Templates) when editing
* an existing list, then renders the currently selected tab's content
* (the general settings form on the 'general' tab, or delegates to
* hosts()/tholds()/templates() for the association tabs). Called from
* this script's main request-dispatch switch when action=edit.
*
* @return void
*
* @global array $tabs_thold Map of tab short-name => display label,
* used to render the tab bar.
* @global array $config Cacti global configuration array; used to
* build tab URLs.
*/
function edit() {
global $tabs_thold, $config;
@@ -1125,6 +1172,24 @@ function edit() {
}
}
/**
* Renders the notification list's \"Devices\" tab: validates/stores this
* tab's filter request variables, displays the device filter form, then
* displays a filtered, sorted, paginated table of devices with their
* association status to this list and a bulk-actions dropdown to
* associate/disassociate them.
*
* @param string $header_label The \"[edit: name]\"/\"[new]\" header label
* suffix to display in the box title.
*
* @return void
*
* @global array $assoc_actions Map of drp_action value => action label,
* used for the bulk-actions dropdown.
* @global array $item_rows Default number of rows per page from
* Cacti settings.
* @global array $config Cacti global configuration array.
*/
function hosts($header_label) {
global $assoc_actions, $item_rows, $config;
@@ -1479,6 +1544,18 @@ function hosts($header_label) {
form_end();
}
/**
* Renders the notification list's \"Thresholds\" tab: validates/stores
* this tab's filter request variables, displays the threshold filter
* form, then displays a filtered, sorted, paginated table of
* thresholds with their association status to this list and a
* bulk-actions dropdown to associate/disassociate them.
*
* @param string $header_label The \"[edit: name]\"/\"[new]\" header label
* suffix to display in the box title.
*
* @return void
*/
function tholds($header_label) {
global $item_rows, $assoc_actions, $config;
@@ -1846,6 +1923,18 @@ function tholds($header_label) {
form_end();
}
/**
* Renders the notification list's \"Templates\" tab: validates/stores
* this tab's filter request variables, displays the template filter
* form, then displays a filtered, sorted, paginated table of threshold
* templates with their association status to this list and a
* bulk-actions dropdown to associate/disassociate them.
*
* @param string $header_label The \"[edit: name]\"/\"[new]\" header label
* suffix to display in the box title.
*
* @return void
*/
function templates($header_label) {
global $config, $item_rows, $assoc_actions;
@@ -2076,6 +2165,14 @@ function templates($header_label) {
form_end();
}
/**
* Validates and stores the threshold-templates-tab filter request
* variables (rows, page, filter text, sort column/direction,
* associated flag) into the session for the notification list's
* Templates tab.
*
* @return void
*/
function thold_template_request_validation() {
// ================= input validation and session storage =================
$filters = [
@@ -2114,6 +2211,13 @@ function thold_template_request_validation() {
// ================= input validation =================
}
/**
* Validates and stores the thresholds-tab filter request variables
* (rows, page, filter text, sort column/direction, associated flag)
* into the session for the notification list's Thresholds tab.
*
* @return void
*/
function thold_request_validation() {
// ================= input validation and session storage =================
$filters = [
@@ -2166,6 +2270,20 @@ function thold_request_validation() {
// ================= input validation =================
}
/**
* Renders the main notification lists list page: validates/stores this
* view's filter request variables, then displays a filtered, sorted,
* paginated table of notification lists with a bulk-actions dropdown.
* Called from this script's main request-dispatch switch as the
* default view.
*
* @return void
*
* @global array $actions Map of drp_action value => action label,
* used for the bulk-actions dropdown.
* @global array $item_rows Default number of rows per page from Cacti
* settings.
*/
function lists() {
global $actions, $item_rows;
+31
View File
@@ -97,6 +97,19 @@ switch (get_request_var('action')) {
break;
}
/**
* Handles the bulk-action confirmation page/submission for the
* notification queue list (delete): on confirmed submission with
* selected_items set, deletes the selected notification_queue rows; on
* first display, renders a confirmation box listing the selected
* notifications. Called from this script's main request-dispatch
* switch when action=actions.
*
* @return void
*
* @global array $actions Map of drp_action value => action label, used
* for the bulk-actions confirmation display.
*/
function form_actions() {
global $actions;
@@ -181,6 +194,24 @@ function form_actions() {
bottom_footer();
}
/**
* Renders the main notification queue list page: validates/stores this
* view's filter request variables, displays the filter form, then
* displays a filtered, sorted, paginated table of pending/sent
* notifications with a bulk-actions dropdown. Called from this
* script's main request-dispatch switch as the default view.
*
* @return void
*
* @global array $actions Map of drp_action value =>
* action label, used for the
* bulk-actions dropdown.
* @global array $item_rows Default number of rows per
* page from Cacti settings.
* @global array $thold_notification_topics Notification topic option
* list used by the filter
* form.
*/
function notify_queue() {
global $actions, $item_rows, $thold_notification_topics;
+13
View File
@@ -102,6 +102,19 @@ 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;
+492
View File
@@ -22,6 +22,28 @@
+-------------------------------------------------------------------------+
*/
/**
* Registers all of this plugin's hooks (settings, breadcrumbs, poller
* output/bottom, device/data-source/graph management actions, graph
* buttons, SNMP agent cache, clog regex, and more) and permission
* realms with Cacti, then creates/updates its database schema and SNMP
* agent cache. Cacti plugin API entry point invoked when the plugin is
* installed or re-registered during an upgrade. A no-op returning false
* on Cacti versions older than 1.2.
*
* @param bool $upgrade Whether this call is for an in-place upgrade of
* an already-installed plugin (true) rather than
* a fresh install (false, default); affects
* whether the database is upgraded vs. freshly
* created.
*
* @return bool|void False when the Cacti version is too old; otherwise
* no explicit return value.
*
* @global array $config Cacti global configuration array; used to
* check the Cacti version and locate the database
* include file.
*/
function plugin_thold_install($upgrade = false) {
global $config;
@@ -126,6 +148,13 @@ function plugin_thold_install($upgrade = false) {
}
}
/**
* Removes this plugin's SNMP agent cache entries and all of its
* settings table rows. Cacti plugin API entry point invoked when the
* plugin is uninstalled.
*
* @return void
*/
function plugin_thold_uninstall() {
// Do any extra Uninstall stuff here
thold_snmpagent_cache_uninstall();
@@ -135,6 +164,13 @@ function plugin_thold_uninstall() {
WHERE name LIKE "%thold%"');
}
/**
* Ensures the plugin's configuration/schema is up to date by delegating
* to plugin_thold_upgrade(). Cacti plugin API entry point invoked on
* relevant page loads to catch pending upgrades.
*
* @return bool Always true.
*/
function plugin_thold_check_config() {
// Here we will check to ensure everything is configured
plugin_thold_upgrade();
@@ -142,6 +178,20 @@ function plugin_thold_check_config() {
return true;
}
/**
* Detects a version mismatch between the running plugin code and the
* version recorded in plugin_config, and when found (and only on a
* small set of pages, to limit overhead), re-runs
* plugin_thold_install() in upgrade mode to re-register hooks and
* upgrade the database schema.
*
* @return bool True (whether or not an upgrade was actually needed);
* false only when called from a page that doesn't need
* this check.
*
* @global array $config Cacti global configuration array (declared but
* not used directly here).
*/
function plugin_thold_upgrade() {
// Here we will upgrade to the newest version
global $config;
@@ -166,6 +216,17 @@ function plugin_thold_upgrade() {
return true;
}
/**
* Reads this plugin's version and metadata from its INFO file. Cacti
* plugin API entry point used throughout the plugin to display version
* information.
*
* @return array The parsed INFO file's 'info' section (name, author,
* homepage, version, etc.).
*
* @global array $config Cacti global configuration array; used to
* locate the plugin's INFO file.
*/
function plugin_thold_version() {
global $config;
$info = parse_ini_file($config['base_path'] . '/plugins/thold/INFO', true);
@@ -173,10 +234,24 @@ function plugin_thold_version() {
return $info['info'];
}
/**
* Checks whether this plugin's dependencies are satisfied. Cacti
* plugin API hook point; currently always reports dependencies as
* satisfied.
*
* @return bool Always true.
*/
function thold_check_dependencies() {
return true;
}
/**
* Checks whether the database session is running in MySQL/MariaDB
* STRICT SQL mode, which this plugin (or its schema) is incompatible
* with.
*
* @return bool False if STRICT mode is active, true otherwise.
*/
function plugin_thold_check_strict() {
$mode = db_fetch_cell('select @@global.sql_mode', false);
@@ -187,6 +262,20 @@ function plugin_thold_check_strict() {
return true;
}
/**
* Renders this plugin's graph-page action buttons (toggle threshold
* VRULE display, create-threshold link) for a graph, shown only to
* users with the relevant view/edit permissions. Registered as the
* 'graph_buttons' and 'graph_buttons_thumbnails' Cacti hooks.
*
* @param array $data The graph button hook payload; $data[1] contains
* the graph's local_graph_id and rra selection.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* build the Create Threshold link's URL.
*/
function thold_graph_button($data) {
global $config;
@@ -272,12 +361,43 @@ function thold_graph_button($data) {
}
}
/**
* Splits a string on any of several delimiter characters at once, by
* first collapsing all given delimiters down to the first one and then
* exploding on it.
*
* @param array $delimiters The list of delimiter characters/strings
* to split on (the first entry is used as
* the unified delimiter).
* @param string $string The string to split.
*
* @return array|false The resulting array of substrings, or false on
* failure.
*/
function thold_multiexplode($delimiters, $string) {
$ready = str_replace($delimiters, $delimiters[0], $string);
return @explode($delimiters[0], $ready);
}
/**
* Substitutes this plugin's `|thold:hi:<ds>|` / `|thold:low:<ds>|`
* graph text-item placeholder variables with each referenced data
* source's current threshold hi/low values, by mapping the graph's RRD
* definitions' data source names to their underlying local_data_id and
* looking up the matching threshold. Registered as the
* 'rrd_graph_graph_options' Cacti hook.
*
* @param array $g The graph rendering options array, including
* 'graph_defs' and 'txt_graph_items'.
*
* @return array The graph rendering options array with thold
* placeholder variables substituted in
* 'txt_graph_items'.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
*/
function thold_rrd_graph_graph_options($g) {
global $config;
@@ -675,10 +795,34 @@ function thold_rrd_graph_graph_options($g) {
return $g;
}
/**
* Prepares a string value for safe embedding in an RRDtool command
* line argument by shell-escaping it, then RRDtool-escaping it, then
* wrapping it in single quotes.
*
* @param string $string The raw string value to prepare.
*
* @return string The quoted, escaped string ready for RRDtool command
* construction.
*/
function thold_prep_rrd_string($string) {
return '\'' . trim(cacti_escapeshellarg(rrdtool_escape_string($string)), "'") . '\'';
}
/**
* Executes the "Apply Thresholds" bulk device action: auto-creates
* thresholds for each selected device using its device template's
* associated threshold templates. Registered as the
* 'device_action_execute' Cacti hook; a no-op passthrough for any
* other action.
*
* @param string $action The bulk action identifier being executed.
*
* @return string The unmodified $action, for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
*/
function thold_device_action_execute($action) {
global $config;
@@ -699,6 +843,19 @@ function thold_device_action_execute($action) {
return $action;
}
/**
* Auto-creates thresholds for a newly created device when the global
* thold_autocreate setting is enabled. Registered as the
* 'api_device_new' Cacti hook.
*
* @param array $save The newly created device's saved field data,
* including its 'id'.
*
* @return array The unmodified $save array, for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
*/
function thold_api_device_new($save) {
global $config;
@@ -713,6 +870,22 @@ function thold_api_device_new($save) {
return $save;
}
/**
* Renders the confirmation box listing the devices selected for the
* "Apply Thresholds" bulk device action. Registered as the
* 'device_action_prepare' Cacti hook; a no-op passthrough for any
* other action.
*
* @param array $save The bulk-action form submission data, including
* 'drp_action' and a pre-built 'host_list' HTML
* fragment.
*
* @return array The unmodified $save array, for hook chaining.
*
* @global array $host_list Reserved/declared for parity with other
* functions in this file; not used directly
* here.
*/
function thold_device_action_prepare($save) {
global $host_list;
@@ -730,12 +903,38 @@ function thold_device_action_prepare($save) {
return $save;
}
/**
* Adds the "Apply Thresholds" entry to the device management bulk-
* actions dropdown. Registered as the 'device_action_array' Cacti
* hook.
*
* @param array $device_action_array The existing bulk-action label
* map, keyed by action id.
*
* @return array The action map with this plugin's entry added.
*/
function thold_device_action_array($device_action_array) {
$device_action_array['thold'] = 'Apply Thresholds';
return $device_action_array;
}
/**
* Reacts to a device being saved: when the device's disabled state
* changed, triggers this plugin's device up/down/enable/disable
* notification handling; and (elsewhere in this function, per the
* broader save flow) keeps this plugin's per-device data in sync with
* the saved device fields. Registered as the 'api_device_save' Cacti
* hook.
*
* @param array $save The device's saved field data, including 'id' and
* 'disabled'.
*
* @return array The unmodified $save array, for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
*/
function thold_api_device_save($save) {
global $config;
@@ -787,6 +986,20 @@ function thold_api_device_save($save) {
return $save;
}
/**
* Turns a data source's name cell in the Console data sources table
* into a link to either edit its existing threshold, or (when no graph
* exists yet for it) create a new one, when applicable. Registered as
* the 'data_sources_table' Cacti hook.
*
* @param array $ds The data source row being rendered.
*
* @return array The $ds row, with 'data_template_name' replaced by a
* linked HTML fragment when applicable.
*
* @global array $config Cacti global configuration array (declared but
* not used directly here).
*/
function thold_data_sources_table($ds) {
global $config;
@@ -824,12 +1037,35 @@ function thold_data_sources_table($ds) {
return $ds;
}
/**
* Prints an "Auto-create Thresholds" link on the "new graphs" page for
* the current host. Registered as the 'graphs_new_top_links' Cacti
* hook.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* build the link URL.
*/
function thold_graphs_new() {
global $config;
print '<span class="linkMarker">*</span><a class="autocreate linkEditMain" href="' . html_escape($config['url_path'] . 'plugins/thold/thold.php?action=autocreate&host_id=' . get_filter_request_var('host_id')) . '">' . __('Auto-create Thresholds', 'thold') . '</a><br>';
}
/**
* Saves (or clears) a user's notification email address into this
* plugin's contacts table whenever a Cacti user account is saved with
* an email/email_address field. Registered as the
* 'user_admin_setup_sql_save' Cacti hook; a no-op passthrough when the
* user save already failed validation.
*
* @param array $save The user account's saved field data, including
* 'id'.
*
* @return array The unmodified (or id-populated) $save array, for hook
* chaining.
*/
function thold_user_admin_setup_sql_save($save) {
if (is_error_message()) {
return $save;
@@ -864,6 +1100,23 @@ function thold_user_admin_setup_sql_save($save) {
return $save;
}
/**
* Executes the "Create Threshold from Data Source" bulk data source
* action: creates thresholds for each selected data source using the
* threshold template chosen on the confirmation page. Registered as
* the 'data_source_action_execute' Cacti hook; a no-op passthrough for
* any other action.
*
* @param string $action The bulk action identifier being executed.
*
* @return string The unmodified $action, for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
* @global array $form_array Reserved/declared for parity with other
* functions in this file; not used directly
* here.
*/
function thold_data_source_action_execute($action) {
global $config, $form_array;
@@ -923,6 +1176,26 @@ function thold_data_source_action_execute($action) {
return $action;
}
/**
* Renders the confirmation page for the "Create Threshold from
* Template" bulk data source action, listing which selected data
* sources have at least one applicable threshold template (and
* offering a template selection), while filtering out any that don't.
* Registered as the 'data_source_action_prepare' Cacti hook; a no-op
* passthrough for any other action.
*
* @param array $save The bulk-action form submission data, including
* 'drp_action' and 'ds_array' (selected data source
* ids).
*
* @return array|void The unmodified $save array (for hook chaining)
* when the action isn't 'plugin_thold_create';
* otherwise this renders the confirmation UI
* directly and returns nothing.
*
* @global array $config Cacti global configuration array (declared but
* not used directly here).
*/
function thold_data_source_action_prepare($save) {
global $config;
@@ -1017,12 +1290,40 @@ function thold_data_source_action_prepare($save) {
}
}
/**
* Adds the "Create Threshold from Template" entry to the data source
* management bulk-actions dropdown. Registered as the
* 'data_source_action_array' Cacti hook.
*
* @param array $action The existing bulk-action label map, keyed by
* action id.
*
* @return array The action map with this plugin's entry added.
*/
function thold_data_source_action_array($action) {
$action['plugin_thold_create'] = __('Create Threshold from Template', 'thold');
return $action;
}
/**
* Executes the "Create Threshold from Template" bulk graph action:
* applies the selected threshold template to each selected graph's
* matching data source(s), creating a new threshold for each one that
* doesn't already have one from that template. Registered as the
* 'graphs_action_execute' Cacti hook; a no-op passthrough for any
* other action.
*
* @param string $action The bulk action identifier being executed.
*
* @return string The unmodified $action, for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
* @global array $form_array Reserved/declared for parity with other
* functions in this file; not used directly
* here.
*/
function thold_graphs_action_execute($action) {
global $config, $form_array;
@@ -1082,6 +1383,25 @@ function thold_graphs_action_execute($action) {
return $action;
}
/**
* Renders the confirmation page for the "Create Threshold from
* Template" bulk graph action, listing which selected graphs have at
* least one applicable threshold template (and offering a template
* selection), while filtering out any that don't. Registered as the
* 'graphs_action_prepare' Cacti hook; a no-op passthrough for any
* other action.
*
* @param array $save The bulk-action form submission data, including
* 'drp_action'.
*
* @return array|void The unmodified $save array (for hook chaining)
* when the action isn't 'plugin_thold_create';
* otherwise this renders the confirmation UI
* directly and returns nothing.
*
* @global array $config Cacti global configuration array (declared but
* not used directly here).
*/
function thold_graphs_action_prepare($save) {
global $config;
@@ -1181,12 +1501,30 @@ function thold_graphs_action_prepare($save) {
}
}
/**
* Adds the "Create Threshold from Template" entry to the graph
* management bulk-actions dropdown. Registered as the
* 'graphs_action_array' Cacti hook.
*
* @param array $action The existing bulk-action label map, keyed by
* action id.
*
* @return array The action map with this plugin's entry added.
*/
function thold_graphs_action_array($action) {
$action['plugin_thold_create'] = __('Create Threshold from Template', 'thold');
return $action;
}
/**
* Emits the JavaScript that shows/hides the notification-list dropdown
* on the device edit form based on the selected "Threshold Up/Down
* Email Notification" mode. Registered as the 'host_edit_bottom' and
* 'device_change_javascript' Cacti hooks.
*
* @return void
*/
function thold_host_edit_bottom() {
?>
<script type='text/javascript'>
@@ -1204,6 +1542,18 @@ function thold_host_edit_bottom() {
<?php
}
/**
* Installs this plugin's CACTI-THOLD-MIB definitions into Cacti's SNMP
* agent cache (SNMP Notification Receiver / SNMP Agent support),
* when the SNMP agent's MibCache class is available. Registered as the
* 'snmpagent_cache_install' Cacti hook, and invoked during plugin
* installation.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate the MIB definition file.
*/
function thold_snmpagent_cache_install() {
global $config;
@@ -1213,6 +1563,16 @@ function thold_snmpagent_cache_install() {
}
}
/**
* Removes this plugin's CACTI-THOLD-MIB definitions from Cacti's SNMP
* agent cache, when the SNMP agent's MibCache class is available.
* Invoked during plugin uninstallation.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate the MIB definition file.
*/
function thold_snmpagent_cache_uninstall() {
global $config;
@@ -1222,6 +1582,18 @@ function thold_snmpagent_cache_uninstall() {
}
}
/**
* Emits this plugin's theme-specific stylesheet link (when one exists)
* and a JavaScript handler that rebinds the threshold-VRULE toggle
* link's click behavior to an AJAX partial-page refresh after each AJAX
* completion. Registered as the 'page_head' Cacti hook.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* check for a theme-specific stylesheet and build
* asset URLs.
*/
function thold_page_head() {
global $config;
@@ -1252,6 +1624,15 @@ function thold_page_head() {
<?php
}
/**
* Renders the "Associated Threshold Templates" box on the device edit
* page, listing threshold templates already associated with the
* device (with their per-device threshold existence status and a
* remove link) and offering a dropdown to associate an additional
* template. Registered as the 'device_edit_pre_bottom' Cacti hook.
*
* @return void
*/
function thold_device_edit_pre_bottom() {
html_start_box(__('Associated Threshold Templates', 'thold'), '100%', false, '3', 'center', '');
@@ -1353,6 +1734,16 @@ function thold_device_edit_pre_bottom() {
html_end_box();
}
/**
* Renders the confirmation page for removing a threshold template's
* association with a device (action=item_remove_tt_confirm), or
* otherwise defers to the standard device edit page (this hook is
* registered on host.php, whose own action-dispatch relies on this
* function to intercept this plugin-specific action). Registered as
* the 'device_top' Cacti hook.
*
* @return void
*/
function thold_device_top() {
if (get_request_var('action') == 'item_remove_tt_confirm') {
// ================= input validation =================
@@ -1443,6 +1834,15 @@ function thold_device_top() {
}
}
/**
* Renders the "Associated Threshold Templates" box on the device
* template edit page, listing threshold templates already associated
* with the device template (with a remove link) and offering a
* dropdown to associate an additional template. Registered as the
* 'device_template_edit' Cacti hook.
*
* @return void
*/
function thold_device_template_edit() {
html_start_box(__('Associated Threshold Templates', 'thold'), '100%', false, '3', 'center', '');
@@ -1523,6 +1923,13 @@ function thold_device_template_edit() {
html_end_box();
}
/**
* Renders the confirmation page for removing a threshold template's
* association with a device template (action=item_remove_tt_confirm).
* Registered as the 'device_template_top' Cacti hook.
*
* @return void
*/
function thold_device_template_top() {
if (get_request_var('action') == 'item_remove_tt_confirm') {
// ================= input validation =================
@@ -1613,6 +2020,17 @@ function thold_device_template_top() {
}
}
/**
* Propagates a device template's associated threshold templates to a
* device when its device template is changed, associating the device
* with every threshold template linked to the newly selected device
* template. Registered as the 'device_template_change' Cacti hook.
*
* @param array $data The device template change payload, including
* 'device_id' and 'device_template_id'.
*
* @return array The unmodified $data array, for hook chaining.
*/
function thold_device_template_change($data) {
$device_id = $data['device_id'];
$device_template_id = $data['device_template_id'];
@@ -1632,12 +2050,35 @@ function thold_device_template_change($data) {
return $data;
}
/**
* Auto-creates thresholds for a device using its device template's
* associated threshold templates. Registered as the
* 'device_threshold_autocreate' Cacti hook.
*
* @param int $host_id The device id to auto-create thresholds for.
*
* @return int The unmodified $host_id, for hook chaining.
*/
function thold_device_autocreate($host_id) {
autocreate($host_id);
return $host_id;
}
/**
* Auto-creates a threshold for a newly created graph using its host's
* associated threshold templates, when the global thold_autocreate
* setting is enabled. Registered as the
* 'create_complete_graph_from_template' Cacti hook.
*
* @param array $save The newly created graph's saved field data,
* including its 'id'.
*
* @return array The unmodified $save array, for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
*/
function thold_create_graph_thold($save) {
global $config;
@@ -1657,6 +2098,19 @@ function thold_create_graph_thold($save) {
return $save;
}
/**
* Deletes any thresholds associated with data sources that are being
* removed, logging each removal for audit purposes. Registered as the
* 'data_source_remove' Cacti hook.
*
* @param array $data_ids The local_data_id values of the data sources
* being removed.
*
* @return array The unmodified $data_ids array, for hook chaining.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include.
*/
function thold_data_source_remove($data_ids) {
global $config;
@@ -1679,12 +2133,43 @@ function thold_data_source_remove($data_ids) {
return $data_ids;
}
/**
* Registers a "TH[id, id, ...]" pattern with Cacti's log viewer (clog)
* regex hyperlinking system, so that threshold id references embedded
* in log messages are rendered as links via
* thold_clog_regex_threshold(). Registered as the 'clog_regex_array'
* Cacti hook.
*
* @param array $regex_array The existing list of clog hyperlink regex
* definitions.
*
* @return array The regex definitions list with this plugin's pattern
* added.
*/
function thold_clog_regex_array($regex_array) {
$regex_array[] = ['name' => 'TH', 'regex' => '( TH\[)([, \d]+)(\])', 'func' => 'thold_clog_regex_threshold'];
return $regex_array;
}
/**
* Replaces a "TH[id, id, ...]" log-message match with linked threshold
* descriptions (falling back to the raw threshold id when no matching
* threshold is found), used as the clog regex callback registered by
* thold_clog_regex_array().
*
* @param array $matches The regex match groups: [0] the full match,
* [1] the opening " TH[" text, [2] the
* comma-separated threshold ids, [3] the closing
* "]" text.
*
* @return string The rendered HTML with each threshold id replaced by a
* link to its edit page.
*
* @global array $config Cacti global configuration array; used to
* locate the library file to include and build
* edit link URLs.
*/
function thold_clog_regex_threshold($matches) {
global $config;
@@ -1723,6 +2208,13 @@ function thold_clog_regex_threshold($matches) {
return $result;
}
/**
* Emits the JavaScript that initializes the multiselect widget for the
* "Pause Notifications" settings field on the Console settings page.
* Registered as the 'settings_bottom' Cacti hook.
*
* @return void
*/
function thold_settings_bottom() {
?>
<script type='text/javascript'>
+27
View File
@@ -168,6 +168,33 @@ $unmeasured_allowlist = [
// isolated unit process. Its persistence/evaluation logic lives in the
// covered thold_daemon_persist_sample()/thold_check_threshold() helpers.
'thold_process.php',
// CLI entry points: include cli_check.php / chdir and execute at the
// top level, so they cannot be require()'d into the isolated unit process.
'cli_import.php',
'cli_thresholds.php',
// Poller entry point: bootstraps the poller environment and executes
// at the top level, so it cannot be require()'d into the isolated unit
// process.
'poller_thold.php',
// Authenticated web entry points: chdir + include(auth.php) and several
// lib/* includes at the top level, so they cannot be require()'d into
// the isolated unit process.
'thold.php',
'thold_graph.php',
'thold_templates.php',
'notify_lists.php',
// Daemon entry point, same category as thold_process.php above (pcntl
// signal handling at the top level).
'thold_daemon.php',
// Settings-page and header-tab-bar hook callbacks: only meaningful when
// invoked by Cacti's plugin hook dispatcher inside a live page render,
// with the real $settings/$config arrays and database populated.
'includes/settings.php',
'includes/tab.php',
// Web-page action handlers (thold_wizard() et al.) that read $_REQUEST
// and read/write the Cacti database directly; only meaningful inside a
// live authenticated request, not the isolated unit process.
'thold_webapi.php',
];
$unmeasured = array_values(array_diff(array_keys($changed), array_keys($measured)));
$unexpected_unmeasured = array_values(array_diff($unmeasured, $unmeasured_allowlist));
+84
View File
@@ -153,6 +153,20 @@ switch(get_request_var('action')) {
break;
}
/**
* Dispatches the "add threshold(s)" flow for a graph: routes between
* the threshold-template wizard (thold_wizard()), applying a selected
* template to create thresholds (thold_add_graphs_action_execute()),
* or the template-selection confirmation page
* (thold_add_graphs_action_prepare()), depending on which wizard step
* request variables are present. Called from this script's main
* request-dispatch switch when action=add.
*
* @return void
*
* @global array $config Cacti global configuration array (declared but
* not used directly here).
*/
function thold_add() {
global $config;
@@ -206,6 +220,26 @@ function thold_add() {
}
}
/**
* Handles the bulk-action confirmation page/submission for the
* thresholds list (delete, enable, disable, and other batch
* operations), restricting each action to thresholds on graphs the
* current user is permitted to manage, logging each change, and
* updating the "last change" timestamps used for change-detection
* elsewhere in the plugin. Called from this script's main
* request-dispatch switch when action=actions.
*
* @return void
*
* @global array $config Cacti global configuration array
* (declared but not used directly here).
* @global int $host_id Reserved/declared for parity with
* other functions in this file; not used
* directly here.
* @global array $thold_actions Map of drp_action value => action
* label, used for the bulk-actions
* confirmation display.
*/
function do_actions() {
global $config, $host_id, $thold_actions;
@@ -577,6 +611,34 @@ function thold_request_validation() {
// ================= input validation =================
}
/**
* Renders the main thresholds list page: validates/stores this view's
* filter request variables, then displays a filtered, sorted,
* paginated table of thresholds (by host, data/threshold template,
* site, state, and name filter) with a bulk-actions dropdown. Called
* from this script's main request-dispatch switch as the default view.
*
* @return void
*
* @global array $thold_actions Map of drp_action value => action label,
* used for the bulk-actions dropdown.
* @global array $thold_states Threshold state option list used by the
* filter form.
* @global array $config Cacti global configuration array; used
* to locate library files to include.
* @global int $host_id Reserved/declared for parity with other
* functions in this file; not used
* directly here.
* @global array $timearray Map of RRD step-normalized range values
* to display labels, used to render each
* baseline threshold's reference time
* range.
* @global array $thold_types Reserved/declared for parity with other
* functions in this file; not used
* directly here.
* @global array $item_rows Default number of rows per page from
* Cacti settings.
*/
function list_tholds() {
global $thold_actions, $thold_states, $config, $host_id, $timearray, $thold_types, $item_rows;
@@ -1109,6 +1171,28 @@ function list_tholds() {
bottom_footer();
}
/**
* Renders the add/edit form for a single threshold (thresholds,
* expressions, notification/severity settings, syslog options,
* graph/time-span preview), loading the existing record when editing
* (force-upgrading the schema first if it's missing an expected
* column) or seeding a new record's identifying fields from the
* request when adding a threshold for a specific graph/data source.
* Called from this script's main request-dispatch switch when
* action=edit.
*
* @return void
*
* @global array $config Cacti global configuration
* array; used to locate library
* files to include.
* @global array $graph_timespans Time span option list used by
* the graph preview.
* @global array $syslog_facil_array Syslog facility option list
* used by syslog-related fields.
* @global array $syslog_priority_array Syslog priority option list
* used by syslog-related fields.
*/
function thold_edit() {
global $config, $graph_timespans, $syslog_facil_array, $syslog_priority_array;
+86 -1
View File
@@ -253,12 +253,25 @@ while (true) {
}
}
/**
* Truncates the plugin_thold_daemon_data table, clearing all queued
* per-thread threshold work items.
*
* @return void
*/
function thold_truncate_daemon_data() {
thold_daemon_debug('Truncating historical Threshold Daemon Data');
db_execute('TRUNCATE TABLE plugin_thold_daemon_data');
}
/**
* Checks whether a Cacti poller run is currently in progress (has an
* unfinished poller_time entry).
*
* @return int The number of poller_time rows with no end_time set (0
* if none, meaning no poller run is currently active).
*/
function thold_poller_running() {
return db_fetch_cell('SELECT COUNT(*) FROM poller_time WHERE end_time = "0000-00-00"');
}
@@ -296,6 +309,19 @@ function sig_handler($signo) {
}
}
/**
* Launches a single Thold worker process (thold_process.php) for the
* given thread number as a detached background process.
*
* @param int $thread The worker thread number to launch.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* build the worker script's command line.
* @global bool $debug Whether debug output is enabled; passed
* through to the worker via --debug.
*/
function thold_launch_worker($thread) {
global $config, $debug;
@@ -312,6 +338,24 @@ function thold_launch_worker($thread) {
exec_background($path_php, $process);
}
/**
* Monitors the registered Thold worker child processes, detecting and
* cleaning up crashed processes, and launching new worker processes
* (up to the configured concurrency) to replace missing ones or reach
* the desired total, so that exactly $new_processes workers stay
* running.
*
* @param array $processes The currently known worker process
* registrations (unused directly; current
* state is re-fetched from the database).
* @param int $new_processes The desired total number of concurrent
* worker processes/threads.
*
* @return void
*
* @global array $config Cacti global configuration array; used when
* launching new worker processes.
*/
function thold_heartbeat_processes($processes, $new_processes) {
global $config;
@@ -394,6 +438,23 @@ function thold_heartbeat_processes($processes, $new_processes) {
}
}
/**
* (Re)assigns each threshold's thread_id so that thresholds are evenly
* distributed across the configured number of worker threads, grouped
* by host (so all thresholds for a given host are always processed by
* the same thread); only assigns thread ids to thresholds that
* currently have none (thread_id = 0), unless a full rebalance is
* forced.
*
* @param int $processes The current/target number of worker
* threads/processes to distribute across.
* @param bool $truncate Whether to force a full rebalance by
* resetting all thread assignments first, even
* if the thread count appears unchanged (default
* false).
*
* @return void
*/
function thold_prime_distribution($processes, $truncate = false) {
thold_daemon_debug('Rebalancing Thread Allocation by Device');
@@ -442,6 +503,16 @@ function thold_prime_distribution($processes, $truncate = false) {
thold_daemon_debug('Thread Rebalancing Allocation by Device Completed');
}
/**
* Prints a timestamped debug message directly to stdout when global
* debug mode or the thold_daemon_debug setting is enabled.
*
* @param string $string The message to print.
*
* @return void
*
* @global bool $debug Whether debug output is enabled.
*/
function thold_daemon_debug($string) {
global $debug;
@@ -455,6 +526,15 @@ function thold_daemon_debug($string) {
}
}
/**
* Prints this script's name, version, and copyright banner to stdout.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate setup.php when plugin_thold_version()
* isn't already loaded.
*/
function display_version() {
global $config;
@@ -466,7 +546,12 @@ function display_version() {
print 'Threshold Daemon, Version ' . $info['version'] . ', ' . COPYRIGHT_YEARS . PHP_EOL;
}
// display_help - displays the usage of the function
/**
* Prints this script's version banner followed by its command-line
* usage instructions to stdout.
*
* @return void
*/
function display_help() {
display_version();
+1215 -25
View File
File diff suppressed because it is too large. Load diff
+141 -1
View File
@@ -119,6 +119,17 @@ switch(get_request_var('action')) {
// Clear the Nav Cache, so that it doesn't know we came from Thold
$_SESSION['sess_nav_level_cache'] = [];
/**
* Renders the search/state/host/site/template filter form controls for
* the thresholds list view.
*
* @return void
*
* @global array $item_rows Rows-per-page option list used to populate
* the rows dropdown.
* @global array $config Cacti global configuration array (declared
* but not used directly here).
*/
function form_thold_filter() {
global $item_rows, $config;
@@ -320,6 +331,28 @@ function form_thold_filter() {
<?php
}
/**
* Renders the main thresholds list page (the plugin's primary
* dashboard view): validates/stores this view's filter request
* variables, displays the threshold filter form, then displays a
* filtered, sorted, paginated table of thresholds with a bulk-actions
* dropdown and status legend. Called from this script's main
* request-dispatch switch as the default 'thold' view.
*
* @return void
*
* @global array $config Cacti global configuration array.
* @global array $device_actions Map of drp_action value => action
* label, used for the bulk-actions
* dropdown.
* @global array $item_rows Default number of rows per page from
* Cacti settings.
* @global array $thold_classes Reserved/declared for parity with
* other functions in this file; not used
* directly here.
* @global array $thold_states Threshold state option list used by
* the filter form.
*/
function tholds() {
global $config, $device_actions, $item_rows, $thold_classes, $thold_states;
@@ -806,7 +839,21 @@ function tholds() {
// thold_display_rusage();
}
// form_host_status_row_color - returns a color to use based upon the host's current status
/**
* Prints the opening `<tr>` tag for a device-status-list row, using a
* CSS class derived from the host's disabled flag, current status, and
* (when a per-host failure-count override is set) whether its
* consecutive down-event count has reached that threshold.
*
* @param array &$host The host record to determine the row color/class
* for.
*
* @return string The CSS class name used for the row.
*
* @global array $thold_host_states Map of status/state key => display
* info (including 'class') used to
* determine the row's CSS class.
*/
function form_host_status_row_color(&$host) {
global $thold_host_states;
@@ -834,6 +881,17 @@ function form_host_status_row_color(&$host) {
return $class;
}
/**
* Determines a human-readable status label for a host (Disabled, Down,
* Recovering, Up, Error, or Unknown), applying the same per-host
* failure-count override logic as form_host_status_row_color() but
* without any HTML/color output.
*
* @param array &$host The host record to determine the status label
* for.
*
* @return string The human-readable, translated status label.
*/
function get_uncolored_device_status(&$host) {
$disabled = $host['disabled'];
$status = $host['status'];
@@ -872,6 +930,22 @@ function get_uncolored_device_status(&$host) {
}
}
/**
* Renders the device status list view: validates/stores this view's
* filter request variables, displays the host filter form, then
* displays a filtered, sorted, paginated table of hosts with their
* current up/down/recovering status. Called from this script's main
* request-dispatch switch when action=hoststat.
*
* @return void
*
* @global array $config Cacti global configuration array.
* @global array $device_actions Map of drp_action value => action
* label, used for the bulk-actions
* dropdown.
* @global array $item_rows Default number of rows per page from
* Cacti settings.
*/
function hosts() {
global $config, $device_actions, $item_rows;
@@ -1151,6 +1225,17 @@ function hosts() {
// thold_display_rusage();
}
/**
* Renders the search/site filter form controls for the device status
* list view.
*
* @return void
*
* @global array $item_rows Rows-per-page option list used to populate
* the rows dropdown.
* @global array $config Cacti global configuration array (declared
* but not used directly here).
*/
function form_host_filter() {
global $item_rows, $config;
@@ -1294,6 +1379,14 @@ function form_host_filter() {
<?php
}
/**
* Validates and stores this view's filter request variables (rows,
* page, filter text, sort column/direction, threshold id, threshold
* template id, host id, site id, status) into the session for the
* threshold log list view.
*
* @return void
*/
function thold_validate_log_vars() {
// ================= input validation and session storage =================
$filters = [
@@ -1352,6 +1445,13 @@ function thold_validate_log_vars() {
// ================= input validation =================
}
/**
* Exports the current filtered threshold log entries (up to 100000
* rows) as a downloaded CSV file. Called from this script's main
* request-dispatch switch when action=logexport.
*
* @return void
*/
function thold_export_log() {
$sql_where = '';
@@ -1420,6 +1520,32 @@ function thold_export_log() {
}
}
/**
* Renders the main threshold log list page: validates/stores this
* view's filter request variables, displays the log filter form, then
* displays a filtered, sorted, paginated table of threshold log
* entries. Called from this script's main request-dispatch switch when
* action=log.
*
* @return void
*
* @global array $config Cacti global configuration
* array.
* @global array $item_rows Default number of rows per page
* from Cacti settings.
* @global array $thold_log_states Log status option list used by
* the filter form.
* @global array $thold_status Reserved/declared for parity with
* other functions in this file; not
* used directly here.
* @global array $thold_types Map of log entry type id => label,
* used to render each log row's
* type column ('Acknowledgment'
* added here for type 99).
* @global int $thold_log_retention Reserved/declared for parity with
* other functions in this file; not
* used directly here.
*/
function thold_show_log() {
global $config, $item_rows, $thold_log_states, $thold_status, $thold_types, $thold_log_retention;
@@ -1593,6 +1719,20 @@ function thold_show_log() {
log_legend();
}
/**
* Renders the search/site/status/host/template filter form controls for
* the threshold log list view.
*
* @return void
*
* @global array $item_rows Rows-per-page option list used to
* populate the rows dropdown.
* @global array $thold_log_states Log status option list used to
* populate the status dropdown.
* @global array $config Cacti global configuration array
* (declared but not used directly
* here).
*/
function form_thold_log_filter() {
global $item_rows, $thold_log_states, $config;
+38 -1
View File
@@ -136,6 +136,19 @@ function sig_handler($signo) {
}
}
/**
* Logs a debug message from the notification daemon to the Cacti log,
* only when global debug mode or the thold_daemon_debug setting is
* enabled.
*
* @param string $message The message to log.
* @param mixed $thread The worker thread identifier, passed through
* to thold_cacti_log() for log-line context.
*
* @return void
*
* @global bool $debug Whether debug output is enabled.
*/
function thold_daemon_debug($message, $thread) {
global $debug;
@@ -146,6 +159,16 @@ function thold_daemon_debug($message, $thread) {
}
}
/**
* Prints a timestamped debug message directly to stdout when global
* debug mode is enabled.
*
* @param string $string The message to print.
*
* @return void
*
* @global bool $debug Whether debug output is enabled.
*/
function thold_cli_debug($string) {
global $debug;
@@ -156,6 +179,15 @@ function thold_cli_debug($string) {
}
}
/**
* Prints this script's name, version, and copyright banner to stdout.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate setup.php when plugin_thold_version()
* isn't already loaded.
*/
function display_version() {
global $config;
@@ -167,7 +199,12 @@ function display_version() {
print 'Threshold Notification Processor, Version ' . $info['version'] . ', ' . COPYRIGHT_YEARS . PHP_EOL;
}
// display_help - displays the usage of the function
/**
* Prints this script's version banner followed by its command-line
* usage instructions to stdout.
*
* @return void
*/
function display_help() {
display_version();
+96 -1
View File
@@ -289,6 +289,18 @@ function sig_handler($signo) {
}
}
/**
* Logs a debug message from a worker thread to the Cacti log, only
* when global debug mode or the thold_daemon_debug setting is enabled.
*
* @param string $message The message to log.
* @param mixed $thread The worker thread identifier, passed through
* to thold_cacti_log() for log-line context.
*
* @return void
*
* @global bool $debug Whether debug output is enabled.
*/
function thold_daemon_debug($message, $thread) {
global $debug;
@@ -299,6 +311,25 @@ function thold_daemon_debug($message, $thread) {
}
}
/**
* Fetches the set of "live" percent/expression-based thresholds
* (thold_enabled and thold_per_enabled, flagged for a tcheck-style
* evaluation) queued for a worker thread by the daemon's data
* distribution step, restricted to hosts reporting as up. Uses the
* remote-poller-aware host status join when remote storage is
* configured. Filtered further via the 'thold_get_live_hosts' plugin
* hook.
*
* @param int $thread The worker thread id to fetch queued
* thresholds for.
* @param float $start_time The batch's start timestamp; only rows
* queued at or before this time are included.
*
* @return array The matching threshold records.
*
* @global array $config Cacti global configuration array; used when
* remote storage is configured.
*/
function thold_get_thresholds_tholdcheck($thread, $start_time) {
global $config;
@@ -349,6 +380,24 @@ function thold_get_thresholds_tholdcheck($thread, $start_time) {
return $tholds;
}
/**
* Fetches the set of thresholds (with their associated data source
* details) queued for a worker thread by the daemon's data
* distribution step, for standard (non-percent/expression) threshold
* evaluation. Uses the remote-poller-aware query variant when remote
* storage is configured.
*
* @param int $thread The worker thread id to fetch queued
* thresholds for.
* @param float $start_time The batch's start timestamp; only rows
* queued at or before this time are included.
*
* @return array The matching threshold records joined with data source
* details.
*
* @global array $config Cacti global configuration array; used when
* remote storage is configured.
*/
function thold_get_thresholds_precheck($thread, $start_time) {
global $config;
@@ -398,6 +447,16 @@ function thold_get_thresholds_precheck($thread, $start_time) {
return $tholds;
}
/**
* Checks whether the current database connection handle is a live,
* usable connection by attempting a trivial query against it, ignoring
* any resulting error via a temporary error handler swap.
*
* @return bool True if the connection is a valid object and the test
* query succeeds, false otherwise.
*
* @global object $cnn_id The current database connection handle.
*/
function thold_db_connection() {
global $cnn_id;
@@ -418,6 +477,18 @@ function thold_db_connection() {
return false;
}
/**
* Re-establishes a fresh database connection for a worker process,
* closing the given (presumably stale/dead) connection handle first if
* it's a valid object, then reloading Cacti's config.php to obtain
* current connection credentials and reconnecting.
*
* @param object|null $cnn_id The existing (possibly stale) database
* connection handle to close before
* reconnecting (default null).
*
* @return object|resource The new database connection handle.
*/
function thold_db_reconnect($cnn_id = null) {
chdir(__DIR__);
@@ -441,6 +512,16 @@ function thold_db_reconnect($cnn_id = null) {
return $cnn_id;
}
/**
* Prints a timestamped debug message directly to stdout when global
* debug mode is enabled.
*
* @param string $string The message to print.
*
* @return void
*
* @global bool $debug Whether debug output is enabled.
*/
function thold_cli_debug($string) {
global $debug;
@@ -451,6 +532,15 @@ function thold_cli_debug($string) {
}
}
/**
* Prints this script's name, version, and copyright banner to stdout.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate setup.php when plugin_thold_version()
* isn't already loaded.
*/
function display_version() {
global $config;
@@ -462,7 +552,12 @@ function display_version() {
print 'Threshold Processor, Version ' . $info['version'] . ', ' . COPYRIGHT_YEARS . PHP_EOL;
}
// display_help - displays the usage of the function
/**
* Prints this script's version banner followed by its command-line
* usage instructions to stdout.
*
* @return void
*/
function display_help() {
display_version();
+173 -1
View File
@@ -89,6 +89,20 @@ switch ($action) {
exit;
/**
* Handles the bulk-action confirmation page/submission for the
* threshold templates list (export via an injected download iframe,
* and delete). Called from this script's main request-dispatch switch
* when action=actions.
*
* @return void
*
* @global array $thold_template_actions Map of drp_action value =>
* action label (declared but the
* action values are switched on
* directly rather than read from
* this map).
*/
function do_actions() {
global $thold_template_actions;
@@ -342,6 +356,13 @@ function do_actions() {
exit;
}
/**
* Removes the association between a host and a threshold template.
* Called from this script's main request-dispatch switch when
* action=remove_host.
*
* @return void
*/
function template_remove_host_from_template() {
$host_id = get_filter_request_var('host_id');
$thold_template_id = get_filter_request_var('thold_template_id');
@@ -352,6 +373,13 @@ function template_remove_host_from_template() {
[$host_id, $thold_template_id]);
}
/**
* Creates (or replaces) the association between a host and a threshold
* template. Called from this script's main request-dispatch switch
* when action=add_host.
*
* @return void
*/
function template_add_host_to_template() {
$host_id = get_filter_request_var('host_id');
$thold_template_id = get_filter_request_var('thold_template_id');
@@ -361,6 +389,15 @@ function template_add_host_to_template() {
[$host_id, $thold_template_id]);
}
/**
* Exports the selected threshold template(s) as a downloaded XML file,
* replacing internal data template/data source ids with their portable
* hash identifiers so the export can be re-imported into a different
* Cacti instance. Called from this script's main request-dispatch
* switch when action=export.
*
* @return void
*/
function template_export() {
// if we are to save this form, instead of display it
if (isset_request_var('selected_items')) {
@@ -408,6 +445,17 @@ function template_export() {
}
}
/**
* Renders the threshold template creation wizard: on first display,
* shows the data template/data source selection form; once a selection
* is submitted, delegates to the standard template edit form
* (template_edit()-style rendering) pre-populated for the chosen data
* template/source so the new template's thresholds can be configured.
* Called from this script's main request-dispatch switch when
* action=template_add.
*
* @return void
*/
function template_add() {
if ((!isset_request_var('save')) || (get_nfilter_request_var('save') == '')) {
$data_templates = array_rekey(
@@ -656,6 +704,14 @@ function template_add() {
}
}
/**
* Disables all thresholds created from a given threshold template
* (that still have template-based fields enabled).
*
* @param int $id The threshold template id to disable thresholds for.
*
* @return void
*/
function thold_template_disable($id) {
db_execute_prepared('UPDATE thold_data
SET thold_enabled = "off"
@@ -664,6 +720,14 @@ function thold_template_disable($id) {
[$id]);
}
/**
* Re-enables all thresholds created from a given threshold template
* (that still have template-based fields enabled).
*
* @param int $id The threshold template id to enable thresholds for.
*
* @return void
*/
function thold_template_enable($id) {
db_execute_prepared('UPDATE thold_data
SET thold_enabled = "on"
@@ -672,6 +736,16 @@ function thold_template_enable($id) {
[$id]);
}
/**
* Validates and saves a threshold template's submitted edit form
* fields (name, thresholds/expression settings, notification/severity
* settings, host/enabled-state propagation to existing
* template-derived thresholds), then redirects back to the template
* edit form. Called from this script's main request-dispatch switch
* when action=template_save.
*
* @return void
*/
function template_save_edit() {
// ================= input validation =================
get_filter_request_var('id');
@@ -946,6 +1020,19 @@ function template_save_edit() {
}
}
/**
* Renders the add/edit form for a threshold template (thresholds,
* expressions, notification/severity settings, associated hosts), with
* a graph preview for the underlying data template/source. Called from
* this script's main request-dispatch switch when action=edit.
*
* @return void
*
* @global array $config Cacti global configuration array
* (declared but not used directly here).
* @global array $graph_timespans Time span option list used by the
* graph preview.
*/
function template_edit() {
global $config, $graph_timespans;
@@ -2049,6 +2136,18 @@ function template_edit() {
<?php
}
/**
* Formats a duration given in seconds into a human-readable
* "X Months, Y Days, Z Hours, ..." style string, showing only the
* largest applicable units and omitting zero-valued larger units.
*
* @param int $seconds The duration in seconds.
* @param string $suffix Either 'avg' (default, appends " (Average)"
* to the result) or any other value (no
* suffix).
*
* @return string The formatted, translated duration string.
*/
function template_calculate_reference_avg($seconds, $suffix = 'avg') {
$s = ($seconds % 60);
$m = floor(($seconds % 3600) / 60);
@@ -2089,6 +2188,13 @@ function template_calculate_reference_avg($seconds, $suffix = 'avg') {
}
}
/**
* Validates and stores this view's filter request variables (rows,
* page, filter text, sort column/direction) into the session for the
* threshold templates list view.
*
* @return void
*/
function template_request_validation() {
// ================= input validation and session storage =================
$filters = [
@@ -2127,6 +2233,29 @@ function template_request_validation() {
// ================= input validation =================
}
/**
* Renders the main threshold templates list page: validates/stores
* this view's filter request variables, then displays a filtered,
* sorted, paginated table of threshold templates with a bulk-actions
* dropdown. Called from this script's main request-dispatch switch as
* the default view.
*
* @return void
*
* @global array $config Cacti global configuration
* array.
* @global array $thold_template_actions Map of drp_action value =>
* action label, used for the
* bulk-actions dropdown.
* @global array $item_rows Default number of rows per
* page from Cacti settings.
* @global array $thold_types Threshold type option list
* used to display each template's
* type.
* @global array $bl_types Baseline type option list used
* to display each template's
* baseline type.
*/
function templates() {
global $config, $thold_template_actions, $item_rows, $thold_types, $bl_types;
@@ -2407,6 +2536,14 @@ function templates() {
thold_form_end();
}
/**
* Renders the threshold template import page: displays results from a
* previous import attempt (if any, stashed in the session), and the
* file-upload/paste-text import form. Called from this script's main
* request-dispatch switch when action=import.
*
* @return void
*/
function import() {
$form_data = [
'import_file' => [
@@ -2460,6 +2597,15 @@ function import() {
html_end_box();
}
/**
* Validates an uploaded threshold template import file (checking for
* upload errors and reading its contents), raising an error message
* for any upload failure.
*
* @return string|false The uploaded file's XML contents, or false if
* no file was uploaded or an upload error
* occurred.
*/
function validate_upload() {
// check file transfer if used
if (isset($_FILES['import_file'])) {
@@ -2516,6 +2662,16 @@ function validate_upload() {
return false;
}
/**
* Processes a submitted threshold template import (from pasted XML
* text or an uploaded file via validate_upload()), delegating the
* actual parsing/creation to thold_template_import(), then stashes the
* resulting success/error/failure messages in the session (also
* logging each to the Cacti log) before redirecting back to the import
* page.
*
* @return void This function calls exit() and never returns normally.
*/
function template_import() {
$xml_data = trim(get_nfilter_request_var('import_text'));
@@ -2557,7 +2713,23 @@ function template_import() {
exit();
}
// form_end - draws post form end. To be combined with form_start()
/**
* Prints the closing `</form>` tag for a page's main form, optionally
* followed by a JavaScript submit handler that redirects the form's
* submission through an AJAX-friendly URL (adding header=false) instead
* of a full page reload, unless the delete bulk-action was chosen. To
* be paired with an earlier form_start() call.
*
* @param bool $ajax Whether to emit the AJAX-friendly submit handler
* script (default true).
*
* @return void
*
* @global string $form_id The id of the form being closed, set by
* the paired form_start() call.
* @global string $form_action The form's action URL, set by the paired
* form_start() call.
*/
function thold_form_end($ajax = true) {
global $form_id, $form_action;
+81
View File
@@ -22,6 +22,20 @@
+-------------------------------------------------------------------------+
*/
/**
* Executes the "Create Threshold from Template" bulk graph action:
* applies a selected threshold template to a graph's matching data
* source(s) (across all RRD items sharing the template's configured
* data source name), creating a new thold_data row for each RRD item
* that doesn't already have a threshold from that template, then
* redirects back to the originating page with a summary message.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate library files and build the redirect
* URL.
*/
function thold_add_graphs_action_execute() {
global $config;
@@ -165,6 +179,16 @@ function thold_add_graphs_action_execute() {
}
}
/**
* Renders the confirmation/selection page for the "Create Threshold
* from Template" bulk graph action by delegating to thold_wizard().
* Cacti device_action_prepare-style hook entry point.
*
* @return void
*
* @global array $config Cacti global configuration array (declared but
* not used directly here).
*/
function thold_add_graphs_action_prepare() {
global $config;
@@ -175,12 +199,34 @@ function thold_add_graphs_action_prepare() {
bottom_footer();
}
/**
* Adds the "Create Threshold from Template" entry to the graph
* management bulk-actions dropdown. Registered as a Cacti
* graph_action_array-style hook.
*
* @param array $action The existing bulk-action label map, keyed by
* action id.
*
* @return array The action map with this plugin's entry added.
*/
function thold_add_graphs_action_array($action) {
$action['plugin_thold_create'] = __('Create Threshold from Template', 'thold');
return $action;
}
/**
* Renders the threshold-creation wizard: either the single-graph
* "apply a threshold template" confirmation form (when a graph and
* template selection was made), or the initial graph/template
* selection form used to bulk-create thresholds from a template across
* many graphs.
*
* @return void
*
* @global array $config Cacti global configuration array; used to
* locate the graph helper library to include.
*/
function thold_wizard() {
global $config;
@@ -858,6 +904,22 @@ function thold_wizard() {
bottom_footer();
}
/**
* Processes the "create graphs" wizard's submitted selection of new
* graphs/data sources for a host, creating each selected graph (and
* its underlying data source) via Cacti's graph creation API, then
* applying this plugin's configured auto-threshold-creation behavior
* to the newly created graphs. The selected-graphs payload is a nested
* (not flat) serialized structure, so it's parsed with a
* nested-structure-aware sanitizer/unserializer rather than the
* standard flat selected-items sanitizer.
*
* @param int $host_id The host id the new graphs are being created
* for.
*
* @return array|false The created graphs' details, or false if nothing
* was created/selected.
*/
function thold_new_graphs_save($host_id) {
$return_array = false;
@@ -1020,6 +1082,25 @@ function thold_new_graphs_save($host_id) {
return $return_array;
}
/**
* Renders the "create graphs" wizard page for a host/host template,
* listing the available graph templates/data queries to select new
* graphs from, using output buffering so the page can redirect
* elsewhere if no selectable fields end up being drawn.
*
* @param string $page The current page name (used
* for wizard step navigation).
* @param int $host_id The host id to create graphs
* for.
* @param int $host_template_id The host template id providing
* candidate graph templates/data
* queries.
* @param array $selected_graphs_array Previously selected graph
* choices to preserve across
* wizard steps.
*
* @return void
*/
function thold_graph_new_graphs($page, $host_id, $host_template_id, $selected_graphs_array) {
/* we use object buffering on this page to allow redirection to another page if no
fields are actually drawn */