mirror of
https://github.com/Cacti/cacti.git
synced 2026-10-23 03:27:02 +09:00
style(php): [develop] wrap CLI and poller calls without changing execution (#8303)
* style(php): wrap CLI and poller calls without changing execution Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * fix(ci): review security inventories after poller wrapping Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(boost): compare handoff source contracts by PHP tokens Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * style(php): wrap poller constant strings without changing values Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * style(php): wrap poller concatenations with token-preserving source contracts Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test(cli): assert CDEF repair queries after constant folding Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> * test: verify PHP formatting preserves parsed behavior Signed-off-by: Thomas Vincent <thomasvincent@gmail.com> --------- Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
This commit is contained in:
1 parent
f3ff777992
commit
2b6e96b23a
70 files changed
+2062
-417
No files matched your search
@@ -0,0 +1,34 @@
|
|||||||
|
name: PHP formatting behavior
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- '**.php'
|
||||||
|
- '.github/workflows/php-formatting-behavior.yml'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
behavior:
|
||||||
|
if: contains(fromJSON('["fix/develop-sonar-web-lines","fix/develop-sonar-library-lines","fix/develop-sonar-poller-lines"]'), github.head_ref)
|
||||||
|
name: Formatting preserves PHP behavior
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
timeout-minutes: 10
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
persist-credentials: false
|
||||||
|
- uses: ./.github/actions/setup-php-composer
|
||||||
|
with:
|
||||||
|
php-version: '8.3'
|
||||||
|
dependency-mode: locked-formatting-behavior
|
||||||
|
install-args: --prefer-dist --no-progress --no-interaction
|
||||||
|
- name: Check formatting and literal preservation
|
||||||
|
env:
|
||||||
|
BASE_COMMIT: ${{ github.event.pull_request.base.sha }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
php tests/tools/check_php_formatting.php --self-test
|
||||||
|
php tests/tools/check_php_formatting.php --base "$BASE_COMMIT"
|
||||||
+11
-3
@@ -114,7 +114,10 @@ if (!$foreground) {
|
|||||||
// We are the child
|
// We are the child
|
||||||
} else {
|
} else {
|
||||||
cacti_log('NOTE: Cacti Daemon PID[' . getmypid() . '] Started on Device[' . gethostname() . ']');
|
cacti_log('NOTE: Cacti Daemon PID[' . getmypid() . '] Started on Device[' . gethostname() . ']');
|
||||||
admin_email(__('Cacti System Notice'), __('Notice: Cacti Daemon PID[' . getmypid() . '] Started on Device[' . gethostname() . ']', true, 'CACTID'));
|
admin_email(__('Cacti System Notice'),
|
||||||
|
__('Notice: Cacti Daemon PID[' . getmypid() . '] Started on Device[' . gethostname() . ']',
|
||||||
|
true,
|
||||||
|
'CACTID'));
|
||||||
|
|
||||||
print '[OK]' . PHP_EOL;
|
print '[OK]' . PHP_EOL;
|
||||||
|
|
||||||
@@ -156,8 +159,13 @@ function sig_handler(int $signo) : void {
|
|||||||
switch ($signo) {
|
switch ($signo) {
|
||||||
case SIGTERM:
|
case SIGTERM:
|
||||||
case SIGINT:
|
case SIGINT:
|
||||||
cacti_log('WARNING: Cacti Daemon PID[' . getmypid() . '] Terminated on Device[' . gethostname() . ']', true, 'CACTID');
|
cacti_log('WARNING: Cacti Daemon PID[' . getmypid() . '] Terminated on Device[' . gethostname() . ']',
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: Cacti Daemon PID[' . getmypid() . '] Terminated on Device[' . gethostname() . ']', true, 'CACTID'));
|
true,
|
||||||
|
'CACTID');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: Cacti Daemon PID[' . getmypid() . '] Terminated on Device[' . gethostname() . ']',
|
||||||
|
true,
|
||||||
|
'CACTID'));
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
default:
|
default:
|
||||||
|
|||||||
+14
-4
@@ -212,7 +212,10 @@ if (cacti_sizeof($parms)) {
|
|||||||
|
|
||||||
if ((isset($exists_already)) &&
|
if ((isset($exists_already)) &&
|
||||||
($exists_already > 0)) {
|
($exists_already > 0)) {
|
||||||
print "ERROR: Data Query is already associated for host: ($host_id: $host_name) data query ($data_query_id: $data_query_name) reindex method ($reindex_method: " . $reindex_types[$reindex_method] . ')' . PHP_EOL;
|
print "ERROR: Data Query is already associated for host: ($host_id: $host_name) data query ($data_query_id: $data_query_name) reindex method ($reindex_method: " .
|
||||||
|
$reindex_types[$reindex_method] .
|
||||||
|
')' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -228,11 +231,17 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_error_message()) {
|
if (is_error_message()) {
|
||||||
print "ERROR: Failed to add this data query for host ($host_id: $host_name) data query ($data_query_id: $data_query_name) reindex method ($reindex_method: " . $reindex_types[$reindex_method] . ')' . PHP_EOL;
|
print "ERROR: Failed to add this data query for host ($host_id: $host_name) data query ($data_query_id: $data_query_name) reindex method ($reindex_method: " .
|
||||||
|
$reindex_types[$reindex_method] .
|
||||||
|
')' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
print "Success - Host ($host_id: $host_name) data query ($data_query_id: $data_query_name) reindex method ($reindex_method: " . $reindex_types[$reindex_method] . ')' . PHP_EOL;
|
print "Success - Host ($host_id: $host_name) data query ($data_query_id: $data_query_name) reindex method ($reindex_method: " .
|
||||||
|
$reindex_types[$reindex_method] .
|
||||||
|
')' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -261,7 +270,8 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: add_data_query.php --host-id=[ID] --data-query-id=[dq_id] --reindex-method=[method] [--quiet]' . PHP_EOL . PHP_EOL;
|
print ('usage: add_data_query.php --host-id=[ID] --data-query-id=[dq_id] ' .
|
||||||
|
'--reindex-method=[method] [--quiet]') . PHP_EOL . PHP_EOL;
|
||||||
print 'Required Options:' . PHP_EOL;
|
print 'Required Options:' . PHP_EOL;
|
||||||
print ' --host-id the numerical ID of the host' . PHP_EOL;
|
print ' --host-id the numerical ID of the host' . PHP_EOL;
|
||||||
print ' --data-query-id the numerical ID of the data_query to be added' . PHP_EOL;
|
print ' --data-query-id the numerical ID of the data_query to be added' . PHP_EOL;
|
||||||
|
|||||||
+36
-13
@@ -385,7 +385,9 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($snmp_ver > 3 || $snmp_ver < 0 || !is_numeric($snmp_ver)) {
|
if ($snmp_ver > 3 || $snmp_ver < 0 || !is_numeric($snmp_ver)) {
|
||||||
print 'ERROR: The snmp version must be between 0 and 3. If you did not specify one, goto Configuration > Settings > Device Defaults and resave your defaults.' . PHP_EOL;
|
print ('ERROR: The snmp version must be between 0 and 3. If you did not ' .
|
||||||
|
'specify one, goto Configuration > Settings > Device Defaults and ' .
|
||||||
|
'resave your defaults.') . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -405,7 +407,8 @@ if (cacti_sizeof($parms)) {
|
|||||||
break;
|
break;
|
||||||
case 'authnopriv':
|
case 'authnopriv':
|
||||||
if (empty($snmp_username) || empty($snmp_auth_protocol) || empty($snmp_password)) {
|
if (empty($snmp_username) || empty($snmp_auth_protocol) || empty($snmp_password)) {
|
||||||
print 'ERROR: For SNMP security level authNoPriv, you must enter username, password and SNMP auth protocol' . PHP_EOL;
|
print ('ERROR: For SNMP security level authNoPriv, you must enter username, ' .
|
||||||
|
'password and SNMP auth protocol') . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -414,8 +417,13 @@ if (cacti_sizeof($parms)) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case 'authpriv':
|
case 'authpriv':
|
||||||
if (empty($snmp_username) || empty($snmp_auth_protocol) || empty($snmp_password) || empty($snmp_priv_passphrase) || empty($snmp_priv_protocol)) {
|
if (empty($snmp_username) ||
|
||||||
print 'ERROR: For SNMP security level authNoPriv, you must enter username, password, SNMP auth protocol, priv protocol and priv passphrase' . PHP_EOL;
|
empty($snmp_auth_protocol) ||
|
||||||
|
empty($snmp_password) ||
|
||||||
|
empty($snmp_priv_passphrase) ||
|
||||||
|
empty($snmp_priv_protocol)) {
|
||||||
|
print ('ERROR: For SNMP security level authNoPriv, you must enter username, ' .
|
||||||
|
'password, SNMP auth protocol, priv protocol and priv passphrase') . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -474,7 +482,9 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($fail) {
|
if ($fail) {
|
||||||
db_execute_prepared('UPDATE host SET description = ? WHERE deleted = "" AND id = ?', [$description, $addresses[$ip]]);
|
db_execute_prepared('UPDATE host SET description = ? WHERE deleted = "" AND id = ?',
|
||||||
|
[$description,
|
||||||
|
$addresses[$ip]]);
|
||||||
print "ERROR: This IP already exists in the database ($ip) device-id: (" . $addresses[$ip] . ')' . PHP_EOL;
|
print "ERROR: This IP already exists in the database ($ip) device-id: (" . $addresses[$ip] . ')' . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -539,9 +549,15 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($snmp_ver < 3) {
|
if ($snmp_ver < 3) {
|
||||||
print "Adding $description ($ip) as \"" . $host_templates[$template_id] . "\" using SNMP v$snmp_ver with community \"$community\"" . PHP_EOL;
|
print "Adding $description ($ip) as \"" .
|
||||||
|
$host_templates[$template_id] .
|
||||||
|
"\" using SNMP v$snmp_ver with community \"$community\"" .
|
||||||
|
PHP_EOL;
|
||||||
} else {
|
} else {
|
||||||
print "Adding $description ($ip) as \"" . $host_templates[$template_id] . "\" using SNMP v$snmp_ver with username \"$snmp_username\"" . PHP_EOL;
|
print "Adding $description ($ip) as \"" .
|
||||||
|
$host_templates[$template_id] .
|
||||||
|
"\" using SNMP v$snmp_ver with username \"$snmp_username\"" .
|
||||||
|
PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$host_id = api_device_save(0, (int) $template_id, $description, $ip,
|
$host_id = api_device_save(0, (int) $template_id, $description, $ip,
|
||||||
@@ -586,9 +602,11 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: add_device.php --description=[description] --ip=[IP] --template=[ID] [--notes="[]"] [--disable]' . PHP_EOL;
|
print ('usage: add_device.php --description=[description] --ip=[IP] ' .
|
||||||
|
'--template=[ID] [--notes="[]"] [--disable]') . PHP_EOL;
|
||||||
print ' [--poller=[id]] [--site=[id] [--external-id=[S]] [--proxy] [--threads=[1]' . PHP_EOL;
|
print ' [--poller=[id]] [--site=[id] [--external-id=[S]] [--proxy] [--threads=[1]' . PHP_EOL;
|
||||||
print ' [--avail=[ping]] --ping_method=[icmp] --ping_port=[N/A, 1-65534] --ping_timeout=[N] --ping_retries=[2]' . PHP_EOL;
|
print (' [--avail=[ping]] --ping_method=[icmp] --ping_port=[N/A, 1-65534] ' .
|
||||||
|
'--ping_timeout=[N] --ping_retries=[2]') . PHP_EOL;
|
||||||
print ' [--version=[0|1|2|3]] [--community=] [--port=161] [--timeout=500] [--retries=3] [--options=0]' . PHP_EOL;
|
print ' [--version=[0|1|2|3]] [--community=] [--port=161] [--timeout=500] [--retries=3] [--options=0]' . PHP_EOL;
|
||||||
print ' [--username= --password=] [--authproto=] [--privpass= --privproto=] [--context=] [--engineid=]' . PHP_EOL;
|
print ' [--username= --password=] [--authproto=] [--privpass= --privproto=] [--context=] [--engineid=]' . PHP_EOL;
|
||||||
print ' [--quiet]' . PHP_EOL . PHP_EOL;
|
print ' [--quiet]' . PHP_EOL . PHP_EOL;
|
||||||
@@ -619,13 +637,18 @@ function display_help() : void {
|
|||||||
print " --security-level '', noAuthNoPriv|authNoPriv|authPriv, security level for snmpv3" . PHP_EOL;
|
print " --security-level '', noAuthNoPriv|authNoPriv|authPriv, security level for snmpv3" . PHP_EOL;
|
||||||
print " --username '', snmp username for snmpv3" . PHP_EOL;
|
print " --username '', snmp username for snmpv3" . PHP_EOL;
|
||||||
print " --password '', snmp password for snmpv3" . PHP_EOL;
|
print " --password '', snmp password for snmpv3" . PHP_EOL;
|
||||||
print " --authproto '', [None]|MD5|SHA|SHA224|SHA256|SHA392|SHA512$, snmp authentication protocol for snmpv3" . PHP_EOL;
|
print (" --authproto '', [None]|MD5|SHA|SHA224|SHA256|SHA392|SHA512$, " .
|
||||||
|
'snmp authentication protocol for snmpv3') . PHP_EOL;
|
||||||
print " --privpass '', snmp privacy passphrase for snmpv3" . PHP_EOL;
|
print " --privpass '', snmp privacy passphrase for snmpv3" . PHP_EOL;
|
||||||
print " --privproto '', [None]|DES|AES|AES128|AES192|AES192C|AES256|AES256C$, snmp privacy protocol for snmpv3" . PHP_EOL;
|
print (" --privproto '', " .
|
||||||
|
'[None]|DES|AES|AES128|AES192|AES192C|AES256|AES256C$, snmp privacy ' .
|
||||||
|
'protocol for snmpv3') . PHP_EOL;
|
||||||
print " --context '', snmp context for snmpv3" . PHP_EOL;
|
print " --context '', snmp context for snmpv3" . PHP_EOL;
|
||||||
print " --engineid '', snmp engineid for snmpv3" . PHP_EOL;
|
print " --engineid '', snmp engineid for snmpv3" . PHP_EOL;
|
||||||
print ' --max_oids 10, 1-60, the number of OIDs that can be obtained in a single SNMP Get request' . PHP_EOL . PHP_EOL;
|
print (' --max_oids 10, 1-60, the number of OIDs that can be ' .
|
||||||
print ' --bulk_walk -1, 1-60, the bulk walk chunk size that will be used for bulk walks. Use -1 for auto-tune.' . PHP_EOL . PHP_EOL;
|
'obtained in a single SNMP Get request') . PHP_EOL . PHP_EOL;
|
||||||
|
print (' --bulk_walk -1, 1-60, the bulk walk chunk size that will be ' .
|
||||||
|
'used for bulk walks. Use -1 for auto-tune.') . PHP_EOL . PHP_EOL;
|
||||||
print 'List Options:' . PHP_EOL;
|
print 'List Options:' . PHP_EOL;
|
||||||
print ' --list-host-templates' . PHP_EOL;
|
print ' --list-host-templates' . PHP_EOL;
|
||||||
print ' --list-communities' . PHP_EOL;
|
print ' --list-communities' . PHP_EOL;
|
||||||
|
|||||||
@@ -162,11 +162,16 @@ if (cacti_sizeof($parms)) {
|
|||||||
|
|
||||||
if ((isset($exists_already)) &&
|
if ((isset($exists_already)) &&
|
||||||
($exists_already > 0)) {
|
($exists_already > 0)) {
|
||||||
print "ERROR: Graph Template is already associated for host: ($host_id: $host_name) - graph-template: ($graph_template_id: $graph_template_name)" . PHP_EOL;
|
print "ERROR: Graph Template is already associated for host: ($host_id: $host_name) - graph-template: ($graph_template_id: $graph_template_name)" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
db_execute('replace into host_graph (host_id,graph_template_id) values (' . $host_id . ',' . $graph_template_id . ')');
|
db_execute('replace into host_graph (host_id,graph_template_id) values (' .
|
||||||
|
$host_id .
|
||||||
|
',' .
|
||||||
|
$graph_template_id .
|
||||||
|
')');
|
||||||
|
|
||||||
if ($host_id > 0) {
|
if ($host_id > 0) {
|
||||||
object_cache_get_totals('device_state', $host_id);
|
object_cache_get_totals('device_state', $host_id);
|
||||||
@@ -179,15 +184,19 @@ if (cacti_sizeof($parms)) {
|
|||||||
object_cache_update_totals('diff');
|
object_cache_update_totals('diff');
|
||||||
}
|
}
|
||||||
|
|
||||||
api_plugin_hook_function('add_graph_template_to_host', ['host_id' => $host_id, 'graph_template_id' => $graph_template_id]);
|
api_plugin_hook_function('add_graph_template_to_host',
|
||||||
|
['host_id' => $host_id,
|
||||||
|
'graph_template_id' => $graph_template_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_error_message()) {
|
if (is_error_message()) {
|
||||||
print "ERROR: Failed to add this graph template for host: ($host_id: $host_name) - graph-template: ($graph_template_id: $graph_template_name)" . PHP_EOL;
|
print "ERROR: Failed to add this graph template for host: ($host_id: $host_name) - graph-template: ($graph_template_id: $graph_template_name)" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
print "Success: Graph Template associated for host: ($host_id: $host_name) - graph-template: ($graph_template_id: $graph_template_name)" . PHP_EOL;
|
print "Success: Graph Template associated for host: ($host_id: $host_name) - graph-template: ($graph_template_id: $graph_template_name)" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
+34
-12
@@ -467,7 +467,8 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
} elseif ($nbSnmpValuesRegex) {
|
} elseif ($nbSnmpValuesRegex) {
|
||||||
if ($nbSnmpFields != $nbSnmpValuesRegex) {
|
if ($nbSnmpFields != $nbSnmpValuesRegex) {
|
||||||
print "ERROR: number of --snmp-field ($nbSnmpFields) and --snmp-value-regex ($nbSnmpValuesRegex) does not match" . PHP_EOL;
|
print "ERROR: number of --snmp-field ($nbSnmpFields) and --snmp-value-regex ($nbSnmpValuesRegex) does not match" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -544,7 +545,10 @@ if (cacti_sizeof($parms)) {
|
|||||||
foreach ($dsGraph['snmpFieldExclude'] as $snmpField) {
|
foreach ($dsGraph['snmpFieldExclude'] as $snmpField) {
|
||||||
if ($snmpField != '') {
|
if ($snmpField != '') {
|
||||||
if (!isset($snmpFields[$snmpField])) {
|
if (!isset($snmpFields[$snmpField])) {
|
||||||
print 'ERROR: Unknown snmp-field-exclude ' . $dsGraph['snmpFieldExclude'][$index_filter] . " for host $host_id" . PHP_EOL;
|
print 'ERROR: Unknown snmp-field-exclude ' .
|
||||||
|
$dsGraph['snmpFieldExclude'][$index_filter] .
|
||||||
|
" for host $host_id" .
|
||||||
|
PHP_EOL;
|
||||||
print 'Try --list-snmp-fields' . PHP_EOL;
|
print 'Try --list-snmp-fields' . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -639,7 +643,9 @@ if (cacti_sizeof($parms)) {
|
|||||||
|
|
||||||
$value = $option_value[1];
|
$value = $option_value[1];
|
||||||
|
|
||||||
$values['cg'][$template_id]['custom_data'][$data_template_id][$input_fields[$data_template_id . ':' . $field_name]['data_input_field_id']] = $value;
|
$values['cg'][$template_id]['custom_data'][$data_template_id][$input_fields[$data_template_id .
|
||||||
|
':' .
|
||||||
|
$field_name]['data_input_field_id']] = $value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -671,7 +677,8 @@ if (cacti_sizeof($parms)) {
|
|||||||
LIMIT 1',
|
LIMIT 1',
|
||||||
[$existsAlready]);
|
[$existsAlready]);
|
||||||
|
|
||||||
print "NOTE: Not Adding Graph - this graph already exists - graph-id: ($existsAlready) - data-source-id: ($dataSourceId)" . PHP_EOL;
|
print "NOTE: Not Adding Graph - this graph already exists - graph-id: ($existsAlready) - data-source-id: ($dataSourceId)" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
@@ -714,7 +721,9 @@ if (cacti_sizeof($parms)) {
|
|||||||
print 'Graph Not Added due to whitelist check failure.' . PHP_EOL;
|
print 'Graph Not Added due to whitelist check failure.' . PHP_EOL;
|
||||||
}
|
}
|
||||||
} elseif ($graph_type == 'ds') {
|
} elseif ($graph_type == 'ds') {
|
||||||
if (($dsGraph['snmpQueryId'] == '') || ($dsGraph['snmpQueryType'] == '') || (cacti_sizeof($dsGraph['snmpField']) == 0)) {
|
if (($dsGraph['snmpQueryId'] == '') ||
|
||||||
|
($dsGraph['snmpQueryType'] == '') ||
|
||||||
|
(cacti_sizeof($dsGraph['snmpField']) == 0)) {
|
||||||
print 'ERROR: For graph-type of \'ds\' you must supply more options' . PHP_EOL;
|
print 'ERROR: For graph-type of \'ds\' you must supply more options' . PHP_EOL;
|
||||||
display_help();
|
display_help();
|
||||||
|
|
||||||
@@ -736,7 +745,10 @@ if (cacti_sizeof($parms)) {
|
|||||||
if (cacti_sizeof($dsGraph['snmpField'])) {
|
if (cacti_sizeof($dsGraph['snmpField'])) {
|
||||||
foreach ($dsGraph['snmpField'] as $snmpField) {
|
foreach ($dsGraph['snmpField'] as $snmpField) {
|
||||||
$req .= ' AND snmp_index IN (
|
$req .= ' AND snmp_index IN (
|
||||||
SELECT DISTINCT snmp_index FROM host_snmp_cache WHERE host_id=' . $host_id . ' AND field_name = ' . db_qstr($snmpField);
|
SELECT DISTINCT snmp_index FROM host_snmp_cache WHERE host_id=' .
|
||||||
|
$host_id .
|
||||||
|
' AND field_name = ' .
|
||||||
|
db_qstr($snmpField);
|
||||||
|
|
||||||
if (isset($dsGraph['snmpValue'][$index_snmp_filter])) {
|
if (isset($dsGraph['snmpValue'][$index_snmp_filter])) {
|
||||||
$req .= ' AND field_value = ' . db_qstr($dsGraph['snmpValue'][$index_snmp_filter]) . ')';
|
$req .= ' AND field_value = ' . db_qstr($dsGraph['snmpValue'][$index_snmp_filter]) . ')';
|
||||||
@@ -753,7 +765,10 @@ if (cacti_sizeof($parms)) {
|
|||||||
if (cacti_sizeof($dsGraph['snmpFieldExclude'])) {
|
if (cacti_sizeof($dsGraph['snmpFieldExclude'])) {
|
||||||
foreach ($dsGraph['snmpFieldExclude'] as $snmpField) {
|
foreach ($dsGraph['snmpFieldExclude'] as $snmpField) {
|
||||||
$req .= ' AND snmp_index NOT IN (
|
$req .= ' AND snmp_index NOT IN (
|
||||||
SELECT DISTINCT snmp_index FROM host_snmp_cache WHERE host_id=' . $host_id . ' AND field_name = ' . db_qstr($snmpField);
|
SELECT DISTINCT snmp_index FROM host_snmp_cache WHERE host_id=' .
|
||||||
|
$host_id .
|
||||||
|
' AND field_name = ' .
|
||||||
|
db_qstr($snmpField);
|
||||||
$req .= ' AND field_value REGEXP ' . db_qstr($dsGraph['snmpValueExclude'][$index_snmp_filter]) . ')';
|
$req .= ' AND field_value REGEXP ' . db_qstr($dsGraph['snmpValueExclude'][$index_snmp_filter]) . ')';
|
||||||
$index_snmp_filter++;
|
$index_snmp_filter++;
|
||||||
}
|
}
|
||||||
@@ -794,7 +809,8 @@ if (cacti_sizeof($parms)) {
|
|||||||
LIMIT 1',
|
LIMIT 1',
|
||||||
[$existsAlready]);
|
[$existsAlready]);
|
||||||
|
|
||||||
print "NOTE: Not Adding Graph - this graph already exists - graph-id: ($existsAlready) - data-source-id: ($dataSourceId)" . PHP_EOL;
|
print "NOTE: Not Adding Graph - this graph already exists - graph-id: ($existsAlready) - data-source-id: ($dataSourceId)" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -846,7 +862,10 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cacti_sizeof($dsGraph['snmpValueExclude'])) {
|
if (cacti_sizeof($dsGraph['snmpValueExclude'])) {
|
||||||
$err_msg .= ') and snmp-field-exclude (' . implode(',',$dsGraph['snmpFieldExclude']) . ' ) with values (' . implode(',',$dsGraph['snmpValueExclude']);
|
$err_msg .= ') and snmp-field-exclude (' .
|
||||||
|
implode(',',$dsGraph['snmpFieldExclude']) .
|
||||||
|
' ) with values (' .
|
||||||
|
implode(',',$dsGraph['snmpValueExclude']);
|
||||||
}
|
}
|
||||||
|
|
||||||
$err_msg .= ') for host-id ' . $host_id . ' (' . $hosts[$host_id]['hostname'] . ')' . PHP_EOL;
|
$err_msg .= ') for host-id ' . $host_id . ' (' . $hosts[$host_id]['hostname'] . ')' . PHP_EOL;
|
||||||
@@ -908,7 +927,8 @@ function display_help() : void {
|
|||||||
print ' --snmp-value=[SNMP Value] | --snmp-value-regex=[REGEX]' . PHP_EOL;
|
print ' --snmp-value=[SNMP Value] | --snmp-value-regex=[REGEX]' . PHP_EOL;
|
||||||
print ' [--graph-title=S] Defaults to what ever is in the Graph Template/Data Template.' . PHP_EOL;
|
print ' [--graph-title=S] Defaults to what ever is in the Graph Template/Data Template.' . PHP_EOL;
|
||||||
print ' [--reindex-method=N] The reindex method to be used for that data query.' . PHP_EOL;
|
print ' [--reindex-method=N] The reindex method to be used for that data query.' . PHP_EOL;
|
||||||
print ' NOTE: If Data Query is already associated, the reindex method will NOT be changed.' . PHP_EOL . PHP_EOL;
|
print (' NOTE: If Data Query is already ' .
|
||||||
|
'associated, the reindex method will NOT be changed.') . PHP_EOL . PHP_EOL;
|
||||||
print ' --snmp-field-exclude=[SNMP Field] | --snmp-value-exclude=[REGEX]' . PHP_EOL;
|
print ' --snmp-field-exclude=[SNMP Field] | --snmp-value-exclude=[REGEX]' . PHP_EOL;
|
||||||
print ' Optionally used to exclude specific word/s in adding graphs' . PHP_EOL;
|
print ' Optionally used to exclude specific word/s in adding graphs' . PHP_EOL;
|
||||||
print ' Valid --reindex-methods include' . PHP_EOL;
|
print ' Valid --reindex-methods include' . PHP_EOL;
|
||||||
@@ -916,8 +936,10 @@ function display_help() : void {
|
|||||||
print ' 1|Uptime = Uptime goes Backwards (Default)' . PHP_EOL;
|
print ' 1|Uptime = Uptime goes Backwards (Default)' . PHP_EOL;
|
||||||
print ' 2|Index = Index Count Changed' . PHP_EOL;
|
print ' 2|Index = Index Count Changed' . PHP_EOL;
|
||||||
print ' 3|Fields = Verify all Fields' . PHP_EOL . PHP_EOL;
|
print ' 3|Fields = Verify all Fields' . PHP_EOL . PHP_EOL;
|
||||||
print ' NOTE: You may supply multiples of the --snmp-field and --snmp-value | --snmp-value-regex arguments.' . PHP_EOL . PHP_EOL;
|
print (' NOTE: You may supply multiples of the --snmp-field and ' .
|
||||||
print ' NOTE2: You may supply multiples of the --snmp-field-exclude and --snmp-value-exclude arguments.' . PHP_EOL . PHP_EOL;
|
'--snmp-value | --snmp-value-regex arguments.') . PHP_EOL . PHP_EOL;
|
||||||
|
print (' NOTE2: You may supply multiples of the --snmp-field-exclude and ' .
|
||||||
|
'--snmp-value-exclude arguments.') . PHP_EOL . PHP_EOL;
|
||||||
print 'List Options:' . PHP_EOL;
|
print 'List Options:' . PHP_EOL;
|
||||||
print ' --list-hosts' . PHP_EOL;
|
print ' --list-hosts' . PHP_EOL;
|
||||||
print ' --list-graph-templates [--host-template-id=[ID]]' . PHP_EOL;
|
print ' --list-graph-templates [--host-template-id=[ID]]' . PHP_EOL;
|
||||||
|
|||||||
+2
-1
@@ -215,7 +215,8 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: add_groups.php --type=[add_group|group_perm] --name=[name] --description=[description]' . PHP_EOL . PHP_EOL;
|
print ('usage: add_groups.php --type=[add_group|group_perm] --name=[name] ' .
|
||||||
|
'--description=[description]') . PHP_EOL . PHP_EOL;
|
||||||
print '[--quiet]' . PHP_EOL . PHP_EOL;
|
print '[--quiet]' . PHP_EOL . PHP_EOL;
|
||||||
print 'List Options:' . PHP_EOL;
|
print 'List Options:' . PHP_EOL;
|
||||||
print ' --list-users' . PHP_EOL;
|
print ' --list-users' . PHP_EOL;
|
||||||
|
|||||||
@@ -222,7 +222,8 @@ if (cacti_sizeof($params) == 0) {
|
|||||||
// TODO replace magic numbers by global constants, treat user_admin as well
|
// TODO replace magic numbers by global constants, treat user_admin as well
|
||||||
switch ($itemType) {
|
switch ($itemType) {
|
||||||
case 1: // graph
|
case 1: // graph
|
||||||
if (!db_fetch_cell_prepared('SELECT local_graph_id FROM graph_templates_graph WHERE local_graph_id = ?', [$itemId])) {
|
if (!db_fetch_cell_prepared('SELECT local_graph_id FROM graph_templates_graph WHERE local_graph_id = ?',
|
||||||
|
[$itemId])) {
|
||||||
print "ERROR: Invalid Graph item id: ($itemId)" . PHP_EOL . PHP_EOL;
|
print "ERROR: Invalid Graph item id: ($itemId)" . PHP_EOL . PHP_EOL;
|
||||||
display_help();
|
display_help();
|
||||||
|
|
||||||
@@ -272,7 +273,8 @@ if (cacti_sizeof($params) == 0) {
|
|||||||
* Right now it only does hostname */
|
* Right now it only does hostname */
|
||||||
$idName = db_fetch_cell_prepared('SELECT hostname FROM host WHERE id = ?', [$itemId]);
|
$idName = db_fetch_cell_prepared('SELECT hostname FROM host WHERE id = ?', [$itemId]);
|
||||||
|
|
||||||
print "Group Permissions Created - Group-Name: ($groupId - \"$groupName\" ) Item-Type: ($itemType - $itemTypeName) Item-ID: ($itemId - $idName)" . PHP_EOL;
|
print "Group Permissions Created - Group-Name: ($groupId - \"$groupName\" ) Item-Type: ($itemType - $itemTypeName) Item-ID: ($itemId - $idName)" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -225,7 +225,8 @@ if (cacti_sizeof($parms) == 0) {
|
|||||||
// TODO replace magic numbers by global constants, treat user_admin as well
|
// TODO replace magic numbers by global constants, treat user_admin as well
|
||||||
switch ($itemType) {
|
switch ($itemType) {
|
||||||
case 1: // graph
|
case 1: // graph
|
||||||
if (!db_fetch_cell_prepared('SELECT local_graph_id FROM graph_templates_graph WHERE local_graph_id = ?', [$itemId])) {
|
if (!db_fetch_cell_prepared('SELECT local_graph_id FROM graph_templates_graph WHERE local_graph_id = ?',
|
||||||
|
[$itemId])) {
|
||||||
print "ERROR: Invalid Graph item id: ($itemId)" . PHP_EOL . PHP_EOL;
|
print "ERROR: Invalid Graph item id: ($itemId)" . PHP_EOL . PHP_EOL;
|
||||||
display_help();
|
display_help();
|
||||||
|
|
||||||
@@ -264,7 +265,10 @@ if (cacti_sizeof($parms) == 0) {
|
|||||||
// verified item-id
|
// verified item-id
|
||||||
|
|
||||||
foreach ($userIds as $id) {
|
foreach ($userIds as $id) {
|
||||||
db_execute_prepared('REPLACE INTO user_auth_perms (user_id, item_id, type) VALUES (?, ?, ?)', [$id, $itemId, $itemType]);
|
db_execute_prepared('REPLACE INTO user_auth_perms (user_id, item_id, type) VALUES (?, ?, ?)',
|
||||||
|
[$id,
|
||||||
|
$itemId,
|
||||||
|
$itemType]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+27
-7
@@ -427,7 +427,11 @@ function doDeviceMap(int $deviceId, int $siteId) : bool {
|
|||||||
*
|
*
|
||||||
* @return array - The geocodeAddress location
|
* @return array - The geocodeAddress location
|
||||||
*/
|
*/
|
||||||
function geocodeAddress(string $siteAddr1, string $siteAddr2, string $siteCity, string $siteZip, string $siteCountry) : array {
|
function geocodeAddress(string $siteAddr1,
|
||||||
|
string $siteAddr2,
|
||||||
|
string $siteCity,
|
||||||
|
string $siteZip,
|
||||||
|
string $siteCountry) : array {
|
||||||
global $verbose, $debug, $quiet, $geocodeApiKey, $httpsProxy;
|
global $verbose, $debug, $quiet, $geocodeApiKey, $httpsProxy;
|
||||||
|
|
||||||
$latGeocode = '';
|
$latGeocode = '';
|
||||||
@@ -444,7 +448,13 @@ function geocodeAddress(string $siteAddr1, string $siteAddr2, string $siteCity,
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
$requestUrl = sprintf('%s?address=%s,%s,%s,%s&key=%s', $googleApiUrl, urlencode($siteAddr1), urlencode($siteAddr2), urlencode($siteCity), urlencode($siteCountry), $geocodeApiKey);
|
$requestUrl = sprintf('%s?address=%s,%s,%s,%s&key=%s',
|
||||||
|
$googleApiUrl,
|
||||||
|
urlencode($siteAddr1),
|
||||||
|
urlencode($siteAddr2),
|
||||||
|
urlencode($siteCity),
|
||||||
|
urlencode($siteCountry),
|
||||||
|
$geocodeApiKey);
|
||||||
|
|
||||||
if ($verbose || $debug) {
|
if ($verbose || $debug) {
|
||||||
echoQuiet("Geocode URL: $requestUrl\n" . PHP_EOL);
|
echoQuiet("Geocode URL: $requestUrl\n" . PHP_EOL);
|
||||||
@@ -477,9 +487,14 @@ function geocodeAddress(string $siteAddr1, string $siteAddr2, string $siteCity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fixCoordinates(string $lat, string $lng) : array {
|
function fixCoordinates(string $lat, string $lng) : array {
|
||||||
$utfCoord = mb_convert_encoding("$lat $lng", 'ISO-8859-1', 'UTF-8'); // Normalise the characters to put them through a regex
|
$utfCoord = mb_convert_encoding("$lat $lng",
|
||||||
|
'ISO-8859-1',
|
||||||
|
'UTF-8'); // Normalise the characters to put them through a regex
|
||||||
|
|
||||||
if (preg_match('/(\d+)\xB0(\d+)\'((?:[.]\d+|\d+(?:[.]\d*)?))"?([NS]) +(\d+)\xB0(\d+)\'((?:[.]\d+|\d+(?:[.]\d*)?))"?([EW])/', $utfCoord, $matches)) {
|
if (preg_match('/(\d+)\xB0(\d+)\'((?:[.]\d+|\d+(?:[.]\d*)?))"?([NS]) ' .
|
||||||
|
'+(\d+)\xB0(\d+)\'((?:[.]\d+|\d+(?:[.]\d*)?))"?([EW])/',
|
||||||
|
$utfCoord,
|
||||||
|
$matches)) {
|
||||||
array_shift($matches); // Get rid of $matches[0]
|
array_shift($matches); // Get rid of $matches[0]
|
||||||
[$degN, $minN, $secN, $NS, $degE, $minE, $secE, $EW] = $matches; // Get the matches from the regex
|
[$degN, $minN, $secN, $NS, $degE, $minE, $secE, $EW] = $matches; // Get the matches from the regex
|
||||||
|
|
||||||
@@ -515,7 +530,10 @@ function fetchCurl(string $url) : string|false {
|
|||||||
global $verbose, $debug, $httpsProxy;
|
global $verbose, $debug, $httpsProxy;
|
||||||
|
|
||||||
if (!function_exists('curl_init')) {
|
if (!function_exists('curl_init')) {
|
||||||
print 'Error: cURL must be enabled in PHP if --geocode is specified.' . PHP_EOL . 'See http://php.net/manual/en/curl.setup.php for help.' . PHP_EOL;
|
print 'Error: cURL must be enabled in PHP if --geocode is specified.' .
|
||||||
|
PHP_EOL .
|
||||||
|
'See http://php.net/manual/en/curl.setup.php for help.' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
display_help();
|
display_help();
|
||||||
|
|
||||||
@@ -599,8 +617,10 @@ function display_help() : void {
|
|||||||
|
|
||||||
echoQuiet('Geocoding Options:' . PHP_EOL);
|
echoQuiet('Geocoding Options:' . PHP_EOL);
|
||||||
echoQuiet(' --geocode Try to turn addresses into GPS coordinates' . PHP_EOL);
|
echoQuiet(' --geocode Try to turn addresses into GPS coordinates' . PHP_EOL);
|
||||||
echoQuiet(' --geocode-api-key Your Google API key - https://developers.google.com/maps/documentation/geocoding/get-api-key' . PHP_EOL);
|
echoQuiet((' --geocode-api-key Your Google API key - ' .
|
||||||
echoQuiet(' --proxy Proxy server to use in http://proxy.server:port format' . PHP_EOL . PHP_EOL);
|
'https://developers.google.com/maps/documentation/geocoding/get-api-key') . PHP_EOL);
|
||||||
|
echoQuiet((' --proxy Proxy server to use in ' .
|
||||||
|
'http://proxy.server:port format') . PHP_EOL . PHP_EOL);
|
||||||
|
|
||||||
echoQuiet('Device Map Options:' . PHP_EOL);
|
echoQuiet('Device Map Options:' . PHP_EOL);
|
||||||
echoQuiet(" --device-map-regex=[regular expression] e.g.'rtr-th[e|w]-pe\d'" . PHP_EOL);
|
echoQuiet(" --device-map-regex=[regular expression] e.g.'rtr-th[e|w]-pe\d'" . PHP_EOL);
|
||||||
|
|||||||
+11
-1
@@ -347,7 +347,17 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// $nodeId could be a Header Node, a Graph Node, or a Host node.
|
// $nodeId could be a Header Node, a Graph Node, or a Host node.
|
||||||
$nodeId = api_tree_item_save(0, $treeId, $itemType, $parentNode, $name, $graphId, $hostId, $siteId, $hostGroupStyle, $sortMethods[$sortMethod], false);
|
$nodeId = api_tree_item_save(0,
|
||||||
|
$treeId,
|
||||||
|
$itemType,
|
||||||
|
$parentNode,
|
||||||
|
$name,
|
||||||
|
$graphId,
|
||||||
|
$hostId,
|
||||||
|
$siteId,
|
||||||
|
$hostGroupStyle,
|
||||||
|
$sortMethods[$sortMethod],
|
||||||
|
false);
|
||||||
|
|
||||||
print "Added Node node-id: ($nodeId)" . PHP_EOL;
|
print "Added Node node-id: ($nodeId)" . PHP_EOL;
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ if (cacti_sizeof($tables)) {
|
|||||||
print ($status == 0 ? ' Failed' : ' Successful') . PHP_EOL;
|
print ($status == 0 ? ' Failed' : ' Successful') . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log('ANALYSIS STATS: Analyzing Cacti Tables Complete. Total time ' . (time() - $start) . ' seconds.', false, 'SYSTEM');
|
cacti_log('ANALYSIS STATS: Analyzing Cacti Tables Complete. Total time ' . (time() - $start) . ' seconds.',
|
||||||
|
false,
|
||||||
|
'SYSTEM');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -201,7 +201,8 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: apply_automation_rules.php --ids="id1 id2 ..." || --description=S || --hostname=S [--debug]' . PHP_EOL . PHP_EOL;
|
print ('usage: apply_automation_rules.php --ids="id1 id2 ..." || ' .
|
||||||
|
'--description=S || --hostname=S [--debug]') . PHP_EOL . PHP_EOL;
|
||||||
print 'A utility to execute Cacti automation rules for a devices or devices. Any of the following' . PHP_EOL;
|
print 'A utility to execute Cacti automation rules for a devices or devices. Any of the following' . PHP_EOL;
|
||||||
print 'three options can be used, but at least one must be specified.' . PHP_EOL . PHP_EOL;
|
print 'three options can be used, but at least one must be specified.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
|
|||||||
+45
-11
@@ -244,7 +244,10 @@ function upgrade_database() : void {
|
|||||||
if ($return_var == 0) {
|
if ($return_var == 0) {
|
||||||
cacti_log(sprintf('NOTE: Cacti Upgrade succeeded in %.2f seconds', $end - $start), true, 'UPGRADE');
|
cacti_log(sprintf('NOTE: Cacti Upgrade succeeded in %.2f seconds', $end - $start), true, 'UPGRADE');
|
||||||
} else {
|
} else {
|
||||||
cacti_log('WARNING: Cacti Upgrade Encountered Errors. Messages below. Details are below, but also in Cacti upgrade log.', true, 'UPGRADE');
|
cacti_log('WARNING: Cacti Upgrade Encountered Errors. Messages below. Details ' .
|
||||||
|
'are below, but also in Cacti upgrade log.',
|
||||||
|
true,
|
||||||
|
'UPGRADE');
|
||||||
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
||||||
print implode(PHP_EOL, $output) . PHP_EOL;
|
print implode(PHP_EOL, $output) . PHP_EOL;
|
||||||
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
||||||
@@ -310,7 +313,9 @@ function upgrade_database() : void {
|
|||||||
// Always run the new function if it's there
|
// Always run the new function if it's there
|
||||||
// Some plugins don't upgrade in the proper way
|
// Some plugins don't upgrade in the proper way
|
||||||
if (function_exists($ufunc3)) {
|
if (function_exists($ufunc3)) {
|
||||||
cacti_log("NOTE: Running Plugin $pname install function due to some plugins not upgrading properly.", true, 'UPGRADE');
|
cacti_log("NOTE: Running Plugin $pname install function due to some plugins not upgrading properly.",
|
||||||
|
true,
|
||||||
|
'UPGRADE');
|
||||||
$ufunc3(true);
|
$ufunc3(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,19 +333,25 @@ function upgrade_database() : void {
|
|||||||
$return_var = 0;
|
$return_var = 0;
|
||||||
$output = [];
|
$output = [];
|
||||||
|
|
||||||
exec('php ' . CACTI_PATH_PLUGINS . '/' . $pname . '/database_upgrade.php --type=large --force-ver=' . $old, $output, $return_var);
|
exec('php ' . CACTI_PATH_PLUGINS . '/' . $pname . '/database_upgrade.php --type=large --force-ver=' . $old,
|
||||||
|
$output,
|
||||||
|
$return_var);
|
||||||
|
|
||||||
if ($return_var == 0) {
|
if ($return_var == 0) {
|
||||||
print implode(PHP_EOL, $output) . PHP_EOL;
|
print implode(PHP_EOL, $output) . PHP_EOL;
|
||||||
cacti_log("NOTE: Cacti Plugin $pname Upgrade Succeeded.", true, 'UPGRADE');
|
cacti_log("NOTE: Cacti Plugin $pname Upgrade Succeeded.", true, 'UPGRADE');
|
||||||
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL;
|
||||||
print implode(PHP_EOL, $output) . PHP_EOL;
|
print implode(PHP_EOL, $output) . PHP_EOL;
|
||||||
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL;
|
||||||
} else {
|
} else {
|
||||||
cacti_log("WARNING: Cacti Plugin $pname Upgrade Encountered Errors.", true, 'UPGRADE');
|
cacti_log("WARNING: Cacti Plugin $pname Upgrade Encountered Errors.", true, 'UPGRADE');
|
||||||
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL;
|
||||||
print implode(PHP_EOL, $output) . PHP_EOL;
|
print implode(PHP_EOL, $output) . PHP_EOL;
|
||||||
print '------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -374,7 +385,9 @@ function upgrade_database() : void {
|
|||||||
|
|
||||||
api_plugin_uninstall($pname, false);
|
api_plugin_uninstall($pname, false);
|
||||||
} else {
|
} else {
|
||||||
cacti_log("NOTE: Uninstalling Plugin $pname which is not supported and setup.php not found. Preserving tables.", true, 'UPGRADE');
|
cacti_log("NOTE: Uninstalling Plugin $pname which is not supported and setup.php not found. Preserving tables.",
|
||||||
|
true,
|
||||||
|
'UPGRADE');
|
||||||
db_execute_prepared('DELETE FROM plugin_config WHERE directory = ?', [$pname]);
|
db_execute_prepared('DELETE FROM plugin_config WHERE directory = ?', [$pname]);
|
||||||
db_execute_prepared('DELETE FROM plugin_db_changes WHERE plugin = ?', [$pname]);
|
db_execute_prepared('DELETE FROM plugin_db_changes WHERE plugin = ?', [$pname]);
|
||||||
db_execute_prepared('DELETE FROM plugin_hooks WHERE name = ?', [$pname]);
|
db_execute_prepared('DELETE FROM plugin_hooks WHERE name = ?', [$pname]);
|
||||||
@@ -635,7 +648,16 @@ function report_audit_results(bool $output = true) : array {
|
|||||||
// Handle Timestamp on DEFAULT/ON UPDATE irregularities
|
// Handle Timestamp on DEFAULT/ON UPDATE irregularities
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
print PHP_EOL . 'ERROR Col: \'' . $c['Field'] . '\', Attribute \'' . $col . '\' invalid. Should be: \'' . $dbc[$dbcol] . '\', Is: \'' . $c[$col] . '\'';
|
print PHP_EOL .
|
||||||
|
'ERROR Col: \'' .
|
||||||
|
$c['Field'] .
|
||||||
|
'\', Attribute \'' .
|
||||||
|
$col .
|
||||||
|
'\' invalid. Should be: \'' .
|
||||||
|
$dbc[$dbcol] .
|
||||||
|
'\', Is: \'' .
|
||||||
|
$c[$col] .
|
||||||
|
'\'';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -727,7 +749,16 @@ function report_audit_results(bool $output = true) : array {
|
|||||||
if ($i['Key_name'] != 'PRIMARY') {
|
if ($i['Key_name'] != 'PRIMARY') {
|
||||||
if (array_search($i['Key_name'], $idx_added, true) === false) {
|
if (array_search($i['Key_name'], $idx_added, true) === false) {
|
||||||
if ($output) {
|
if ($output) {
|
||||||
print PHP_EOL . 'ERROR Index: \'' . $i['Key_name'] . '\', Attribute \'' . $idx . '\' invalid. Should be: \'' . $dbc[$dbidx] . '\', Is: \'' . $i[$idx] . '\'';
|
print PHP_EOL .
|
||||||
|
'ERROR Index: \'' .
|
||||||
|
$i['Key_name'] .
|
||||||
|
'\', Attribute \'' .
|
||||||
|
$idx .
|
||||||
|
'\' invalid. Should be: \'' .
|
||||||
|
$dbc[$dbidx] .
|
||||||
|
'\', Is: \'' .
|
||||||
|
$i[$idx] .
|
||||||
|
'\'';
|
||||||
}
|
}
|
||||||
|
|
||||||
$alter_cmds = array_merge($alter_cmds, make_index_alter($table_name, $i['Key_name']));
|
$alter_cmds = array_merge($alter_cmds, make_index_alter($table_name, $i['Key_name']));
|
||||||
@@ -1123,7 +1154,10 @@ function create_tables(bool $load = true) : void {
|
|||||||
/* the credentials go in a private defaults file rather than on the
|
/* the credentials go in a private defaults file rather than on the
|
||||||
* command line, where any local user could read them out of the
|
* command line, where any local user could read them out of the
|
||||||
* process list for as long as the import runs */
|
* process list for as long as the import runs */
|
||||||
$defaults_file = audit_database_defaults_file($database_username, $database_password, $database_hostname, $database_port);
|
$defaults_file = audit_database_defaults_file($database_username,
|
||||||
|
$database_password,
|
||||||
|
$database_hostname,
|
||||||
|
$database_port);
|
||||||
|
|
||||||
if ($defaults_file === false) {
|
if ($defaults_file === false) {
|
||||||
print 'FATAL: Unable to create a private credentials file' . PHP_EOL;
|
print 'FATAL: Unable to create a private credentials file' . PHP_EOL;
|
||||||
|
|||||||
+35
-5
@@ -364,8 +364,17 @@ if ($child == 0) {
|
|||||||
$now = date('H:i:s');
|
$now = date('H:i:s');
|
||||||
|
|
||||||
if ($not_finished > 0) {
|
if ($not_finished > 0) {
|
||||||
printf('NOTE: %s, Status %s of %s RRDfiles processed. Total Time is %.0f.' . PHP_EOL, $now, number_format($rrdfiles - $not_finished), number_format($rrdfiles), $end - $start);
|
printf('NOTE: %s, Status %s of %s RRDfiles processed. Total Time is %.0f.' . PHP_EOL,
|
||||||
printf('NOTE: %s, Processing Rate: %s RRDfiles per/second, Estimated Complete in: %s seconds, Sleeping 1 seconds.' . PHP_EOL, $now, round($rate, 2), $estimate);
|
$now,
|
||||||
|
number_format($rrdfiles - $not_finished),
|
||||||
|
number_format($rrdfiles),
|
||||||
|
$end - $start);
|
||||||
|
printf(('NOTE: %s, Processing Rate: %s RRDfiles per/second, Estimated Complete ' .
|
||||||
|
'in: %s seconds, Sleeping 1 seconds.') . PHP_EOL,
|
||||||
|
$now,
|
||||||
|
round($rate,
|
||||||
|
2),
|
||||||
|
$estimate);
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: All RRDfiles processed. Total Time was %.2f seconds.' . PHP_EOL, $end - $start);
|
printf('NOTE: All RRDfiles processed. Total Time was %.2f seconds.' . PHP_EOL, $end - $start);
|
||||||
|
|
||||||
@@ -376,7 +385,16 @@ if ($child == 0) {
|
|||||||
$succeeded = db_fetch_cell('SELECT COUNT(*) FROM graph_local_spikekill WHERE exit_code = 0');
|
$succeeded = db_fetch_cell('SELECT COUNT(*) FROM graph_local_spikekill WHERE exit_code = 0');
|
||||||
$failed = db_fetch_cell('SELECT COUNT(*) FROM graph_local_spikekill WHERE exit_code != 0');
|
$failed = db_fetch_cell('SELECT COUNT(*) FROM graph_local_spikekill WHERE exit_code != 0');
|
||||||
|
|
||||||
cacti_log(sprintf('BATCHFIX STATS: Time:%s, RRDfiles:%s, Threads:%s, Rate:%s, Succeeded:%s, Failed:%s', round($end - $start, 2), $rrdfiles, $threads, round($rate,2), $succeeded, $failed), false, 'SYSTEM');
|
cacti_log(sprintf('BATCHFIX STATS: Time:%s, RRDfiles:%s, Threads:%s, Rate:%s, Succeeded:%s, Failed:%s',
|
||||||
|
round($end - $start,
|
||||||
|
2),
|
||||||
|
$rrdfiles,
|
||||||
|
$threads,
|
||||||
|
round($rate,2),
|
||||||
|
$succeeded,
|
||||||
|
$failed),
|
||||||
|
false,
|
||||||
|
'SYSTEM');
|
||||||
|
|
||||||
unregister_process('batchgapfix', $type, $child);
|
unregister_process('batchgapfix', $type, $child);
|
||||||
|
|
||||||
@@ -444,9 +462,21 @@ if ($child == 0) {
|
|||||||
|
|
||||||
$end = microtime(true);
|
$end = microtime(true);
|
||||||
|
|
||||||
printf('NOTE: Batch Fill Process Ended in %s seconds. Succeeded:%s, Failed:%s' . PHP_EOL, round($end - $start, 2), $succeeded, $failed);
|
printf('NOTE: Batch Fill Process Ended in %s seconds. Succeeded:%s, Failed:%s' . PHP_EOL,
|
||||||
|
round($end - $start,
|
||||||
|
2),
|
||||||
|
$succeeded,
|
||||||
|
$failed);
|
||||||
|
|
||||||
cacti_log(sprintf('BATCHFIX CHILD STATS: Time:%s, Thread:%s, RRDfiles:%s, Succeeded:%s, Failed:%s', round($end - $start, 2), $child, cacti_sizeof($rrdfiles), $succeeded, $failed), false, 'SYSTEM');
|
cacti_log(sprintf('BATCHFIX CHILD STATS: Time:%s, Thread:%s, RRDfiles:%s, Succeeded:%s, Failed:%s',
|
||||||
|
round($end - $start,
|
||||||
|
2),
|
||||||
|
$child,
|
||||||
|
cacti_sizeof($rrdfiles),
|
||||||
|
$succeeded,
|
||||||
|
$failed),
|
||||||
|
false,
|
||||||
|
'SYSTEM');
|
||||||
|
|
||||||
unregister_process('batchgapfix', $type, $child);
|
unregister_process('batchgapfix', $type, $child);
|
||||||
}
|
}
|
||||||
|
|||||||
+26
-8
@@ -357,7 +357,9 @@ if ($host['hostname'] == '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($host['snmp_version'] > 3 || $host['snmp_version'] < 0 || !is_numeric($host['snmp_version'])) {
|
if ($host['snmp_version'] > 3 || $host['snmp_version'] < 0 || !is_numeric($host['snmp_version'])) {
|
||||||
print 'ERROR: The snmp version must be between 0 and 3. If you did not specify one, goto Configuration > Settings > Device Defaults and resave your defaults.' . PHP_EOL;
|
print ('ERROR: The snmp version must be between 0 and 3. If you did not ' .
|
||||||
|
'specify one, goto Configuration > Settings > Device Defaults and ' .
|
||||||
|
'resave your defaults.') . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -407,7 +409,8 @@ if ($host['snmp_version'] < 3) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$quietMode) {
|
if (!$quietMode) {
|
||||||
print "Changing device-id: $device_id to {$host['description']} ({$host['hostname']}) as \"{$host_templates[$host['host_template_id']]}\" using SNMP v{$host['snmp_version']} with community \"{$host['snmp_community']}\"" . PHP_EOL;
|
print "Changing device-id: $device_id to {$host['description']} ({$host['hostname']}) as \"{$host_templates[$host['host_template_id']]}\" using SNMP v{$host['snmp_version']} with community \"{$host['snmp_community']}\"" .
|
||||||
|
PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$host_id = api_device_save($device_id, $host['host_template_id'], $host['description'], $host['hostname'],
|
$host_id = api_device_save($device_id, $host['host_template_id'], $host['description'], $host['hostname'],
|
||||||
@@ -415,8 +418,18 @@ $host_id = api_device_save($device_id, $host['host_template_id'], $host['descrip
|
|||||||
$host['snmp_port'], $host['snmp_timeout'], $host['disabled'], $host['availability_method'], $host['ping_method'],
|
$host['snmp_port'], $host['snmp_timeout'], $host['disabled'], $host['availability_method'], $host['ping_method'],
|
||||||
$host['ping_port'], $host['ping_timeout'], $host['ping_retries'], $host['notes'],
|
$host['ping_port'], $host['ping_timeout'], $host['ping_retries'], $host['notes'],
|
||||||
$host['snmp_auth_protocol'], $host['snmp_priv_passphrase'],
|
$host['snmp_auth_protocol'], $host['snmp_priv_passphrase'],
|
||||||
$host['snmp_priv_protocol'], $host['snmp_context'], $host['snmp_engine_id'], $host['max_oids'], $host['device_threads'],
|
$host['snmp_priv_protocol'],
|
||||||
$host['poller_id'], $host['site_id'], $host['external_id'], $host['location'], $host['bulk_walk_size'], $host['snmp_options'], $host['snmp_retries']);
|
$host['snmp_context'],
|
||||||
|
$host['snmp_engine_id'],
|
||||||
|
$host['max_oids'],
|
||||||
|
$host['device_threads'],
|
||||||
|
$host['poller_id'],
|
||||||
|
$host['site_id'],
|
||||||
|
$host['external_id'],
|
||||||
|
$host['location'],
|
||||||
|
$host['bulk_walk_size'],
|
||||||
|
$host['snmp_options'],
|
||||||
|
$host['snmp_retries']);
|
||||||
|
|
||||||
if (is_error_message() || $host_id != $device_id) {
|
if (is_error_message() || $host_id != $device_id) {
|
||||||
print "ERROR: Failed to change this device ($device_id-$host_id)" . PHP_EOL;
|
print "ERROR: Failed to change this device ($device_id-$host_id)" . PHP_EOL;
|
||||||
@@ -449,16 +462,20 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: change_device.php --id=<device-id> [--description=[description]] [--ip=[IP]] [--template=[ID]] [--notes="[]"] [--disable]' . PHP_EOL;
|
print ('usage: change_device.php --id=<device-id> ' .
|
||||||
|
'[--description=[description]] [--ip=[IP]] [--template=[ID]] ' .
|
||||||
|
'[--notes="[]"] [--disable]') . PHP_EOL;
|
||||||
print ' [--poller=[id]] [--site=[id] [--external-id=[S]] [--proxy] [--threads=[1]' . PHP_EOL;
|
print ' [--poller=[id]] [--site=[id] [--external-id=[S]] [--proxy] [--threads=[1]' . PHP_EOL;
|
||||||
print ' [--avail=[ping]] --ping_method=[icmp] --ping_port=[N/A, 1-65534] --ping_timeout=[N] --ping_retries=[2]' . PHP_EOL;
|
print (' [--avail=[ping]] --ping_method=[icmp] --ping_port=[N/A, 1-65534] ' .
|
||||||
|
'--ping_timeout=[N] --ping_retries=[2]') . PHP_EOL;
|
||||||
print ' [--version=[0|1|2|3]] [--community=] [--port=161] [--timeout=500] [--retries=3] [--options=0]' . PHP_EOL;
|
print ' [--version=[0|1|2|3]] [--community=] [--port=161] [--timeout=500] [--retries=3] [--options=0]' . PHP_EOL;
|
||||||
print ' [--username= --password=] [--authproto=] [--privpass= --privproto=] [--context=] [--engineid=]' . PHP_EOL;
|
print ' [--username= --password=] [--authproto=] [--privpass= --privproto=] [--context=] [--engineid=]' . PHP_EOL;
|
||||||
print ' [--quiet]' . PHP_EOL . PHP_EOL;
|
print ' [--quiet]' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Required:' . PHP_EOL;
|
print 'Required:' . PHP_EOL;
|
||||||
print ' --id the id for a device, that is field id in table host' . PHP_EOL;
|
print ' --id the id for a device, that is field id in table host' . PHP_EOL;
|
||||||
print ' any optional device attribute parameter given, will replace the existing parameter' . PHP_EOL . PHP_EOL;
|
print (' any optional device attribute parameter given, ' .
|
||||||
|
'will replace the existing parameter') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Optional:' . PHP_EOL;
|
print 'Optional:' . PHP_EOL;
|
||||||
print ' --description the name that will be displayed by Cacti in the graphs' . PHP_EOL;
|
print ' --description the name that will be displayed by Cacti in the graphs' . PHP_EOL;
|
||||||
@@ -491,6 +508,7 @@ function display_help() : void {
|
|||||||
print " --context '', snmp context for snmpv3" . PHP_EOL;
|
print " --context '', snmp context for snmpv3" . PHP_EOL;
|
||||||
print " --engineid '', snmp engineid for snmpv3" . PHP_EOL;
|
print " --engineid '', snmp engineid for snmpv3" . PHP_EOL;
|
||||||
print ' --max_oids 10, 1-60, the number of OIDs that can be obtained in a single SNMP Get request' . PHP_EOL;
|
print ' --max_oids 10, 1-60, the number of OIDs that can be obtained in a single SNMP Get request' . PHP_EOL;
|
||||||
print ' --bulk_walk -1, 1-60, the bulk walk chunk size that will be used for bulk walks. Use -1 for auto-tune.' . PHP_EOL;
|
print (' --bulk_walk -1, 1-60, the bulk walk chunk size that will be ' .
|
||||||
|
'used for bulk walks. Use -1 for auto-tune.') . PHP_EOL;
|
||||||
print ' --quiet - batch mode value return' . PHP_EOL . PHP_EOL;
|
print ' --quiet - batch mode value return' . PHP_EOL . PHP_EOL;
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,12 @@ if (cacti_sizeof($parms)) {
|
|||||||
printf('---------------------------------------------------------------' . PHP_EOL);
|
printf('---------------------------------------------------------------' . PHP_EOL);
|
||||||
|
|
||||||
if ($template_id) {
|
if ($template_id) {
|
||||||
$output = api_clone_device_template_check_for_errors($template_id, $template_name, $include_gt, $clone_gt, $include_dq, $clone_dq,
|
$output = api_clone_device_template_check_for_errors($template_id,
|
||||||
|
$template_name,
|
||||||
|
$include_gt,
|
||||||
|
$clone_gt,
|
||||||
|
$include_dq,
|
||||||
|
$clone_dq,
|
||||||
$include_dt, $clone_dt, $suffix, $clone_xml, $clone_script);
|
$include_dt, $clone_dt, $suffix, $clone_xml, $clone_script);
|
||||||
} else {
|
} else {
|
||||||
$output['errors'][] = sprintf('FATAL: You must specify a Device Template ID to continue!');
|
$output['errors'][] = sprintf('FATAL: You must specify a Device Template ID to continue!');
|
||||||
@@ -451,7 +456,8 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: clone_device_template.php --device-template=N [ --device-template-name=S ] [ --debug ] [ --quiet ]' . PHP_EOL;
|
print ('usage: clone_device_template.php --device-template=N [ ' .
|
||||||
|
'--device-template-name=S ] [ --debug ] [ --quiet ]') . PHP_EOL;
|
||||||
print ' [ --include-graph-templates=all|N,N,... ] [ --clone-graph-templates=all|N,N,N ]' . PHP_EOL;
|
print ' [ --include-graph-templates=all|N,N,... ] [ --clone-graph-templates=all|N,N,N ]' . PHP_EOL;
|
||||||
print ' [ --include-data-queries=all|N,N,... ] [ --clone-data-queries=all|N,N,N ]' . PHP_EOL;
|
print ' [ --include-data-queries=all|N,N,... ] [ --clone-data-queries=all|N,N,N ]' . PHP_EOL;
|
||||||
print ' [ --include-data-templates=all|N,N,... ] [ --clone-data-templates=all|N,N,N ]' . PHP_EOL;
|
print ' [ --include-data-templates=all|N,N,... ] [ --clone-data-templates=all|N,N,N ]' . PHP_EOL;
|
||||||
@@ -473,7 +479,8 @@ function display_help() : void {
|
|||||||
print '* The default Device Template Name will be the original with the --suffix specified' . PHP_EOL;
|
print '* The default Device Template Name will be the original with the --suffix specified' . PHP_EOL;
|
||||||
print '* The default setting for both \'--include-*\' and \'--clone-*\' is \'--include=all\'' . PHP_EOL;
|
print '* The default setting for both \'--include-*\' and \'--clone-*\' is \'--include=all\'' . PHP_EOL;
|
||||||
print '* The default setting for \'--suffix\' id \'_copy\'.' . PHP_EOL . PHP_EOL;
|
print '* The default setting for \'--suffix\' id \'_copy\'.' . PHP_EOL . PHP_EOL;
|
||||||
print '* The \'all\' Options for \'--include-*\' and \'--clone-*\' are mutually exclusive to one another.' . PHP_EOL . PHP_EOL;
|
print ('* The \'all\' Options for \'--include-*\' and \'--clone-*\' are ' .
|
||||||
|
'mutually exclusive to one another.') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'NOTES:' . PHP_EOL;
|
print 'NOTES:' . PHP_EOL;
|
||||||
print '* CDEFs, VDEFs, GPRINTs, and Data Source Profiles will not be cloned.' . PHP_EOL;
|
print '* CDEFs, VDEFs, GPRINTs, and Data Source Profiles will not be cloned.' . PHP_EOL;
|
||||||
@@ -493,7 +500,8 @@ function display_help() : void {
|
|||||||
print ' --clone-data-templates=all|N,N - Comma delimited list of Data Templates to clone.' . PHP_EOL;
|
print ' --clone-data-templates=all|N,N - Comma delimited list of Data Templates to clone.' . PHP_EOL;
|
||||||
|
|
||||||
print ' --suffix=S - When cloning the object, the new name suffix.' . PHP_EOL;
|
print ' --suffix=S - When cloning the object, the new name suffix.' . PHP_EOL;
|
||||||
print ' --quiet - Do not prompt to confirm, just take action (batch mode).' . PHP_EOL . PHP_EOL;
|
print (' --quiet - Do not prompt to confirm, just ' .
|
||||||
|
'take action (batch mode).') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Script and XML Handling:' . PHP_EOL;
|
print 'Script and XML Handling:' . PHP_EOL;
|
||||||
print ' --clone-scripts - Will copy the Data Input Scripts to new names when cloning Data Templates.' . PHP_EOL;
|
print ' --clone-scripts - Will copy the Data Input Scripts to new names when cloning Data Templates.' . PHP_EOL;
|
||||||
@@ -501,7 +509,8 @@ function display_help() : void {
|
|||||||
|
|
||||||
print 'List Options:' . PHP_EOL;
|
print 'List Options:' . PHP_EOL;
|
||||||
print ' --list-all - List all Device Templates their names and ids.' . PHP_EOL;
|
print ' --list-all - List all Device Templates their names and ids.' . PHP_EOL;
|
||||||
print ' --list-template=N - List a specific Device Template and all its components.' . PHP_EOL . PHP_EOL;
|
print (' --list-template=N - List a specific Device Template ' .
|
||||||
|
'and all its components.') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Debug Options:' . PHP_EOL;
|
print 'Debug Options:' . PHP_EOL;
|
||||||
print ' --debug - Be more verbose in during processing' . PHP_EOL;
|
print ' --debug - Be more verbose in during processing' . PHP_EOL;
|
||||||
|
|||||||
@@ -136,7 +136,8 @@ if (cacti_sizeof($parms)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cacti_sizeof($skip_tables) && $table_name != '') {
|
if (cacti_sizeof($skip_tables) && $table_name != '') {
|
||||||
print_or_log($installer, 'ERROR: You can not specify a single table and skip tables at the same time.' . PHP_EOL . PHP_EOL);
|
print_or_log($installer,
|
||||||
|
'ERROR: You can not specify a single table and skip tables at the same time.' . PHP_EOL . PHP_EOL);
|
||||||
display_help();
|
display_help();
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -333,7 +334,8 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: convert_tables.php [--debug] [--innodb] [--utf8] [--latin1] [--table=N] [--size=N] [--rebuild] [--dynamic]' . PHP_EOL . PHP_EOL;
|
print ('usage: convert_tables.php [--debug] [--innodb] [--utf8] [--latin1] ' .
|
||||||
|
'[--table=N] [--size=N] [--rebuild] [--dynamic]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'A utility to convert a Cacti Database from MyISAM to the InnoDB table format.' . PHP_EOL;
|
print 'A utility to convert a Cacti Database from MyISAM to the InnoDB table format.' . PHP_EOL;
|
||||||
print 'MEMORY tables are not converted to InnoDB in this process.' . PHP_EOL . PHP_EOL;
|
print 'MEMORY tables are not converted to InnoDB in this process.' . PHP_EOL . PHP_EOL;
|
||||||
|
|||||||
+12
-2
@@ -161,7 +161,12 @@ function database_fix_mediumint_columns() : int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($attribs['Default'] != '') {
|
if ($attribs['Default'] != '') {
|
||||||
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $c . ' int(10) unsigned NOT NULL default "' . $attribs['Default'] . '"';
|
$sql .= ($i == 0 ? '' : ', ') .
|
||||||
|
' MODIFY COLUMN ' .
|
||||||
|
$c .
|
||||||
|
' int(10) unsigned NOT NULL default "' .
|
||||||
|
$attribs['Default'] .
|
||||||
|
'"';
|
||||||
} elseif ($attribs['Null'] == 'NO') {
|
} elseif ($attribs['Null'] == 'NO') {
|
||||||
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $c . ' int(10) unsigned NOT NULL';
|
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $c . ' int(10) unsigned NOT NULL';
|
||||||
} else {
|
} else {
|
||||||
@@ -210,7 +215,12 @@ function database_fix_mediumint_columns() : int {
|
|||||||
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $field . ' int(10) unsigned NOT NULL AUTO_INCREMENT';
|
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $field . ' int(10) unsigned NOT NULL AUTO_INCREMENT';
|
||||||
} else {
|
} else {
|
||||||
if ($attribs['Default'] != '') {
|
if ($attribs['Default'] != '') {
|
||||||
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $field . ' int(10) unsigned NOT NULL default "' . $attribs['Default'] . '"';
|
$sql .= ($i == 0 ? '' : ', ') .
|
||||||
|
' MODIFY COLUMN ' .
|
||||||
|
$field .
|
||||||
|
' int(10) unsigned NOT NULL default "' .
|
||||||
|
$attribs['Default'] .
|
||||||
|
'"';
|
||||||
} elseif ($attribs['Null'] == 'NO') {
|
} elseif ($attribs['Null'] == 'NO') {
|
||||||
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $field . ' int(10) unsigned NOT NULL';
|
$sql .= ($i == 0 ? '' : ', ') . ' MODIFY COLUMN ' . $field . ' int(10) unsigned NOT NULL';
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+92
-14
@@ -197,7 +197,11 @@ if (!is_numeric($end_time)) {
|
|||||||
|
|
||||||
// validate the start and end times are sane
|
// validate the start and end times are sane
|
||||||
if ($start_time >= $end_time) {
|
if ($start_time >= $end_time) {
|
||||||
printf('ERROR: The Start Time \'%s\' is equal or grater to the End Time \'%s\' is not a valid date/time' . PHP_EOL, date('Y-m-d H:i:s', (int) $start_time), date('Y-m-d H:i:s', $end_time));
|
printf('ERROR: The Start Time \'%s\' is equal or grater to the End Time \'%s\' is not a valid date/time' . PHP_EOL,
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
(int) $start_time),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$end_time));
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -268,7 +272,16 @@ if (!$forcerun) {
|
|||||||
// Collect data as determined by the type
|
// Collect data as determined by the type
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'rmaster':
|
case 'rmaster':
|
||||||
float_master_handler($forcerun, $resume, $host_id, $host_template_id, $graph_template_id, $local_graph_ids, $threads, $step, $start_time, $end_time);
|
float_master_handler($forcerun,
|
||||||
|
$resume,
|
||||||
|
$host_id,
|
||||||
|
$host_template_id,
|
||||||
|
$graph_template_id,
|
||||||
|
$local_graph_ids,
|
||||||
|
$threads,
|
||||||
|
$step,
|
||||||
|
$start_time,
|
||||||
|
$end_time);
|
||||||
|
|
||||||
unregister_process('rfloat', 'rmaster', 0);
|
unregister_process('rfloat', 'rmaster', 0);
|
||||||
|
|
||||||
@@ -415,9 +428,28 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
|
|||||||
} elseif ($prev_data != '') {
|
} elseif ($prev_data != '') {
|
||||||
if ($seebug) {
|
if ($seebug) {
|
||||||
if ($step !== false) {
|
if ($step !== false) {
|
||||||
is_resource($lf) && fwrite($lf, sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s, Step:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time, $step));
|
is_resource($lf) && fwrite($lf,
|
||||||
|
sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s, Step:%s' . PHP_EOL,
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$timestamp),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$start_time),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$end_time),
|
||||||
|
$granularity,
|
||||||
|
$delta_time,
|
||||||
|
$step));
|
||||||
} else {
|
} else {
|
||||||
is_resource($lf) && fwrite($lf, sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time));
|
is_resource($lf) && fwrite($lf,
|
||||||
|
sprintf('In Range: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL,
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$timestamp),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$start_time),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$end_time),
|
||||||
|
$granularity,
|
||||||
|
$delta_time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,14 +461,36 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
|
|||||||
$nline = $db_prefix . implode(' ', $parts) . ' ' . $prev_data . PHP_EOL;
|
$nline = $db_prefix . implode(' ', $parts) . ' ' . $prev_data . PHP_EOL;
|
||||||
|
|
||||||
if ($seebug) {
|
if ($seebug) {
|
||||||
is_resource($lf) && fwrite($lf, sprintf('Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time));
|
is_resource($lf) && fwrite($lf,
|
||||||
is_resource($lf) && fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\nNewLine: %s\n\n", trim($prev_line), trim($line), trim($nline)));
|
sprintf('Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL,
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$timestamp),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$start_time),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$end_time),
|
||||||
|
$granularity,
|
||||||
|
$delta_time));
|
||||||
|
is_resource($lf) && fwrite($lf,
|
||||||
|
sprintf("PreLine: %s\nOldLine: %s\nNewLine: %s\n\n",
|
||||||
|
trim($prev_line),
|
||||||
|
trim($line),
|
||||||
|
trim($nline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$line = $nline;
|
$line = $nline;
|
||||||
} else {
|
} else {
|
||||||
if ($seebug) {
|
if ($seebug) {
|
||||||
is_resource($lf) && fwrite($lf, sprintf('Not Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL, date('Y-m-d H:i:s', $timestamp), date('Y-m-d H:i:s', $start_time), date('Y-m-d H:i:s', $end_time), $granularity, $delta_time));
|
is_resource($lf) && fwrite($lf,
|
||||||
|
sprintf('Not Pruning: CurDate:%s, StartDate:%s, EndDate:%s, Granularity:%s, Delta:%s' . PHP_EOL,
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$timestamp),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$start_time),
|
||||||
|
date('Y-m-d H:i:s',
|
||||||
|
$end_time),
|
||||||
|
$granularity,
|
||||||
|
$delta_time));
|
||||||
is_resource($lf) && fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\n\n", trim($prev_line), trim($line)));
|
is_resource($lf) && fwrite($lf, sprintf("PreLine: %s\nOldLine: %s\n\n", trim($prev_line), trim($line)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -461,7 +515,11 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
|
|||||||
// restore the file
|
// restore the file
|
||||||
$return = 0;
|
$return = 0;
|
||||||
$output = [];
|
$output = [];
|
||||||
$command = cacti_escapeshellcmd($rrdtool_bin) . ' restore -f ' . cacti_escapeshellarg($tmp_file) . ' ' . cacti_escapeshellarg($rrd_path);
|
$command = cacti_escapeshellcmd($rrdtool_bin) .
|
||||||
|
' restore -f ' .
|
||||||
|
cacti_escapeshellarg($tmp_file) .
|
||||||
|
' ' .
|
||||||
|
cacti_escapeshellarg($rrd_path);
|
||||||
|
|
||||||
$response = exec($command, $output, $return);
|
$response = exec($command, $output, $return);
|
||||||
|
|
||||||
@@ -478,7 +536,11 @@ function float_rrdfile(string $rrd_path, int $local_data_id, mixed $step, int $s
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
cacti_log(sprintf('WARNING: Range float FAILED for RRDfile %s. Message is %s', $rrd_path, $response), false, 'RFLOAT');
|
cacti_log(sprintf('WARNING: Range float FAILED for RRDfile %s. Message is %s',
|
||||||
|
$rrd_path,
|
||||||
|
$response),
|
||||||
|
false,
|
||||||
|
'RFLOAT');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -583,7 +645,8 @@ function float_master_handler(bool $forcerun, bool $resume, int $host_id, int $h
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$rrdfiles_per_process = ceil(db_fetch_cell_prepared('SELECT COUNT(*)/? FROM poller_float_rrdfiles_not_done', [$threads]));
|
$rrdfiles_per_process = ceil(db_fetch_cell_prepared('SELECT COUNT(*)/? FROM poller_float_rrdfiles_not_done',
|
||||||
|
[$threads]));
|
||||||
|
|
||||||
print "There are $threads and $rrdfiles_per_process RRDfiles to process per thread" . PHP_EOL;
|
print "There are $threads and $rrdfiles_per_process RRDfiles to process per thread" . PHP_EOL;
|
||||||
|
|
||||||
@@ -640,9 +703,19 @@ function float_launch_child(int $thread_id, mixed $step, int $start_time, int $e
|
|||||||
|
|
||||||
float_debug(sprintf('Launching Float Data Process Number %s for Type %s', $thread_id, 'child'));
|
float_debug(sprintf('Launching Float Data Process Number %s for Type %s', $thread_id, 'child'));
|
||||||
|
|
||||||
cacti_log(sprintf('NOTE: Launching Float Data Number %s for Type %s', $thread_id, 'child'), false, 'RFLOAT', POLLER_VERBOSITY_MEDIUM);
|
cacti_log(sprintf('NOTE: Launching Float Data Number %s for Type %s',
|
||||||
|
$thread_id,
|
||||||
|
'child'),
|
||||||
|
false,
|
||||||
|
'RFLOAT',
|
||||||
|
POLLER_VERBOSITY_MEDIUM);
|
||||||
|
|
||||||
exec_background($php_binary, CACTI_PATH_CLI . "/float_rrdfiles.php --type=child --child=$thread_id --start=$start_time --end=$end_time" . ($step !== false ? ' --step=' . $step : '') . ($seebug ? ' --debug' : ''));
|
exec_background($php_binary,
|
||||||
|
CACTI_PATH_CLI .
|
||||||
|
"/float_rrdfiles.php --type=child --child=$thread_id --start=$start_time --end=$end_time" .
|
||||||
|
($step !== false ? ' --step=' .
|
||||||
|
$step : '') .
|
||||||
|
($seebug ? ' --debug' : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -722,7 +795,11 @@ function float_kill_running_processes() : void {
|
|||||||
if (cacti_sizeof($processes)) {
|
if (cacti_sizeof($processes)) {
|
||||||
foreach ($processes as $p) {
|
foreach ($processes as $p) {
|
||||||
if (cacti_process_still_running((int) $p['pid'])) {
|
if (cacti_process_still_running((int) $p['pid'])) {
|
||||||
cacti_log(sprintf('WARNING: Killing Cleanup %s PID %d due to another due to signal or overrun.', ucfirst($p['taskname']), $p['pid']), false, 'RFLOAT');
|
cacti_log(sprintf('WARNING: Killing Cleanup %s PID %d due to another due to signal or overrun.',
|
||||||
|
ucfirst($p['taskname']),
|
||||||
|
$p['pid']),
|
||||||
|
false,
|
||||||
|
'RFLOAT');
|
||||||
|
|
||||||
cacti_process_kill((int) $p['pid'], SIGTERM, 'RFLOAT');
|
cacti_process_kill((int) $p['pid'], SIGTERM, 'RFLOAT');
|
||||||
}
|
}
|
||||||
@@ -750,7 +827,8 @@ function display_version() : void {
|
|||||||
function display_help() : void {
|
function display_help() : void {
|
||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL . 'usage: float_rrdfiles.php --start=TS --end=TS [--threads=N --host-id=N --host-template-id=N --graph-template-id=N] [--debug]' . PHP_EOL . PHP_EOL;
|
print PHP_EOL . ('usage: float_rrdfiles.php --start=TS --end=TS [--threads=N ' .
|
||||||
|
'--host-id=N --host-template-id=N --graph-template-id=N] [--debug]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Cacti\'s RRDfile Data Float Tool. This CLI script will float a' . PHP_EOL;
|
print 'Cacti\'s RRDfile Data Float Tool. This CLI script will float a' . PHP_EOL;
|
||||||
print 'range in select Cacti Graphs using the RRDtool dump/import utility.' . PHP_EOL . PHP_EOL;
|
print 'range in select Cacti Graphs using the RRDtool dump/import utility.' . PHP_EOL . PHP_EOL;
|
||||||
|
|||||||
@@ -188,7 +188,9 @@ if ($exists > 0) {
|
|||||||
|
|
||||||
automation_hook_graph_template($host['id'], $graph_template['graph_template_id']);
|
automation_hook_graph_template($host['id'], $graph_template['graph_template_id']);
|
||||||
|
|
||||||
api_plugin_hook_function('add_graph_template_to_host', ['host_id' => $host['id'], 'graph_template_id' => $graph_template['graph_template_id']]);
|
api_plugin_hook_function('add_graph_template_to_host',
|
||||||
|
['host_id' => $host['id'],
|
||||||
|
'graph_template_id' => $graph_template['graph_template_id']]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -223,7 +223,9 @@ function display_version() : void {
|
|||||||
function display_help() : void {
|
function display_help() : void {
|
||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL . 'usage: import_package.php --filename=[filename] [--info] [--remove-orphans] [--replace-svalues] [--with-profile] [--profile-id=N' . PHP_EOL . PHP_EOL;
|
print PHP_EOL . ('usage: import_package.php --filename=[filename] [--info] ' .
|
||||||
|
'[--remove-orphans] [--replace-svalues] [--with-profile] ' .
|
||||||
|
'[--profile-id=N') . PHP_EOL . PHP_EOL;
|
||||||
print 'A utility to allow signed Cacti Packages to be imported from the command line.' . PHP_EOL . PHP_EOL;
|
print 'A utility to allow signed Cacti Packages to be imported from the command line.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Required:' . PHP_EOL;
|
print 'Required:' . PHP_EOL;
|
||||||
|
|||||||
+13
-5
@@ -98,7 +98,10 @@ if (!isset($config['input_whitelist'])) {
|
|||||||
|
|
||||||
if ($audit) {
|
if ($audit) {
|
||||||
if (isset($config['input_whitelist']) && !file_exists($config['input_whitelist'])) {
|
if (isset($config['input_whitelist']) && !file_exists($config['input_whitelist'])) {
|
||||||
print 'ERROR: Data Input Whitelist file \'' . $config['input_whitelist'] . '\' does not exist. Please run with the \'--update\' option.' . PHP_EOL;
|
print 'ERROR: Data Input Whitelist file \'' .
|
||||||
|
$config['input_whitelist'] .
|
||||||
|
'\' does not exist. Please run with the \'--update\' option.' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -110,24 +113,29 @@ if ($audit) {
|
|||||||
|
|
||||||
if ($items) {
|
if ($items) {
|
||||||
print 'Data Input Methods Whitelist Verification' . PHP_EOL . PHP_EOL;
|
print 'Data Input Methods Whitelist Verification' . PHP_EOL . PHP_EOL;
|
||||||
print '------------------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
foreach ($input as $hash => $input_string) {
|
foreach ($input as $hash => $input_string) {
|
||||||
$aud = verify_data_input($hash, $input_string);
|
$aud = verify_data_input($hash, $input_string);
|
||||||
|
|
||||||
if ($aud['status'] == true) {
|
if ($aud['status'] == true) {
|
||||||
print 'ID: ' . $aud['id'] . ', Name: ' . $aud['name'] . ', Status: ' . 'Success' . PHP_EOL;
|
print 'ID: ' . $aud['id'] . ', Name: ' . $aud['name'] . ', Status: ' . 'Success' . PHP_EOL;
|
||||||
print '------------------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL;
|
||||||
print 'Command: ' . $aud['input_string'] . PHP_EOL . 'Whitelist: ' . $input_string . PHP_EOL;
|
print 'Command: ' . $aud['input_string'] . PHP_EOL . 'Whitelist: ' . $input_string . PHP_EOL;
|
||||||
} else {
|
} else {
|
||||||
print 'ID: ' . $aud['id'] . ', Name: ' . $aud['name'] . ', Status: ' . 'Failed' . PHP_EOL;
|
print 'ID: ' . $aud['id'] . ', Name: ' . $aud['name'] . ', Status: ' . 'Failed' . PHP_EOL;
|
||||||
print '------------------------------------------------------------------------------------------------------------' . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL;
|
||||||
print 'Command: ' . $aud['input_string'] . PHP_EOL . 'Whitelist: ' . $input_string . PHP_EOL;
|
print 'Command: ' . $aud['input_string'] . PHP_EOL . 'Whitelist: ' . $input_string . PHP_EOL;
|
||||||
|
|
||||||
$totals++;
|
$totals++;
|
||||||
}
|
}
|
||||||
|
|
||||||
print '------------------------------------------------------------------------------------------------------------' . PHP_EOL . PHP_EOL;
|
print '------------------------------------------------------------------------------------------------------------' .
|
||||||
|
PHP_EOL .
|
||||||
|
PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($totals) {
|
if ($totals) {
|
||||||
|
|||||||
+17
-2
@@ -391,7 +391,12 @@ function set_install_option(array &$options, string $key, string $display_name,
|
|||||||
/**
|
/**
|
||||||
* set_install_multioption - sets sub-options that have multiple key/value combinations with optional prefix
|
* set_install_multioption - sets sub-options that have multiple key/value combinations with optional prefix
|
||||||
*/
|
*/
|
||||||
function set_install_multioption(array &$options, string $key, string $display_name, mixed $value, string $prefix, bool $replace_dots = false) : void {
|
function set_install_multioption(array &$options,
|
||||||
|
string $key,
|
||||||
|
string $display_name,
|
||||||
|
mixed $value,
|
||||||
|
string $prefix,
|
||||||
|
bool $replace_dots = false) : void {
|
||||||
$option_pos = strpos($value, ':');
|
$option_pos = strpos($value, ':');
|
||||||
|
|
||||||
if ($option_pos !== false) {
|
if ($option_pos !== false) {
|
||||||
@@ -458,7 +463,17 @@ function process_install_errors(array $results) : void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print PHP_EOL . 'Unable to continue as ' . $count . ' issue' . ($count == 1 ? '' : 's') . ' in ' . $sections . ' section' . ($sections == 1 ? '' : 's') . ' were found.' . PHP_EOL;
|
print PHP_EOL .
|
||||||
|
'Unable to continue as ' .
|
||||||
|
$count .
|
||||||
|
' issue' .
|
||||||
|
($count == 1 ? '' : 's') .
|
||||||
|
' in ' .
|
||||||
|
$sections .
|
||||||
|
' section' .
|
||||||
|
($sections == 1 ? '' : 's') .
|
||||||
|
' were found.' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
// exit does not execute the caller's finally block.
|
// exit does not execute the caller's finally block.
|
||||||
unregister_process('install', 'master', 0);
|
unregister_process('install', 'master', 0);
|
||||||
|
|||||||
+20
-7
@@ -209,7 +209,8 @@ function get_poller_list() : mixed {
|
|||||||
* @return array List of devices on the poller
|
* @return array List of devices on the poller
|
||||||
*/
|
*/
|
||||||
function get_devices_by_poller(int $poller_id) : mixed {
|
function get_devices_by_poller(int $poller_id) : mixed {
|
||||||
return db_fetch_assoc_prepared('SELECT id, hostname, description, poller_id FROM host WHERE poller_id = ?', [$poller_id]);
|
return db_fetch_assoc_prepared('SELECT id, hostname, description, poller_id FROM host WHERE poller_id = ?',
|
||||||
|
[$poller_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -414,7 +415,11 @@ function migrate_from_host_ids(string $host_ids_string, int $source_poller, int
|
|||||||
if (!$quietMode) {
|
if (!$quietMode) {
|
||||||
print 'Migration Mode: Specific host IDs' . PHP_EOL;
|
print 'Migration Mode: Specific host IDs' . PHP_EOL;
|
||||||
print 'Host IDs to migrate: ' . implode(', ', $host_id_array) . PHP_EOL;
|
print 'Host IDs to migrate: ' . implode(', ', $host_id_array) . PHP_EOL;
|
||||||
print 'This will move ' . count($host_id_array) . " device(s) from any poller to Poller $dest_poller" . PHP_EOL . PHP_EOL;
|
print 'This will move ' .
|
||||||
|
count($host_id_array) .
|
||||||
|
" device(s) from any poller to Poller $dest_poller" .
|
||||||
|
PHP_EOL .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
// Display devices to be migrated
|
// Display devices to be migrated
|
||||||
print 'Devices to be migrated:' . PHP_EOL;
|
print 'Devices to be migrated:' . PHP_EOL;
|
||||||
@@ -423,7 +428,8 @@ function migrate_from_host_ids(string $host_ids_string, int $source_poller, int
|
|||||||
$device = db_fetch_row_prepared('SELECT id, hostname, description, poller_id FROM host WHERE id = ?', [$host_id]);
|
$device = db_fetch_row_prepared('SELECT id, hostname, description, poller_id FROM host WHERE id = ?', [$host_id]);
|
||||||
|
|
||||||
if (!empty($device)) {
|
if (!empty($device)) {
|
||||||
print " ID: {$device['id']} - {$device['hostname']} ({$device['description']}) [Current Poller: {$device['poller_id']}]" . PHP_EOL;
|
print " ID: {$device['id']} - {$device['hostname']} ({$device['description']}) [Current Poller: {$device['poller_id']}]" .
|
||||||
|
PHP_EOL;
|
||||||
} else {
|
} else {
|
||||||
print " ID: $host_id - ERROR: Device not found" . PHP_EOL;
|
print " ID: $host_id - ERROR: Device not found" . PHP_EOL;
|
||||||
}
|
}
|
||||||
@@ -455,7 +461,8 @@ function migrate_from_host_ids(string $host_ids_string, int $source_poller, int
|
|||||||
$success_count++;
|
$success_count++;
|
||||||
|
|
||||||
if (!$quietMode) {
|
if (!$quietMode) {
|
||||||
print "Moved device: {$device['description']} (ID: {$device['id']}) from Poller {$device['poller_id']} to Poller $dest_poller" . PHP_EOL;
|
print "Moved device: {$device['description']} (ID: {$device['id']}) from Poller {$device['poller_id']} to Poller $dest_poller" .
|
||||||
|
PHP_EOL;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$error_count++;
|
$error_count++;
|
||||||
@@ -505,7 +512,8 @@ function display_help() : void {
|
|||||||
print 'Purpose: This script is used to move devices off a given poller to another poller' . PHP_EOL . PHP_EOL;
|
print 'Purpose: This script is used to move devices off a given poller to another poller' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Usage:' . PHP_EOL;
|
print 'Usage:' . PHP_EOL;
|
||||||
print 'php ' . basename(__FILE__) . ' --source-poller=ID --dest-poller=ID [--all | --host-ids=ID1,ID2,...] [--quiet] [--help]' . PHP_EOL . PHP_EOL;
|
print 'php ' . basename(__FILE__) . (' --source-poller=ID --dest-poller=ID [--all | --host-ids=ID1,ID2,...] ' .
|
||||||
|
'[--quiet] [--help]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Required Arguments:' . PHP_EOL;
|
print 'Required Arguments:' . PHP_EOL;
|
||||||
print ' --source-poller=ID Source Poller ID to move devices from' . PHP_EOL;
|
print ' --source-poller=ID Source Poller ID to move devices from' . PHP_EOL;
|
||||||
@@ -513,7 +521,8 @@ function display_help() : void {
|
|||||||
|
|
||||||
print 'Migration Mode (choose exactly one):' . PHP_EOL;
|
print 'Migration Mode (choose exactly one):' . PHP_EOL;
|
||||||
print ' --all Migrate all devices off the source poller' . PHP_EOL;
|
print ' --all Migrate all devices off the source poller' . PHP_EOL;
|
||||||
print ' --host-ids=ID1,ID2,... Migrate specific devices by host ID (single ID or comma-separated list)' . PHP_EOL . PHP_EOL;
|
print (' --host-ids=ID1,ID2,... Migrate specific devices by host ID ' .
|
||||||
|
'(single ID or comma-separated list)') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Optional Arguments:' . PHP_EOL;
|
print 'Optional Arguments:' . PHP_EOL;
|
||||||
print ' --quiet Suppress verbose output (batch mode)' . PHP_EOL;
|
print ' --quiet Suppress verbose output (batch mode)' . PHP_EOL;
|
||||||
@@ -530,7 +539,11 @@ function display_help() : void {
|
|||||||
print ' # Migrate a single device by host ID:' . PHP_EOL;
|
print ' # Migrate a single device by host ID:' . PHP_EOL;
|
||||||
print ' php ' . basename(__FILE__) . ' --source-poller=1 --dest-poller=2 --host-ids=123' . PHP_EOL;
|
print ' php ' . basename(__FILE__) . ' --source-poller=1 --dest-poller=2 --host-ids=123' . PHP_EOL;
|
||||||
print ' # Migrate multiple devices by host IDs:' . PHP_EOL;
|
print ' # Migrate multiple devices by host IDs:' . PHP_EOL;
|
||||||
print ' php ' . basename(__FILE__) . ' --source-poller=1 --dest-poller=2 --host-ids=123,124,125' . PHP_EOL . PHP_EOL;
|
print ' php ' .
|
||||||
|
basename(__FILE__) .
|
||||||
|
' --source-poller=1 --dest-poller=2 --host-ids=123,124,125' .
|
||||||
|
PHP_EOL .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
print 'Note: You must specify exactly one migration option: --all or --host-ids' . PHP_EOL . PHP_EOL;
|
print 'Note: You must specify exactly one migration option: --all or --host-ids' . PHP_EOL . PHP_EOL;
|
||||||
}
|
}
|
||||||
@@ -275,7 +275,8 @@ function display_version() : void {
|
|||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function display_help() : void {
|
function display_help() : void {
|
||||||
print 'usage: plugin_manage.php [--plugin=S] [--install --enable --allperms] [--uninstall ] [--disable]' . PHP_EOL . PHP_EOL;
|
print ('usage: plugin_manage.php [--plugin=S] [--install --enable --allperms] ' .
|
||||||
|
'[--uninstall ] [--disable]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'A utility to install/uninstall a Cacti plugin or plugins' . PHP_EOL . PHP_EOL;
|
print 'A utility to install/uninstall a Cacti plugin or plugins' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,9 @@ if (cacti_sizeof($data_source_list)) {
|
|||||||
|
|
||||||
update_data_source_title_cache($data_source['local_data_id']);
|
update_data_source_title_cache($data_source['local_data_id']);
|
||||||
|
|
||||||
debug("Data Source Rename Done for Data Source '" . addslashes(get_data_source_title($data_source['local_data_id'])) . "'");
|
debug("Data Source Rename Done for Data Source '" .
|
||||||
|
addslashes(get_data_source_title($data_source['local_data_id'])) .
|
||||||
|
"'");
|
||||||
|
|
||||||
$i++;
|
$i++;
|
||||||
}
|
}
|
||||||
@@ -208,7 +210,8 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: poller_data_sources_reapply_names.php --host-id=[id|all][N1,N2,...] [--filter=string] [--debug]' . PHP_EOL . PHP_EOL;
|
print ('usage: poller_data_sources_reapply_names.php ' .
|
||||||
|
'--host-id=[id|all][N1,N2,...] [--filter=string] [--debug]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'A utility that will recalculate Data Source names for the selected Data Templates.' . PHP_EOL . PHP_EOL;
|
print 'A utility that will recalculate Data Source names for the selected Data Templates.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
|
|||||||
@@ -189,7 +189,8 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: poller_graphs_reapply_names.php --host-id=[id|all][N1,N2,...] [--filter=[string] [--debug]' . PHP_EOL . PHP_EOL;
|
print ('usage: poller_graphs_reapply_names.php --host-id=[id|all][N1,N2,...] ' .
|
||||||
|
'[--filter=[string] [--debug]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'A utility to reapply Cacti Graph naming rules to existing Graphs in bulk.' . PHP_EOL . PHP_EOL;
|
print 'A utility to reapply Cacti Graph naming rules to existing Graphs in bulk.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ foreach ($parms as $parameter) {
|
|||||||
break;
|
break;
|
||||||
case '--threads':
|
case '--threads':
|
||||||
if (!is_numeric(trim($value))) {
|
if (!is_numeric(trim($value))) {
|
||||||
print 'ERROR: You must supply a valid Number of Treads or skip this parameter for default value (' . $threads . ')' . PHP_EOL;
|
print ('ERROR: You must supply a valid Number of Treads or skip this ' .
|
||||||
|
'parameter for default value (') . $threads . ')' . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -278,7 +279,12 @@ switch ($type) {
|
|||||||
$sql_where",
|
$sql_where",
|
||||||
$params);
|
$params);
|
||||||
|
|
||||||
cacti_log(sprintf('Child Started Process %s with %d hosts, from: %d', $thread_id, $ds_per_process, ($thread_id - 1) * $ds_per_process), true, 'REINDEX');
|
cacti_log(sprintf('Child Started Process %s with %d hosts, from: %d',
|
||||||
|
$thread_id,
|
||||||
|
$ds_per_process,
|
||||||
|
($thread_id - 1) * $ds_per_process),
|
||||||
|
true,
|
||||||
|
'REINDEX');
|
||||||
|
|
||||||
foreach ($data_queries as $data_query) {
|
foreach ($data_queries as $data_query) {
|
||||||
run_data_query($data_query['host_id'], $data_query['snmp_query_id'], false, $forcerun);
|
run_data_query($data_query['host_id'], $data_query['snmp_query_id'], false, $forcerun);
|
||||||
@@ -338,7 +344,8 @@ function reindex_master_handler(bool $forcerun, int $host_id, int $query_id, str
|
|||||||
|
|
||||||
$ds_per_process = ceil($rows / $threads);
|
$ds_per_process = ceil($rows / $threads);
|
||||||
|
|
||||||
print "There are $rows data queries, $threads threads and $ds_per_process data sources to process per thread" . PHP_EOL;
|
print "There are $rows data queries, $threads threads and $ds_per_process data sources to process per thread" .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
$h_done = 0;
|
$h_done = 0;
|
||||||
|
|
||||||
@@ -385,9 +392,21 @@ function reindex_launch_child(int $thread_id, int $threads) : void {
|
|||||||
|
|
||||||
reindex_debug(sprintf('Launching Reindex hosts Process Number %s for Type %s', $thread_id, 'child'));
|
reindex_debug(sprintf('Launching Reindex hosts Process Number %s for Type %s', $thread_id, 'child'));
|
||||||
|
|
||||||
cacti_log(sprintf('NOTE: Launching Reindex hosts Number %s for Type %s', $thread_id, 'child'), true, 'REINDEX', POLLER_VERBOSITY_MEDIUM);
|
cacti_log(sprintf('NOTE: Launching Reindex hosts Number %s for Type %s',
|
||||||
|
$thread_id,
|
||||||
|
'child'),
|
||||||
|
true,
|
||||||
|
'REINDEX',
|
||||||
|
POLLER_VERBOSITY_MEDIUM);
|
||||||
|
|
||||||
exec_background($php_binary, CACTI_PATH_CLI . "/poller_reindex_hosts.php --type=child --threads=$threads --child=$thread_id " . ($debug ? ' --debug' : '') . ($host_id ? " --id=$host_id" : '') . ($query_id ? " --qid=$query_id" : '') . ($host_descr ? " --host-descr=$host_descr" : '') . ($forcerun ? ' --force' : ''));
|
exec_background($php_binary,
|
||||||
|
CACTI_PATH_CLI .
|
||||||
|
"/poller_reindex_hosts.php --type=child --threads=$threads --child=$thread_id " .
|
||||||
|
($debug ? ' --debug' : '') .
|
||||||
|
($host_id ? " --id=$host_id" : '') .
|
||||||
|
($query_id ? " --qid=$query_id" : '') .
|
||||||
|
($host_descr ? " --host-descr=$host_descr" : '') .
|
||||||
|
($forcerun ? ' --force' : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -467,7 +486,11 @@ function reindex_kill_running_processes() : void {
|
|||||||
if (cacti_sizeof($processes)) {
|
if (cacti_sizeof($processes)) {
|
||||||
foreach ($processes as $p) {
|
foreach ($processes as $p) {
|
||||||
if (cacti_process_still_running((int) $p['pid'])) {
|
if (cacti_process_still_running((int) $p['pid'])) {
|
||||||
cacti_log(sprintf('WARNING: Killing Cleanup %s PID %d due to another due to signal or overrun.', ucfirst($p['taskname']), $p['pid']), false, 'REINDEX');
|
cacti_log(sprintf('WARNING: Killing Cleanup %s PID %d due to another due to signal or overrun.',
|
||||||
|
ucfirst($p['taskname']),
|
||||||
|
$p['pid']),
|
||||||
|
false,
|
||||||
|
'REINDEX');
|
||||||
|
|
||||||
cacti_process_kill((int) $p['pid'], SIGTERM, 'REINDEX');
|
cacti_process_kill((int) $p['pid'], SIGTERM, 'REINDEX');
|
||||||
}
|
}
|
||||||
@@ -502,7 +525,8 @@ function display_help() : void {
|
|||||||
|
|
||||||
print 'Optional:' . PHP_EOL;
|
print 'Optional:' . PHP_EOL;
|
||||||
print ' [--host-descr=[description]] [--debug]' . PHP_EOL . PHP_EOL;
|
print ' [--host-descr=[description]] [--debug]' . PHP_EOL . PHP_EOL;
|
||||||
print '--id=host_id - The host_id to have data queries reindexed or \'all\' to reindex all hosts' . PHP_EOL;
|
print ('--id=host_id - The host_id to have data queries reindexed ' .
|
||||||
|
'or \'all\' to reindex all hosts') . PHP_EOL;
|
||||||
print '--qid=query_id - Only index on a specific data query id; defaults to \'all\'' . PHP_EOL;
|
print '--qid=query_id - Only index on a specific data query id; defaults to \'all\'' . PHP_EOL;
|
||||||
print '--host-descr=description - The host description to filter by (SQL filters acknowledged)' . PHP_EOL;
|
print '--host-descr=description - The host description to filter by (SQL filters acknowledged)' . PHP_EOL;
|
||||||
print '--threads=N - The number of threads to use to repopulate' . PHP_EOL;
|
print '--threads=N - The number of threads to use to repopulate' . PHP_EOL;
|
||||||
|
|||||||
@@ -115,7 +115,8 @@ foreach ($parms as $parameter) {
|
|||||||
break;
|
break;
|
||||||
case '--threads':
|
case '--threads':
|
||||||
if (!is_numeric(trim($value))) {
|
if (!is_numeric(trim($value))) {
|
||||||
print 'ERROR: You must supply a valid Number of Treads or skip this parameter for default value (' . $threads . ')' . PHP_EOL;
|
print ('ERROR: You must supply a valid Number of Treads or skip this ' .
|
||||||
|
'parameter for default value (') . $threads . ')' . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -232,7 +233,10 @@ switch ($type) {
|
|||||||
|
|
||||||
$hosts_per_process = ceil($rows / $threads);
|
$hosts_per_process = ceil($rows / $threads);
|
||||||
|
|
||||||
$sql_where .= ' GROUP BY h.id ORDER BY h.id LIMIT ' . (($thread_id - 1) * $hosts_per_process) . ',' . $hosts_per_process;
|
$sql_where .= ' GROUP BY h.id ORDER BY h.id LIMIT ' .
|
||||||
|
(($thread_id - 1) * $hosts_per_process) .
|
||||||
|
',' .
|
||||||
|
$hosts_per_process;
|
||||||
|
|
||||||
$rows = db_fetch_assoc_prepared("SELECT h.id AS id, COUNT(dl.id) AS dl_count
|
$rows = db_fetch_assoc_prepared("SELECT h.id AS id, COUNT(dl.id) AS dl_count
|
||||||
FROM host AS h
|
FROM host AS h
|
||||||
@@ -241,7 +245,12 @@ switch ($type) {
|
|||||||
WHERE h.disabled='' " . $sql_where,
|
WHERE h.disabled='' " . $sql_where,
|
||||||
$sql_params);
|
$sql_params);
|
||||||
|
|
||||||
cacti_log(sprintf('Child Started Process %s with %d hosts, from: %d', $thread_id, $hosts_per_process, ($thread_id - 1) * $hosts_per_process), true, 'PUSHOUT');
|
cacti_log(sprintf('Child Started Process %s with %d hosts, from: %d',
|
||||||
|
$thread_id,
|
||||||
|
$hosts_per_process,
|
||||||
|
($thread_id - 1) * $hosts_per_process),
|
||||||
|
true,
|
||||||
|
'PUSHOUT');
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
if (!$debug) {
|
if (!$debug) {
|
||||||
@@ -266,7 +275,11 @@ pushout_debug('Polling Ending');
|
|||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
function pushout_master_handler(bool $forcerun, int $host_id, int $host_template_id, int $data_template_id, int $threads) : bool {
|
function pushout_master_handler(bool $forcerun,
|
||||||
|
int $host_id,
|
||||||
|
int $host_template_id,
|
||||||
|
int $data_template_id,
|
||||||
|
int $threads) : bool {
|
||||||
global $type;
|
global $type;
|
||||||
|
|
||||||
$sql_where = '';
|
$sql_where = '';
|
||||||
@@ -343,9 +356,19 @@ function pushout_launch_child(int $thread_id, int $threads) : void {
|
|||||||
|
|
||||||
pushout_debug(sprintf('Launching Rebuild poller cache Process Number %s for Type %s', $thread_id, 'child'));
|
pushout_debug(sprintf('Launching Rebuild poller cache Process Number %s for Type %s', $thread_id, 'child'));
|
||||||
|
|
||||||
cacti_log(sprintf('NOTE: Launching Rebuild poller cache Number %s for Type %s', $thread_id, 'child'), true, 'PUSHOUT', POLLER_VERBOSITY_MEDIUM);
|
cacti_log(sprintf('NOTE: Launching Rebuild poller cache Number %s for Type %s',
|
||||||
|
$thread_id,
|
||||||
|
'child'),
|
||||||
|
true,
|
||||||
|
'PUSHOUT',
|
||||||
|
POLLER_VERBOSITY_MEDIUM);
|
||||||
|
|
||||||
exec_background($php_binary, CACTI_PATH_CLI . "/rebuild_poller_cache.php --type=child --threads=$threads --child=$thread_id " . ($debug ? ' --debug' : '') . ($host_template_id ? " --host-template-id=$host_template_id" : '') . ($data_template_id ? " --data-template-id=$data_template_id" : ''));
|
exec_background($php_binary,
|
||||||
|
CACTI_PATH_CLI .
|
||||||
|
"/rebuild_poller_cache.php --type=child --threads=$threads --child=$thread_id " .
|
||||||
|
($debug ? ' --debug' : '') .
|
||||||
|
($host_template_id ? " --host-template-id=$host_template_id" : '') .
|
||||||
|
($data_template_id ? " --data-template-id=$data_template_id" : ''));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -425,7 +448,11 @@ function pushout_kill_running_processes() : void {
|
|||||||
if (cacti_sizeof($processes)) {
|
if (cacti_sizeof($processes)) {
|
||||||
foreach ($processes as $p) {
|
foreach ($processes as $p) {
|
||||||
if (cacti_process_still_running((int) $p['pid'])) {
|
if (cacti_process_still_running((int) $p['pid'])) {
|
||||||
cacti_log(sprintf('WARNING: Killing Cleanup %s PID %d due to another due to signal or overrun.', ucfirst($p['taskname']), $p['pid']), false, 'PUSHOUT');
|
cacti_log(sprintf('WARNING: Killing Cleanup %s PID %d due to another due to signal or overrun.',
|
||||||
|
ucfirst($p['taskname']),
|
||||||
|
$p['pid']),
|
||||||
|
false,
|
||||||
|
'PUSHOUT');
|
||||||
|
|
||||||
cacti_process_kill((int) $p['pid'], SIGTERM, 'PUSHOUT');
|
cacti_process_kill((int) $p['pid'], SIGTERM, 'PUSHOUT');
|
||||||
}
|
}
|
||||||
@@ -452,7 +479,8 @@ function display_version() : void {
|
|||||||
function display_help() : void {
|
function display_help() : void {
|
||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL . 'usage: rebuild_poller_cache.php [--host-id=N] [--host-template-id=N] [--data-template-id=N] [--debug]' . PHP_EOL . PHP_EOL;
|
print PHP_EOL . ('usage: rebuild_poller_cache.php [--host-id=N] [--host-template-id=N] ' .
|
||||||
|
'[--data-template-id=N] [--debug]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Cacti\'s repopulate poller cache tool. This CLI script will ' . PHP_EOL;
|
print 'Cacti\'s repopulate poller cache tool. This CLI script will ' . PHP_EOL;
|
||||||
print 'repopulate poller cache for all or specified hosts.' . PHP_EOL . PHP_EOL;
|
print 'repopulate poller cache for all or specified hosts.' . PHP_EOL . PHP_EOL;
|
||||||
|
|||||||
@@ -107,7 +107,8 @@ if (!$report && !$remove) {
|
|||||||
$report = true;
|
$report = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
print 'Running Query to find Broken Graphs. This Query may run for some time depending the number of Graph in your System' . PHP_EOL;
|
print ('Running Query to find Broken Graphs. This Query may run for some ' .
|
||||||
|
'time depending the number of Graph in your System') . PHP_EOL;
|
||||||
|
|
||||||
$sql = "SELECT name, graph_template_id, graphs, local_graph_ids
|
$sql = "SELECT name, graph_template_id, graphs, local_graph_ids
|
||||||
FROM (
|
FROM (
|
||||||
|
|||||||
@@ -214,7 +214,14 @@ if (cacti_sizeof($parms)) {
|
|||||||
print "Success - removed device-ids: $ids_confirm" . PHP_EOL;
|
print "Success - removed device-ids: $ids_confirm" . PHP_EOL;
|
||||||
|
|
||||||
foreach ($hosts as $host) {
|
foreach ($hosts as $host) {
|
||||||
cacti_log('Device Removed via remove_device.php - Device ID: ' . $host['id'] . ', Hostname: ' . $host['hostname'] . ', Description: ' . $host['description'], false, 'CLI');
|
cacti_log('Device Removed via remove_device.php - Device ID: ' .
|
||||||
|
$host['id'] .
|
||||||
|
', Hostname: ' .
|
||||||
|
$host['hostname'] .
|
||||||
|
', Description: ' .
|
||||||
|
$host['description'],
|
||||||
|
false,
|
||||||
|
'CLI');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -302,7 +302,8 @@ if ($listGraphTemplates) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($all_option && $all === false && $list === false) {
|
if ($all_option && $all === false && $list === false) {
|
||||||
print 'ERROR: The options specified will remove all graphs. To do this you must use the --all option. Exiting' . PHP_EOL;
|
print ('ERROR: The options specified will remove all graphs. To do this you ' .
|
||||||
|
'must use the --all option. Exiting') . PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -315,7 +316,10 @@ if ($listGraphTemplates) {
|
|||||||
$sql_where");
|
$sql_where");
|
||||||
|
|
||||||
if ($graphs != false && cacti_sizeof($graphs)) {
|
if ($graphs != false && cacti_sizeof($graphs)) {
|
||||||
print 'There are ' . cacti_sizeof($graphs) . ' Graphs to Remove.' . (!$force ? ' Use the --force option to remove these Graphs.' : '');
|
print 'There are ' .
|
||||||
|
cacti_sizeof($graphs) .
|
||||||
|
' Graphs to Remove.' .
|
||||||
|
(!$force ? ' Use the --force option to remove these Graphs.' : '');
|
||||||
|
|
||||||
if ($list) {
|
if ($list) {
|
||||||
print PHP_EOL . "ID\tGraphName" . PHP_EOL;
|
print PHP_EOL . "ID\tGraphName" . PHP_EOL;
|
||||||
|
|||||||
@@ -186,7 +186,8 @@ if ($out_start != '' && !is_numeric($out_start)) {
|
|||||||
$out_start = strtotime($out_start);
|
$out_start = strtotime($out_start);
|
||||||
|
|
||||||
if ($out_start == false) {
|
if ($out_start == false) {
|
||||||
print "ERROR: The outlier start value '$orig_out_start' is invalid. Use either a timestamp or a datetime format." . PHP_EOL;
|
print "ERROR: The outlier start value '$orig_out_start' is invalid. Use either a timestamp or a datetime format." .
|
||||||
|
PHP_EOL;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,7 +197,8 @@ if ($out_end != '' && !is_numeric($out_end)) {
|
|||||||
$out_end = strtotime($out_end);
|
$out_end = strtotime($out_end);
|
||||||
|
|
||||||
if ($out_end == false) {
|
if ($out_end == false) {
|
||||||
print "ERROR: The outlier end value '$orig_out_end' is invalid. Use either a timestamp or a datetime format." . PHP_EOL;
|
print "ERROR: The outlier end value '$orig_out_end' is invalid. Use either a timestamp or a datetime format." .
|
||||||
|
PHP_EOL;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,7 +265,8 @@ function display_help() : void {
|
|||||||
print ' --rrdfile=F - The path to the RRDfile that will be de-spiked.' . PHP_EOL . PHP_EOL;
|
print ' --rrdfile=F - The path to the RRDfile that will be de-spiked.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Optional:' . PHP_EOL;
|
print 'Optional:' . PHP_EOL;
|
||||||
print ' --method - The spike removal method to use. Options are stddev|variance|fill|float|absolute' . PHP_EOL;
|
print (' --method - The spike removal method to use. Options are ' .
|
||||||
|
'stddev|variance|fill|float|absolute') . PHP_EOL;
|
||||||
print ' --avgnan - The spike replacement method to use. Options are last|avg|nan' . PHP_EOL;
|
print ' --avgnan - The spike replacement method to use. Options are last|avg|nan' . PHP_EOL;
|
||||||
print ' --stddev - The number of standard deviations +/- allowed' . PHP_EOL;
|
print ' --stddev - The number of standard deviations +/- allowed' . PHP_EOL;
|
||||||
print ' --percent - The sample to sample percentage variation allowed' . PHP_EOL;
|
print ' --percent - The sample to sample percentage variation allowed' . PHP_EOL;
|
||||||
|
|||||||
@@ -196,7 +196,8 @@ function display_help() : void {
|
|||||||
print 'A utility to Re-order Cacti Data Queries for a Device or system in batch mode.' . PHP_EOL . PHP_EOL;
|
print 'A utility to Re-order Cacti Data Queries for a Device or system in batch mode.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Required:' . PHP_EOL;
|
print 'Required:' . PHP_EOL;
|
||||||
print " --qid=query_id - Only index on a specific data query id; or 'all' to reindex all data query id" . PHP_EOL . PHP_EOL;
|
print (" --qid=query_id - Only index on a specific data query id; or 'all' " .
|
||||||
|
'to reindex all data query id') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Optional:' . PHP_EOL;
|
print 'Optional:' . PHP_EOL;
|
||||||
print " --host-id=N - The Device id to be reindexed; defaults to 'all' to reindex all Devices." . PHP_EOL;
|
print " --host-id=N - The Device id to be reindexed; defaults to 'all' to reindex all Devices." . PHP_EOL;
|
||||||
|
|||||||
+71
-24
@@ -136,10 +136,13 @@ print_separator(true);
|
|||||||
if ($total_errors == 0 && $total_repairs == 0) { // @phpstan-ignore booleanAnd.alwaysTrue
|
if ($total_errors == 0 && $total_repairs == 0) { // @phpstan-ignore booleanAnd.alwaysTrue
|
||||||
printf('NOTE: Found 0 Cacti database issues to repair.' . PHP_EOL . PHP_EOL);
|
printf('NOTE: Found 0 Cacti database issues to repair.' . PHP_EOL . PHP_EOL);
|
||||||
} elseif (!$force) {
|
} elseif (!$force) {
|
||||||
printf('WARNING: Found %s problems in your Cacti database and automatically repaired %s of them.' . PHP_EOL, $total_errors, $total_repairs);
|
printf('WARNING: Found %s problems in your Cacti database and automatically repaired %s of them.' . PHP_EOL,
|
||||||
|
$total_errors,
|
||||||
|
$total_repairs);
|
||||||
printf('WARNING: Using the \'--force\' option will either repair, remove or ignore any additional issues' . PHP_EOL);
|
printf('WARNING: Using the \'--force\' option will either repair, remove or ignore any additional issues' . PHP_EOL);
|
||||||
printf('WARNING: if they can not be repaired.' . PHP_EOL . PHP_EOL);
|
printf('WARNING: if they can not be repaired.' . PHP_EOL . PHP_EOL);
|
||||||
printf('WARNING: Because these changes can not be reversed, make sure you make a Cacti backup first.' . PHP_EOL . PHP_EOL);
|
printf(('WARNING: Because these changes can not be reversed, make sure you ' .
|
||||||
|
'make a Cacti backup first.') . PHP_EOL . PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf('WARNING: Found %s and repaired %s Cacti database issues.' . PHP_EOL . PHP_EOL, $total_errors, $total_repairs);
|
printf('WARNING: Found %s and repaired %s Cacti database issues.' . PHP_EOL . PHP_EOL, $total_errors, $total_repairs);
|
||||||
}
|
}
|
||||||
@@ -182,7 +185,8 @@ function table_structural_repair() : void {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Skipping table physical repair' . PHP_EOL);
|
printf('NOTE: Skipping table physical repair' . PHP_EOL);
|
||||||
printf('NOTE: %s Cacti base tables would be checked/repaired if using --tables option.' . PHP_EOL, cacti_sizeof($base_tables));
|
printf('NOTE: %s Cacti base tables would be checked/repaired if using --tables option.' . PHP_EOL,
|
||||||
|
cacti_sizeof($base_tables));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +435,10 @@ function detailed_checks() : void {
|
|||||||
$total_repairs += $fixes;
|
$total_repairs += $fixes;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found ' . ($force ? 'and repaired ' : '') . "$rows invalid GPRINT Preset rows in Graph Templates." . PHP_EOL);
|
printf('NOTE: Found ' .
|
||||||
|
($force ? 'and repaired ' : '') .
|
||||||
|
"$rows invalid GPRINT Preset rows in Graph Templates." .
|
||||||
|
PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found 0 invalid Cacti GPRINT Presets.' . PHP_EOL);
|
printf('NOTE: Found 0 invalid Cacti GPRINT Presets.' . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -459,7 +466,10 @@ function detailed_checks() : void {
|
|||||||
$fixes = 0;
|
$fixes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found ' . ($force ? 'and repaired ' : '') . "$fixes of $rows invalid CDEFs in Graph Templates." . PHP_EOL);
|
printf('NOTE: Found ' .
|
||||||
|
($force ? 'and repaired ' : '') .
|
||||||
|
"$fixes of $rows invalid CDEFs in Graph Templates." .
|
||||||
|
PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found 0 invalid Cacti CDEFs.' . PHP_EOL);
|
printf('NOTE: Found 0 invalid Cacti CDEFs.' . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -468,21 +478,29 @@ function detailed_checks() : void {
|
|||||||
|
|
||||||
$cdef_references = [
|
$cdef_references = [
|
||||||
[
|
[
|
||||||
'rows' => db_fetch_cell('SELECT COUNT(*) FROM graph_templates_item AS source LEFT JOIN cdef ON source.cdef_id = cdef.id WHERE source.cdef_id > 0 AND cdef.id IS NULL'),
|
'rows' => db_fetch_cell('SELECT COUNT(*) FROM graph_templates_item AS source LEFT JOIN cdef ON ' .
|
||||||
|
'source.cdef_id = cdef.id WHERE source.cdef_id > 0 AND cdef.id IS NULL'),
|
||||||
'fix' => static function (): void {
|
'fix' => static function (): void {
|
||||||
db_execute('UPDATE graph_templates_item SET cdef_id = 0 WHERE cdef_id > 0 AND cdef_id NOT IN (SELECT id FROM cdef)');
|
db_execute('UPDATE graph_templates_item SET cdef_id = 0 WHERE cdef_id > 0 AND ' .
|
||||||
|
'cdef_id NOT IN (SELECT id FROM cdef)');
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'rows' => db_fetch_cell('SELECT COUNT(*) FROM aggregate_graph_templates_item AS source LEFT JOIN cdef ON source.cdef_id = cdef.id WHERE source.cdef_id > 0 AND cdef.id IS NULL'),
|
'rows' => db_fetch_cell('SELECT COUNT(*) FROM aggregate_graph_templates_item AS source LEFT ' .
|
||||||
|
'JOIN cdef ON source.cdef_id = cdef.id WHERE source.cdef_id > 0 AND ' .
|
||||||
|
'cdef.id IS NULL'),
|
||||||
'fix' => static function (): void {
|
'fix' => static function (): void {
|
||||||
db_execute("UPDATE aggregate_graph_templates_item SET cdef_id = 0, t_cdef_id = '' WHERE cdef_id > 0 AND cdef_id NOT IN (SELECT id FROM cdef)");
|
db_execute("UPDATE aggregate_graph_templates_item SET cdef_id = 0, t_cdef_id = '' " .
|
||||||
|
'WHERE cdef_id > 0 AND cdef_id NOT IN (SELECT id FROM cdef)');
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'rows' => db_fetch_cell('SELECT COUNT(*) FROM aggregate_graphs_graph_item AS source LEFT JOIN cdef ON source.cdef_id = cdef.id WHERE source.cdef_id > 0 AND cdef.id IS NULL'),
|
'rows' => db_fetch_cell('SELECT COUNT(*) FROM aggregate_graphs_graph_item AS source LEFT JOIN ' .
|
||||||
|
'cdef ON source.cdef_id = cdef.id WHERE source.cdef_id > 0 AND cdef.id ' .
|
||||||
|
'IS NULL'),
|
||||||
'fix' => static function (): void {
|
'fix' => static function (): void {
|
||||||
db_execute("UPDATE aggregate_graphs_graph_item SET cdef_id = 0, t_cdef_id = '' WHERE cdef_id > 0 AND cdef_id NOT IN (SELECT id FROM cdef)");
|
db_execute("UPDATE aggregate_graphs_graph_item SET cdef_id = 0, t_cdef_id = '' " .
|
||||||
|
'WHERE cdef_id > 0 AND cdef_id NOT IN (SELECT id FROM cdef)');
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
@@ -504,7 +522,8 @@ function detailed_checks() : void {
|
|||||||
$total_repairs += $fixed_references;
|
$total_repairs += $fixed_references;
|
||||||
|
|
||||||
if ($force) {
|
if ($force) {
|
||||||
printf("NOTE: Found and repaired $fixed_references of $invalid_references graph item references to missing CDEFs." . PHP_EOL);
|
printf("NOTE: Found and repaired $fixed_references of $invalid_references graph item references to missing CDEFs." .
|
||||||
|
PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf("NOTE: Found $invalid_references graph item references to missing CDEFs." . PHP_EOL);
|
printf("NOTE: Found $invalid_references graph item references to missing CDEFs." . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -532,7 +551,10 @@ function detailed_checks() : void {
|
|||||||
$fixes = 0;
|
$fixes = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found ' . ($force ? 'and repaired ' : '') . "$fixes of $rows invalid Data Inputs in Data Templates." . PHP_EOL);
|
printf('NOTE: Found ' .
|
||||||
|
($force ? 'and repaired ' : '') .
|
||||||
|
"$fixes of $rows invalid Data Inputs in Data Templates." .
|
||||||
|
PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found 0 invalid Cacti Data Inputs.' . PHP_EOL);
|
printf('NOTE: Found 0 invalid Cacti Data Inputs.' . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -585,7 +607,12 @@ function detailed_checks() : void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found ' . ($force ? 'and repaired ' : '') . '%s Graphs from %s Graph Templates that had invalid item counts.' . PHP_EOL, $total_graphs, cacti_sizeof($rows));
|
printf('NOTE: Found ' .
|
||||||
|
($force ? 'and repaired ' : '') .
|
||||||
|
'%s Graphs from %s Graph Templates that had invalid item counts.' .
|
||||||
|
PHP_EOL,
|
||||||
|
$total_graphs,
|
||||||
|
cacti_sizeof($rows));
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found 0 Graph Templates whose Graphs had incorrect item counts.' . PHP_EOL);
|
printf('NOTE: Found 0 Graph Templates whose Graphs had incorrect item counts.' . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -611,7 +638,10 @@ function detailed_checks() : void {
|
|||||||
update_replication_crc(0, 'poller_replicate_data_input_fields_crc');
|
update_replication_crc(0, 'poller_replicate_data_input_fields_crc');
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found ' . ($force ? 'and repaired ' : '') . "$rows invalid Data Input fields in Data Templates." . PHP_EOL);
|
printf('NOTE: Found ' .
|
||||||
|
($force ? 'and repaired ' : '') .
|
||||||
|
"$rows invalid Data Input fields in Data Templates." .
|
||||||
|
PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found 0 invalid Cacti Data Input fields.' . PHP_EOL);
|
printf('NOTE: Found 0 invalid Cacti Data Input fields.' . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -635,7 +665,10 @@ function detailed_checks() : void {
|
|||||||
WHERE data_input_data.data_template_data_id NOT IN (SELECT id FROM data_template_data)');
|
WHERE data_input_data.data_template_data_id NOT IN (SELECT id FROM data_template_data)');
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found ' . ($force ? 'and repaired ' : '') . "$rows invalid Data Input Data rows in Data Templates" . PHP_EOL);
|
printf('NOTE: Found ' .
|
||||||
|
($force ? 'and repaired ' : '') .
|
||||||
|
"$rows invalid Data Input Data rows in Data Templates" .
|
||||||
|
PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found 0 invalid Cacti Data Input Data rows (Pass 1).' . PHP_EOL);
|
printf('NOTE: Found 0 invalid Cacti Data Input Data rows (Pass 1).' . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -658,7 +691,10 @@ function detailed_checks() : void {
|
|||||||
WHERE data_input_data.data_input_field_id NOT IN (SELECT id FROM data_input_fields)');
|
WHERE data_input_data.data_input_field_id NOT IN (SELECT id FROM data_input_fields)');
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found ' . ($force ? 'and repaired ' : '') . "$rows invalid Data Input Data rows based upon field mappings in Data Templates." . PHP_EOL);
|
printf('NOTE: Found ' .
|
||||||
|
($force ? 'and repaired ' : '') .
|
||||||
|
"$rows invalid Data Input Data rows based upon field mappings in Data Templates." .
|
||||||
|
PHP_EOL);
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found 0 invalid Cacti Data Input Data rows (Pass 2).' . PHP_EOL);
|
printf('NOTE: Found 0 invalid Cacti Data Input Data rows (Pass 2).' . PHP_EOL);
|
||||||
}
|
}
|
||||||
@@ -762,7 +798,9 @@ function snmp_repairs() : void {
|
|||||||
|
|
||||||
if (cacti_sizeof($errors)) {
|
if (cacti_sizeof($errors)) {
|
||||||
if ($force) {
|
if ($force) {
|
||||||
printf('NOTE: Found and repaired %s Device SNMP issues in %s Devices.' . PHP_EOL, $snmp_errors, cacti_sizeof($errors));
|
printf('NOTE: Found and repaired %s Device SNMP issues in %s Devices.' . PHP_EOL,
|
||||||
|
$snmp_errors,
|
||||||
|
cacti_sizeof($errors));
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Not repairing %s Device SNMP issues in %s Devices.' . PHP_EOL, $snmp_errors, cacti_sizeof($errors));
|
printf('NOTE: Not repairing %s Device SNMP issues in %s Devices.' . PHP_EOL, $snmp_errors, cacti_sizeof($errors));
|
||||||
}
|
}
|
||||||
@@ -863,7 +901,9 @@ function snmp_index_repairs() : void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
printf('NOTE: Found and repaired %s of %s Data Sources entries with invalid Device information.' . PHP_EOL, $fixes, cacti_sizeof($entries));
|
printf('NOTE: Found and repaired %s of %s Data Sources entries with invalid Device information.' . PHP_EOL,
|
||||||
|
$fixes,
|
||||||
|
cacti_sizeof($entries));
|
||||||
|
|
||||||
$total_errors += $fixes;
|
$total_errors += $fixes;
|
||||||
$total_repairs += $fixes;
|
$total_repairs += $fixes;
|
||||||
@@ -955,7 +995,8 @@ function snmp_index_repairs() : void {
|
|||||||
$total_errors += cacti_sizeof($broken_data_rows);
|
$total_errors += cacti_sizeof($broken_data_rows);
|
||||||
|
|
||||||
if ($force) {
|
if ($force) {
|
||||||
printf('NOTE: Attempting to repair %s Data Query indexes from other Cacti tables.' . PHP_EOL, $broken_local_data_ids);
|
printf('NOTE: Attempting to repair %s Data Query indexes from other Cacti tables.' . PHP_EOL,
|
||||||
|
$broken_local_data_ids);
|
||||||
|
|
||||||
$fixes = 0;
|
$fixes = 0;
|
||||||
|
|
||||||
@@ -1047,9 +1088,12 @@ function snmp_index_repairs() : void {
|
|||||||
|
|
||||||
$total_repairs += $fixes;
|
$total_repairs += $fixes;
|
||||||
|
|
||||||
printf('NOTE: Found and repaired %s of %s Data Query Index entries in (Pass 1).' . PHP_EOL, $fixes, cacti_sizeof($broken_data_rows));
|
printf('NOTE: Found and repaired %s of %s Data Query Index entries in (Pass 1).' . PHP_EOL,
|
||||||
|
$fixes,
|
||||||
|
cacti_sizeof($broken_data_rows));
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Skipping attempt to repair %s Data Query indexes in (Pass 1).' . PHP_EOL, cacti_sizeof($broken_data_rows));
|
printf('NOTE: Skipping attempt to repair %s Data Query indexes in (Pass 1).' . PHP_EOL,
|
||||||
|
cacti_sizeof($broken_data_rows));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Found no damaged Data Query indexes in (Pass 1).' . PHP_EOL);
|
printf('NOTE: Found no damaged Data Query indexes in (Pass 1).' . PHP_EOL);
|
||||||
@@ -1218,7 +1262,8 @@ function snmp_index_repairs() : void {
|
|||||||
$total_errors += cacti_sizeof($local_data_ids);
|
$total_errors += cacti_sizeof($local_data_ids);
|
||||||
|
|
||||||
if (cacti_sizeof($local_data_ids)) {
|
if (cacti_sizeof($local_data_ids)) {
|
||||||
printf('NOTE: Found %s Devices with orphaned Data Sources that may not be orphaned.' . PHP_EOL, cacti_sizeof($local_data_ids));
|
printf('NOTE: Found %s Devices with orphaned Data Sources that may not be orphaned.' . PHP_EOL,
|
||||||
|
cacti_sizeof($local_data_ids));
|
||||||
|
|
||||||
if ($force) {
|
if ($force) {
|
||||||
printf('NOTE: Attempting to confirm and repair Data Sources are in fact not orphaned.' . PHP_EOL);
|
printf('NOTE: Attempting to confirm and repair Data Sources are in fact not orphaned.' . PHP_EOL);
|
||||||
@@ -1249,7 +1294,9 @@ function snmp_index_repairs() : void {
|
|||||||
|
|
||||||
$total_repairs += $fixes;
|
$total_repairs += $fixes;
|
||||||
|
|
||||||
printf('NOTE: Found and repaired %s of %s Data Sources with invalid orphan status.' . PHP_EOL, $fixes, cacti_sizeof($local_data_ids));
|
printf('NOTE: Found and repaired %s of %s Data Sources with invalid orphan status.' . PHP_EOL,
|
||||||
|
$fixes,
|
||||||
|
cacti_sizeof($local_data_ids));
|
||||||
} else {
|
} else {
|
||||||
printf('NOTE: Skipping attempt to confirm and repair Data Sources orphan status.' . PHP_EOL);
|
printf('NOTE: Skipping attempt to confirm and repair Data Sources orphan status.' . PHP_EOL);
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-2
@@ -154,7 +154,10 @@ if (cacti_sizeof($graph)) {
|
|||||||
$task_item_id = 0;
|
$task_item_id = 0;
|
||||||
|
|
||||||
// Get datasource for supplied data template for current host
|
// Get datasource for supplied data template for current host
|
||||||
$ds = db_fetch_assoc('SELECT * FROM data_local where host_id=' . $g['host_id'] . ' and data_template_id=' . $data_template_id);
|
$ds = db_fetch_assoc('SELECT * FROM data_local where host_id=' .
|
||||||
|
$g['host_id'] .
|
||||||
|
' and data_template_id=' .
|
||||||
|
$data_template_id);
|
||||||
|
|
||||||
if (!cacti_sizeof($ds)) {
|
if (!cacti_sizeof($ds)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -216,7 +219,17 @@ if (cacti_sizeof($graph)) {
|
|||||||
', Graph Item ' . implode(',',$graph_templates_item) .
|
', Graph Item ' . implode(',',$graph_templates_item) .
|
||||||
', Task Item ID ' . implode(',',$task_item_id) . '->' . $rrd_data[0]['id'] . PHP_EOL;
|
', Task Item ID ' . implode(',',$task_item_id) . '->' . $rrd_data[0]['id'] . PHP_EOL;
|
||||||
|
|
||||||
$query = 'UPDATE graph_templates_item SET task_item_id =' . $rrd_data[0]['id'] . ' WHERE task_item_id != ' . $rrd_data[0]['id'] . ' AND graph_template_id = ' . $graph_template_id . ' AND local_graph_id=' . $g['id'] . ' AND id IN (' . implode(',', $graph_templates_item) . ')';
|
$query = 'UPDATE graph_templates_item SET task_item_id =' .
|
||||||
|
$rrd_data[0]['id'] .
|
||||||
|
' WHERE task_item_id != ' .
|
||||||
|
$rrd_data[0]['id'] .
|
||||||
|
' AND graph_template_id = ' .
|
||||||
|
$graph_template_id .
|
||||||
|
' AND local_graph_id=' .
|
||||||
|
$g['id'] .
|
||||||
|
' AND id IN (' .
|
||||||
|
implode(',',
|
||||||
|
$graph_templates_item) . ')';
|
||||||
|
|
||||||
if ($show_sql) {
|
if ($show_sql) {
|
||||||
print $query . ';' . PHP_EOL;
|
print $query . ';' . PHP_EOL;
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ if ($execute) {
|
|||||||
print 'NOTE: Performing Check of Data Templates' . PHP_EOL;
|
print 'NOTE: Performing Check of Data Templates' . PHP_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
$damaged_template_ids = db_fetch_assoc("SELECT DISTINCT data_template_id FROM data_template_rrd WHERE hash='' AND local_data_id=0");
|
$damaged_template_ids = db_fetch_assoc("SELECT DISTINCT data_template_id FROM data_template_rrd WHERE hash='' " .
|
||||||
|
'AND local_data_id=0');
|
||||||
|
|
||||||
if (cacti_sizeof($damaged_template_ids)) {
|
if (cacti_sizeof($damaged_template_ids)) {
|
||||||
foreach ($damaged_template_ids as $id) {
|
foreach ($damaged_template_ids as $id) {
|
||||||
|
|||||||
+29
-9
@@ -436,7 +436,10 @@ if ($scanned_directory['folders']) {
|
|||||||
if (isset($tmp_ds[$defined_ds_name])) {
|
if (isset($tmp_ds[$defined_ds_name])) {
|
||||||
$tmp_ds_rrd = $tmp_ds[$defined_ds_name];
|
$tmp_ds_rrd = $tmp_ds[$defined_ds_name];
|
||||||
|
|
||||||
if ($tmp_ds_rrd['type'] == $defined_ds_type && $tmp_ds_rrd['minimal_heartbeat'] == $defined_min_heartbeat && $tmp_ds_rrd['min'] == $defined_minimum && $tmp_ds_rrd['max'] == $defined_maximum) {
|
if ($tmp_ds_rrd['type'] == $defined_ds_type &&
|
||||||
|
$tmp_ds_rrd['minimal_heartbeat'] == $defined_min_heartbeat &&
|
||||||
|
$tmp_ds_rrd['min'] == $defined_minimum &&
|
||||||
|
$tmp_ds_rrd['max'] == $defined_maximum) {
|
||||||
$found = true;
|
$found = true;
|
||||||
} else {
|
} else {
|
||||||
$ds_mismatch = true;
|
$ds_mismatch = true;
|
||||||
@@ -520,7 +523,10 @@ if ($scanned_directory['folders']) {
|
|||||||
$defined_ppr = $data_template__rra_settings['steps'];
|
$defined_ppr = $data_template__rra_settings['steps'];
|
||||||
|
|
||||||
foreach ($tmp_rras as $tmp_rra) {
|
foreach ($tmp_rras as $tmp_rra) {
|
||||||
if ($tmp_rra['cf'] == $defined_cf && $tmp_rra['rows'] == $defined_rows && $tmp_rra['xff'] == $defined_xff && $tmp_rra['pdp_per_row'] == $defined_ppr) {
|
if ($tmp_rra['cf'] == $defined_cf &&
|
||||||
|
$tmp_rra['rows'] == $defined_rows &&
|
||||||
|
$tmp_rra['xff'] == $defined_xff &&
|
||||||
|
$tmp_rra['pdp_per_row'] == $defined_ppr) {
|
||||||
$found = true;
|
$found = true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -682,13 +688,17 @@ if ($scanned_directory['folders']) {
|
|||||||
|
|
||||||
foreach ($rra_timespans[$defined_cf] as $g_rra_index => $g_rra_settings) {
|
foreach ($rra_timespans[$defined_cf] as $g_rra_index => $g_rra_settings) {
|
||||||
if ($g_rra_settings['step'] > $defined_step) {
|
if ($g_rra_settings['step'] > $defined_step) {
|
||||||
if (($timestamp > $g_rra_settings['start']) && ($timestamp <= $g_rra_settings['end']) && ($g_rra_settings['step'] <= $step)) {
|
if (($timestamp > $g_rra_settings['start']) &&
|
||||||
|
($timestamp <= $g_rra_settings['end']) &&
|
||||||
|
($g_rra_settings['step'] <= $step)) {
|
||||||
$consolidation_required = false;
|
$consolidation_required = false;
|
||||||
$step = $g_rra_settings['step'];
|
$step = $g_rra_settings['step'];
|
||||||
$selected_archive_index = $g_rra_index;
|
$selected_archive_index = $g_rra_index;
|
||||||
}
|
}
|
||||||
} elseif ($g_rra_settings['step'] < $defined_step) {
|
} elseif ($g_rra_settings['step'] < $defined_step) {
|
||||||
if ((($timestamp - $defined_step) >= $g_rra_settings['start']) && ($timestamp <= $g_rra_settings['end']) && ($g_rra_settings['step'] <= $step)) {
|
if ((($timestamp - $defined_step) >= $g_rra_settings['start']) &&
|
||||||
|
($timestamp <= $g_rra_settings['end']) &&
|
||||||
|
($g_rra_settings['step'] <= $step)) {
|
||||||
$consolidation_required = true;
|
$consolidation_required = true;
|
||||||
$step = $g_rra_settings['step'];
|
$step = $g_rra_settings['step'];
|
||||||
$selected_archive_index = $g_rra_index;
|
$selected_archive_index = $g_rra_index;
|
||||||
@@ -706,7 +716,9 @@ if ($scanned_directory['folders']) {
|
|||||||
|
|
||||||
// There's no data available we could reuse. Fill these entries with NaNs and jump to the next one
|
// There's no data available we could reuse. Fill these entries with NaNs and jump to the next one
|
||||||
if ($selected_archive_index === false) {
|
if ($selected_archive_index === false) {
|
||||||
$rrd_new_body .= "\t\t\t<!-- " . date('Y-m-d H:i:s ', ($timestamp)) . 'GMT / ' . ($timestamp) . ' --> <row><v>' . (is_array($row_copy_fake) ? implode('</v><v>', $row_copy_fake) : $row_copy_fake) . '</v></row>' . PHP_EOL;
|
$rrd_new_body .= "\t\t\t<!-- " . date('Y-m-d H:i:s ',
|
||||||
|
($timestamp)) . 'GMT / ' . ($timestamp) . ' --> <row><v>' . (is_array($row_copy_fake) ? implode('</v><v>',
|
||||||
|
$row_copy_fake) : $row_copy_fake) . '</v></row>' . PHP_EOL;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -730,7 +742,9 @@ if ($scanned_directory['folders']) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$rrd_new_body .= "\t\t\t<!-- " . date('Y-m-d H:i:s ', ($timestamp)) . 'GMT / ' . ($timestamp) . ' --> <row><v>' . (is_array($row_copy) ? implode('</v><v>', $row_copy) : $row_copy) . '</v></row>' . PHP_EOL;
|
$rrd_new_body .= "\t\t\t<!-- " . date('Y-m-d H:i:s ',
|
||||||
|
($timestamp)) . 'GMT / ' . ($timestamp) . ' --> <row><v>' . (is_array($row_copy) ? implode('</v><v>',
|
||||||
|
$row_copy) : $row_copy) . '</v></row>' . PHP_EOL;
|
||||||
} else {
|
} else {
|
||||||
f_notify(false, "\033[0;31m[FAILED]\033[0m");
|
f_notify(false, "\033[0;31m[FAILED]\033[0m");
|
||||||
print_r($rra_timespans);
|
print_r($rra_timespans);
|
||||||
@@ -782,7 +796,10 @@ if ($scanned_directory['folders']) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$consolidated_ds_values[$ds_index] = preg_replace('/(e[+-])(\d)$/', '${1}0$2', sprintf('%.10e', $consolidated_value));
|
$consolidated_ds_values[$ds_index] = preg_replace('/(e[+-])(\d)$/',
|
||||||
|
'${1}0$2',
|
||||||
|
sprintf('%.10e',
|
||||||
|
$consolidated_value));
|
||||||
} else {
|
} else {
|
||||||
$consolidated_ds_values[$ds_index] = 'NaN';
|
$consolidated_ds_values[$ds_index] = 'NaN';
|
||||||
}
|
}
|
||||||
@@ -832,7 +849,9 @@ if ($scanned_directory['folders']) {
|
|||||||
unset($consolidated_ds_values[$ds_superfluous_id]);
|
unset($consolidated_ds_values[$ds_superfluous_id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$rrd_new_body .= "\t\t\t<!-- " . date('Y-m-d H:i:s ', ($timestamp)) . 'GMT / ' . ($timestamp) . ' --> <row><v>' . implode('</v><v>', $consolidated_ds_values) . '</v></row>' . PHP_EOL;
|
$rrd_new_body .= "\t\t\t<!-- " . date('Y-m-d H:i:s ',
|
||||||
|
($timestamp)) . 'GMT / ' . ($timestamp) . ' --> <row><v>' . implode('</v><v>',
|
||||||
|
$consolidated_ds_values) . '</v></row>' . PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,7 +892,8 @@ if ($scanned_directory['folders']) {
|
|||||||
|
|
||||||
// Use RRDtool to verify if XML structure is valid
|
// Use RRDtool to verify if XML structure is valid
|
||||||
f_notify('RRDtool Restore');
|
f_notify('RRDtool Restore');
|
||||||
$file_restore = rrdtool_pipe_execute(' restore -r -f ' . $tmp_xml_file . ' ' . $tmp_rrd_file . "\r\n", $rrdtool_pipes);
|
$file_restore = rrdtool_pipe_execute(' restore -r -f ' . $tmp_xml_file . ' ' . $tmp_rrd_file . "\r\n",
|
||||||
|
$rrdtool_pipes);
|
||||||
|
|
||||||
if (str_contains($file_restore, 'ERROR')) {
|
if (str_contains($file_restore, 'ERROR')) {
|
||||||
f_notify(false, "\033[0;31m[FAILED]\033[0m");
|
f_notify(false, "\033[0;31m[FAILED]\033[0m");
|
||||||
|
|||||||
+4
-1
@@ -276,7 +276,10 @@ if (strlen((string) $response)) {
|
|||||||
$response_array = explode(' ', (string) $response);
|
$response_array = explode(' ', (string) $response);
|
||||||
print 'NOTE: Using ' . $response_array[0] . ' Version ' . $response_array[1] . PHP_EOL;
|
print 'NOTE: Using ' . $response_array[0] . ' Version ' . $response_array[1] . PHP_EOL;
|
||||||
} else {
|
} else {
|
||||||
print 'FATAL: RRDTool not found in configuration or path.' . PHP_EOL . 'Please insure RRDTool can be found using one of these methods!' . PHP_EOL;
|
print 'FATAL: RRDTool not found in configuration or path.' .
|
||||||
|
PHP_EOL .
|
||||||
|
'Please insure RRDTool can be found using one of these methods!' .
|
||||||
|
PHP_EOL;
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-2
@@ -192,9 +192,17 @@ function sqltable_to_php(string $table, bool $create, string $plugin = '') : str
|
|||||||
if (!empty($keys)) {
|
if (!empty($keys)) {
|
||||||
foreach ($keys as $n => $k) {
|
foreach ($keys as $n => $k) {
|
||||||
if ($plugin != '') {
|
if ($plugin != '') {
|
||||||
$text .= "\$data['keys'][] = array('name' => '$n', " . (isset($unique_keys[$n]) ? "'unique' => true, " : '') . "'columns' => '" . implode('`,`', $k) . "');" . PHP_EOL;
|
$text .= "\$data['keys'][] = array('name' => '$n', " .
|
||||||
|
(isset($unique_keys[$n]) ? "'unique' => true, " : '') .
|
||||||
|
"'columns' => '" .
|
||||||
|
implode('`,`',
|
||||||
|
$k) . "');" . PHP_EOL;
|
||||||
} else {
|
} else {
|
||||||
$text .= "\$data['keys'][] = array('name' => '$n', " . (isset($unique_keys[$n]) ? "'unique' => true, " : '') . "'columns' => array('" . implode("','", $k) . "'));" . PHP_EOL;
|
$text .= "\$data['keys'][] = array('name' => '$n', " .
|
||||||
|
(isset($unique_keys[$n]) ? "'unique' => true, " : '') .
|
||||||
|
"'columns' => array('" .
|
||||||
|
implode("','",
|
||||||
|
$k) . "'));" . PHP_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,14 +107,16 @@ if ($host_id !== false && ($host_id <= 0 || !is_numeric($host_id))) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($host_template_id !== false && ($host_template_id <= 0 || !is_numeric($host_template_id))) {
|
if ($host_template_id !== false && ($host_template_id <= 0 || !is_numeric($host_template_id))) {
|
||||||
print PHP_EOL . 'FATAL: When specifying a Device Template ID, you must pick on greater or equal than zero.' . PHP_EOL . PHP_EOL;
|
print PHP_EOL . ('FATAL: When specifying a Device Template ID, you must pick on greater ' .
|
||||||
|
'or equal than zero.') . PHP_EOL . PHP_EOL;
|
||||||
display_help();
|
display_help();
|
||||||
|
|
||||||
exit -1;
|
exit -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($proceed == false) {
|
if ($proceed == false) {
|
||||||
print PHP_EOL . 'FATAL: You Must Explicitly Instruct This Script to Proceed with the \'--proceed\' Option' . PHP_EOL . PHP_EOL;
|
print PHP_EOL . ('FATAL: You Must Explicitly Instruct This Script to Proceed with the ' .
|
||||||
|
'\'--proceed\' Option') . PHP_EOL . PHP_EOL;
|
||||||
display_help();
|
display_help();
|
||||||
|
|
||||||
exit -1;
|
exit -1;
|
||||||
@@ -144,7 +146,9 @@ if ($pattern == '' || $pattern == 'device') {
|
|||||||
} elseif ($pattern == 'device_dq') {
|
} elseif ($pattern == 'device_dq') {
|
||||||
$pattern1 = "CONCAT('<path_rra>/', host_id, '/', snmp_query_id, '/', local_data_id, '.rrd') AS new_data_source_path,";
|
$pattern1 = "CONCAT('<path_rra>/', host_id, '/', snmp_query_id, '/', local_data_id, '.rrd') AS new_data_source_path,";
|
||||||
$pattern2 = "REPLACE(CONCAT('<path_rra>/', host_id, '/', snmp_query_id, '/', local_data_id, '.rrd'), '<path_rra>', '$base_rra_path') AS new_rrd_path";
|
$pattern2 = "REPLACE(CONCAT('<path_rra>/', host_id, '/', snmp_query_id, '/', local_data_id, '.rrd'), '<path_rra>', '$base_rra_path') AS new_rrd_path";
|
||||||
$sql_where = "WHERE dtd.data_source_path != CONCAT('<path_rra>/', dl.host_id, '/', IF(dl.snmp_query_id > 0, CONCAT(dl.snmp_query_id, '/'), ''), dtd.local_data_id, '.rrd')";
|
$sql_where = ("WHERE dtd.data_source_path != CONCAT('<path_rra>/', dl.host_id, '/', " .
|
||||||
|
"IF(dl.snmp_query_id > 0, CONCAT(dl.snmp_query_id, '/'), ''), " .
|
||||||
|
"dtd.local_data_id, '.rrd')");
|
||||||
} elseif ($pattern == 'hash_device') {
|
} elseif ($pattern == 'hash_device') {
|
||||||
$pattern1 = "CONCAT('<path_rra>/', host_id % $maxdirs, '/', host_id, '/', local_data_id, '.rrd') AS new_data_source_path,";
|
$pattern1 = "CONCAT('<path_rra>/', host_id % $maxdirs, '/', host_id, '/', local_data_id, '.rrd') AS new_data_source_path,";
|
||||||
$pattern2 = "REPLACE(CONCAT('<path_rra>/', host_id % $maxdirs, '/', host_id, '/', local_data_id, '.rrd'), '<path_rra>', '$base_rra_path') AS new_rrd_path";
|
$pattern2 = "REPLACE(CONCAT('<path_rra>/', host_id % $maxdirs, '/', host_id, '/', local_data_id, '.rrd'), '<path_rra>', '$base_rra_path') AS new_rrd_path";
|
||||||
@@ -246,17 +250,45 @@ foreach ($data_sources as $info) {
|
|||||||
LIMIT 1',
|
LIMIT 1',
|
||||||
[$local_data_id]);
|
[$local_data_id]);
|
||||||
|
|
||||||
$data_source_path1 = $base_rra_path . '/' . cacti_strtolower(clean_up_file_name($info['description'])) . '_' . $local_data_id . '.rrd';
|
$data_source_path1 = $base_rra_path .
|
||||||
|
'/' .
|
||||||
|
cacti_strtolower(clean_up_file_name($info['description'])) .
|
||||||
|
'_' .
|
||||||
|
$local_data_id .
|
||||||
|
'.rrd';
|
||||||
$data_source_path2 = '';
|
$data_source_path2 = '';
|
||||||
|
|
||||||
if ($pattern == '' || $pattern == 'device') {
|
if ($pattern == '' || $pattern == 'device') {
|
||||||
$data_source_path2 = $base_rra_path . '/' . $info['host_id'] . '/' . $info['snmp_query_id'] . '/' . $local_data_id . '.rrd';
|
$data_source_path2 = $base_rra_path .
|
||||||
|
'/' .
|
||||||
|
$info['host_id'] .
|
||||||
|
'/' .
|
||||||
|
$info['snmp_query_id'] .
|
||||||
|
'/' .
|
||||||
|
$local_data_id .
|
||||||
|
'.rrd';
|
||||||
} elseif ($pattern == 'device_dq') {
|
} elseif ($pattern == 'device_dq') {
|
||||||
$data_source_path2 = $base_rra_path . '/' . $info['host_id'] . '/' . $local_data_id . '.rrd';
|
$data_source_path2 = $base_rra_path . '/' . $info['host_id'] . '/' . $local_data_id . '.rrd';
|
||||||
} elseif ($pattern == 'hash_device') {
|
} elseif ($pattern == 'hash_device') {
|
||||||
$data_source_path2 = $base_rra_path . '/' . $info['hash_id'] . '/' . $info['host_id'] . '/' . $local_data_id . '.rrd';
|
$data_source_path2 = $base_rra_path .
|
||||||
|
'/' .
|
||||||
|
$info['hash_id'] .
|
||||||
|
'/' .
|
||||||
|
$info['host_id'] .
|
||||||
|
'/' .
|
||||||
|
$local_data_id .
|
||||||
|
'.rrd';
|
||||||
} elseif ($pattern == 'hash_device_dq') {
|
} elseif ($pattern == 'hash_device_dq') {
|
||||||
$data_source_path2 = $base_rra_path . '/' . $info['hash_id'] . '/' . $info['host_id'] . '/' . $info['snmp_query_id'] . '/' . $local_data_id . '.rrd';
|
$data_source_path2 = $base_rra_path .
|
||||||
|
'/' .
|
||||||
|
$info['hash_id'] .
|
||||||
|
'/' .
|
||||||
|
$info['host_id'] .
|
||||||
|
'/' .
|
||||||
|
$info['snmp_query_id'] .
|
||||||
|
'/' .
|
||||||
|
$local_data_id .
|
||||||
|
'.rrd';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_exists($data_source_path1)) {
|
if (file_exists($data_source_path1)) {
|
||||||
|
|||||||
+24
-10
@@ -181,7 +181,9 @@ if ($new_heartbeat !== false && (!is_numeric($new_heartbeat) || $new_heartbeat <
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!array_key_exists($new_heartbeat, $heartbeats)) {
|
if (!array_key_exists($new_heartbeat, $heartbeats)) {
|
||||||
printf('ERROR: Your New Heartbeat \'%s\' is not a supported Heartbeat. Use --list-heartbeats to see the list.' . PHP_EOL, $new_heartbeat);
|
printf(('ERROR: Your New Heartbeat \'%s\' is not a supported Heartbeat. Use ' .
|
||||||
|
'--list-heartbeats to see the list.') . PHP_EOL,
|
||||||
|
$new_heartbeat);
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -238,7 +240,9 @@ if (!$force) {
|
|||||||
|
|
||||||
foreach ($profile_ids as $pid) {
|
foreach ($profile_ids as $pid) {
|
||||||
if ($pid['heartbeat'] != $new_heartbeat) {
|
if ($pid['heartbeat'] != $new_heartbeat) {
|
||||||
printf('ERROR: Data Source Profile \'%s\' has a heartbeat of %s which does' . PHP_EOL, $pid['name'], $pid['heartbeat']);
|
printf('ERROR: Data Source Profile \'%s\' has a heartbeat of %s which does' . PHP_EOL,
|
||||||
|
$pid['name'],
|
||||||
|
$pid['heartbeat']);
|
||||||
printf(' not match the new heartbeat of %s. Use the --force option to update' . PHP_EOL, $new_heartbeat);
|
printf(' not match the new heartbeat of %s. Use the --force option to update' . PHP_EOL, $new_heartbeat);
|
||||||
printf(' the Data Source Profile\'s heartbeat as well as the Data Sources.' . PHP_EOL . PHP_EOL);
|
printf(' the Data Source Profile\'s heartbeat as well as the Data Sources.' . PHP_EOL . PHP_EOL);
|
||||||
$exit = true;
|
$exit = true;
|
||||||
@@ -275,7 +279,10 @@ if (cacti_sizeof($rrdfiles)) {
|
|||||||
$output = [];
|
$output = [];
|
||||||
$return_code = 0;
|
$return_code = 0;
|
||||||
|
|
||||||
debug(sprintf('Updating Heartbeat for Data Source:%s, Data Template:%s, RRD:%s from 600 to 900' . PHP_EOL, $f['name_cache'], $f['name'], $f['rrd']));
|
debug(sprintf('Updating Heartbeat for Data Source:%s, Data Template:%s, RRD:%s from 600 to 900' . PHP_EOL,
|
||||||
|
$f['name_cache'],
|
||||||
|
$f['name'],
|
||||||
|
$f['rrd']));
|
||||||
debug(sprintf("The RRDtool command is '$command'" . PHP_EOL));
|
debug(sprintf("The RRDtool command is '$command'" . PHP_EOL));
|
||||||
|
|
||||||
$result = exec($command, $output, $return_code);
|
$result = exec($command, $output, $return_code);
|
||||||
@@ -359,20 +366,27 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: update_heartbeat.php --new-heartbeat=N [--data-template-id=id] [--prev-heartbeat=N] [--force] [--debug|-d]' . PHP_EOL . PHP_EOL;
|
print ('usage: update_heartbeat.php --new-heartbeat=N [--data-template-id=id] ' .
|
||||||
|
'[--prev-heartbeat=N] [--force] [--debug|-d]') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'A utility to update RRDfile heartbeats and the Cacti database to match.' . PHP_EOL . PHP_EOL;
|
print 'A utility to update RRDfile heartbeats and the Cacti database to match.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'Required:' . PHP_EOL;
|
print 'Required:' . PHP_EOL;
|
||||||
print ' --new-heartbeat=N - A Heartbeat in seconds. It must align with available Heartbeats in Cacti' . PHP_EOL;
|
print (' --new-heartbeat=N - A Heartbeat in seconds. It must align ' .
|
||||||
print ' Currently Heartbeats include from 20-172800 seconds. The value must also' . PHP_EOL;
|
'with available Heartbeats in Cacti') . PHP_EOL;
|
||||||
|
print (' Currently Heartbeats include from ' .
|
||||||
|
'20-172800 seconds. The value must also') . PHP_EOL;
|
||||||
print ' be at least two times the current Cacti poller interval.' . PHP_EOL;
|
print ' be at least two times the current Cacti poller interval.' . PHP_EOL;
|
||||||
|
|
||||||
print 'Optional:' . PHP_EOL;
|
print 'Optional:' . PHP_EOL;
|
||||||
print ' --data-template-id=N - Only update Cacti Data Source Heartbeats that are associated with a Data Template id.' . PHP_EOL;
|
print (' --data-template-id=N - Only update Cacti Data Source Heartbeats ' .
|
||||||
print ' --prev-heartbeat=N - Only update Cacti Data Sources that currently have the Heartbeat specified.' . PHP_EOL;
|
'that are associated with a Data Template id.') . PHP_EOL;
|
||||||
print ' --force - If the heartbeat selected does not match the Data Source Profile, update the' . PHP_EOL;
|
print (' --prev-heartbeat=N - Only update Cacti Data Sources that ' .
|
||||||
print ' Data Source Profile to match the command. Otherwise, the script will exit.' . PHP_EOL;
|
'currently have the Heartbeat specified.') . PHP_EOL;
|
||||||
|
print (' --force - If the heartbeat selected does not match ' .
|
||||||
|
'the Data Source Profile, update the') . PHP_EOL;
|
||||||
|
print (' Data Source Profile to match the command. ' .
|
||||||
|
' Otherwise, the script will exit.') . PHP_EOL;
|
||||||
print ' --debug - Display verbose output during execution' . PHP_EOL . PHP_EOL;
|
print ' --debug - Display verbose output during execution' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'List Options:' . PHP_EOL;
|
print 'List Options:' . PHP_EOL;
|
||||||
|
|||||||
@@ -119,7 +119,12 @@ $old_version_index = (array_key_exists($old_cacti_version, $cacti_version_codes)
|
|||||||
if (cacti_version_compare($old_cacti_version,CACTI_VERSION,'=')) {
|
if (cacti_version_compare($old_cacti_version,CACTI_VERSION,'=')) {
|
||||||
exit_version_error($old_cacti_version, 'Your Cacti is already up to date');
|
exit_version_error($old_cacti_version, 'Your Cacti is already up to date');
|
||||||
} elseif (cacti_version_compare($old_cacti_version,'0.7','<')) {
|
} elseif (cacti_version_compare($old_cacti_version,'0.7','<')) {
|
||||||
exit_error('You are attempting to install cacti ' . CACTI_VERSION . ' onto a 0.6.x database.' . PHP_EOL . "To continue, you must create a new database, import 'cacti.sql' into it," . PHP_EOL . "and\tupdate 'include/config.php' to point to the new database.");
|
exit_error('You are attempting to install cacti ' .
|
||||||
|
CACTI_VERSION .
|
||||||
|
' onto a 0.6.x database.' .
|
||||||
|
PHP_EOL .
|
||||||
|
("To continue, you must create a new database, import 'cacti.sql' into " .
|
||||||
|
'it,') . PHP_EOL . "and\tupdate 'include/config.php' to point to the new database.");
|
||||||
} elseif (empty($old_cacti_version)) {
|
} elseif (empty($old_cacti_version)) {
|
||||||
exit_error('You have created a new database, but have not yet imported the \'cacti.sql\' file.');
|
exit_error('You have created a new database, but have not yet imported the \'cacti.sql\' file.');
|
||||||
|
|
||||||
@@ -206,7 +211,8 @@ function exit_error(string $text) : void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function exit_version_error(string $old_cacti_version, string $text) : void {
|
function exit_version_error(string $old_cacti_version, string $text) : void {
|
||||||
exit_error($text . PHP_EOL . ' - from: v' . get_cacti_version_text(false, $old_cacti_version) . PHP_EOL . ' to: v' . CACTI_VERSION_BRIEF_FULL);
|
exit_error($text . PHP_EOL . ' - from: v' . get_cacti_version_text(false,
|
||||||
|
$old_cacti_version) . PHP_EOL . ' to: v' . CACTI_VERSION_BRIEF_FULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
function db_install_errors(string $cacti_version) : int {
|
function db_install_errors(string $cacti_version) : int {
|
||||||
@@ -238,7 +244,19 @@ function db_install_errors(string $cacti_version) : int {
|
|||||||
|
|
||||||
$sep1 = '################################';
|
$sep1 = '################################';
|
||||||
$sep2 = '+------------------------------+';
|
$sep2 = '+------------------------------+';
|
||||||
printf('%s%s%s%-10s - %s%s%s%s%s%s%s%s', PHP_EOL, $sep1, PHP_EOL, $db_status, $error, PHP_EOL, $sep2, PHP_EOL, clean_up_lines($sql), PHP_EOL, $sep1, PHP_EOL);
|
printf('%s%s%s%-10s - %s%s%s%s%s%s%s%s',
|
||||||
|
PHP_EOL,
|
||||||
|
$sep1,
|
||||||
|
PHP_EOL,
|
||||||
|
$db_status,
|
||||||
|
$error,
|
||||||
|
PHP_EOL,
|
||||||
|
$sep2,
|
||||||
|
PHP_EOL,
|
||||||
|
clean_up_lines($sql),
|
||||||
|
PHP_EOL,
|
||||||
|
$sep1,
|
||||||
|
PHP_EOL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -344,7 +344,10 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
|
|||||||
// proc_open returns false if the child could not be spawned; fall back to
|
// proc_open returns false if the child could not be spawned; fall back to
|
||||||
// the non-proc path rather than reading from non-existent pipes
|
// the non-proc path rather than reading from non-existent pipes
|
||||||
if (!is_resource($cactiphp)) {
|
if (!is_resource($cactiphp)) {
|
||||||
cacti_log('WARNING: Unable to start PHP Script Server, falling back to direct execution', $print_data_to_stdout, 'POLLER', POLLER_VERBOSITY_LOW);
|
cacti_log('WARNING: Unable to start PHP Script Server, falling back to direct execution',
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
POLLER_VERBOSITY_LOW);
|
||||||
|
|
||||||
$using_proc_function = false;
|
$using_proc_function = false;
|
||||||
$cactiphp = false;
|
$cactiphp = false;
|
||||||
@@ -376,7 +379,11 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
|
|||||||
$host_end = microtime(true);
|
$host_end = microtime(true);
|
||||||
|
|
||||||
if ($output_count > 0) {
|
if ($output_count > 0) {
|
||||||
cacti_log("Device[$last_host] Writing $output_count items to Poller Output Table", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$last_host] Writing $output_count items to Poller Output Table",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
db_execute('INSERT IGNORE INTO poller_output
|
db_execute('INSERT IGNORE INTO poller_output
|
||||||
(local_data_id, rrd_name, time, output)
|
(local_data_id, rrd_name, time, output)
|
||||||
@@ -408,11 +415,26 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log(sprintf('Device[%d] Time[%3.2f] Items[%d] Errors[%d]', $last_host, $host_end - $host_start, $itemcnt, $errors), $print_data_to_stdout, 'POLLER', $hmedium);
|
cacti_log(sprintf('Device[%d] Time[%3.2f] Items[%d] Errors[%d]',
|
||||||
|
$last_host,
|
||||||
|
$host_end - $host_start,
|
||||||
|
$itemcnt,
|
||||||
|
$errors),
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
$hmedium);
|
||||||
|
|
||||||
if ($errors > 0) {
|
if ($errors > 0) {
|
||||||
if (read_config_option('spine_log_level') == 1) {
|
if (read_config_option('spine_log_level') == 1) {
|
||||||
cacti_log('WARNING: Invalid Response(s), Errors[' . $errors . '] Device[' . $last_host . '] Thread[1] DS[' . implode(', ', $error_ds) . ']', false, 'POLLER');
|
cacti_log('WARNING: Invalid Response(s), Errors[' .
|
||||||
|
$errors .
|
||||||
|
'] Device[' .
|
||||||
|
$last_host .
|
||||||
|
'] Thread[1] DS[' .
|
||||||
|
implode(', ',
|
||||||
|
$error_ds) . ']',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
|
|
||||||
$tot_errors += $errors;
|
$tot_errors += $errors;
|
||||||
@@ -449,14 +471,28 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
|
|||||||
|
|
||||||
if ($set_spike_kill && !substr_count($output, ':')) {
|
if ($set_spike_kill && !substr_count($output, ':')) {
|
||||||
// insert a U in place of the actual value if the snmp agent restarts
|
// insert a U in place of the actual value if the snmp agent restarts
|
||||||
$output_array[] = sprintf('(%d, %s, CURRENT_TIMESTAMP(), %s)', $item['local_data_id'], db_qstr($item['rrd_name'], $poller_db_cnn_id), db_qstr('U', $poller_db_cnn_id));
|
$output_array[] = sprintf('(%d, %s, CURRENT_TIMESTAMP(), %s)',
|
||||||
|
$item['local_data_id'],
|
||||||
|
db_qstr($item['rrd_name'],
|
||||||
|
$poller_db_cnn_id),
|
||||||
|
db_qstr('U',
|
||||||
|
$poller_db_cnn_id));
|
||||||
} else {
|
} else {
|
||||||
// otherwise, just insert the value received from the poller
|
// otherwise, just insert the value received from the poller
|
||||||
$output_array[] = sprintf('(%d, %s, CURRENT_TIMESTAMP(), %s)', $item['local_data_id'], db_qstr($item['rrd_name'], $poller_db_cnn_id), db_qstr($output, $poller_db_cnn_id));
|
$output_array[] = sprintf('(%d, %s, CURRENT_TIMESTAMP(), %s)',
|
||||||
|
$item['local_data_id'],
|
||||||
|
db_qstr($item['rrd_name'],
|
||||||
|
$poller_db_cnn_id),
|
||||||
|
db_qstr($output,
|
||||||
|
$poller_db_cnn_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($output_count > 2000) {
|
if ($output_count > 2000) {
|
||||||
cacti_log("Device[$host_id] Writing $output_count items to Poller Output Table", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] Writing $output_count items to Poller Output Table",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
db_execute('INSERT IGNORE INTO poller_output
|
db_execute('INSERT IGNORE INTO poller_output
|
||||||
(local_data_id, rrd_name, time, output)
|
(local_data_id, rrd_name, time, output)
|
||||||
@@ -488,7 +524,11 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
|
|||||||
|
|
||||||
// Flush the items to the output table
|
// Flush the items to the output table
|
||||||
if ($output_count > 0) {
|
if ($output_count > 0) {
|
||||||
cacti_log("Device[$host_id] Writing $output_count items to Poller Output Table", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] Writing $output_count items to Poller Output Table",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
db_execute('INSERT IGNORE INTO poller_output
|
db_execute('INSERT IGNORE INTO poller_output
|
||||||
(local_data_id, rrd_name, time, output)
|
(local_data_id, rrd_name, time, output)
|
||||||
@@ -517,11 +557,26 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log(sprintf('Device[%d] Time[%3.2f] Items[%d] Errors[%d]', $last_host, $host_end - $host_start, $itemcnt, $errors), $print_data_to_stdout, 'POLLER', $hmedium);
|
cacti_log(sprintf('Device[%d] Time[%3.2f] Items[%d] Errors[%d]',
|
||||||
|
$last_host,
|
||||||
|
$host_end - $host_start,
|
||||||
|
$itemcnt,
|
||||||
|
$errors),
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
$hmedium);
|
||||||
|
|
||||||
if ($host_id > 0 && $errors > 0) {
|
if ($host_id > 0 && $errors > 0) {
|
||||||
if (read_config_option('spine_log_level') == 1) {
|
if (read_config_option('spine_log_level') == 1) {
|
||||||
cacti_log('WARNING: Invalid Response(s), Errors[' . $errors . '] Device[' . $host_id . '] Thread[1] DS[' . implode(', ', $error_ds) . ']', false, 'POLLER');
|
cacti_log('WARNING: Invalid Response(s), Errors[' .
|
||||||
|
$errors .
|
||||||
|
'] Device[' .
|
||||||
|
$host_id .
|
||||||
|
'] Thread[1] DS[' .
|
||||||
|
implode(', ',
|
||||||
|
$error_ds) . ']',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
|
|
||||||
$tot_errors += $errors;
|
$tot_errors += $errors;
|
||||||
@@ -533,7 +588,10 @@ if (cacti_sizeof($poller_items) && read_config_option('poller_enabled') == 'on')
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cacti_sizeof($width_dses)) {
|
if (cacti_sizeof($width_dses)) {
|
||||||
cacti_log('WARNING: Long Responses Errors[' . cacti_sizeof($width_dses) . '] DS[' . implode(', ', $width_dses) . ']', false, 'POLLER');
|
cacti_log('WARNING: Long Responses Errors[' . cacti_sizeof($width_dses) . '] DS[' . implode(', ',
|
||||||
|
$width_dses) . ']',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($using_proc_function && $script_server_calls > 0) {
|
if ($using_proc_function && $script_server_calls > 0) {
|
||||||
@@ -595,10 +653,18 @@ if (cacti_sizeof($hosts)) {
|
|||||||
// perform the appropriate ping check of the host
|
// perform the appropriate ping check of the host
|
||||||
if ($ping->ping($host['availability_method'], $host['ping_method'], $host['ping_timeout'], $host['ping_retries'])) {
|
if ($ping->ping($host['availability_method'], $host['ping_method'], $host['ping_timeout'], $host['ping_retries'])) {
|
||||||
update_host_status(HOST_UP, $host['id'], $ping, $host['availability_method'], $print_data_to_stdout);
|
update_host_status(HOST_UP, $host['id'], $ping, $host['availability_method'], $print_data_to_stdout);
|
||||||
cacti_log('Device[' . $host['id'] . "] STATUS: Device '" . $host['hostname'] . "' is UP.", $print_data_to_stdout, 'POLLER', debug_level($host['id'], POLLER_VERBOSITY_MEDIUM));
|
cacti_log('Device[' . $host['id'] . "] STATUS: Device '" . $host['hostname'] . "' is UP.",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host['id'],
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
} else {
|
} else {
|
||||||
update_host_status(HOST_DOWN, $host['id'], $ping, $host['availability_method'], $print_data_to_stdout);
|
update_host_status(HOST_DOWN, $host['id'], $ping, $host['availability_method'], $print_data_to_stdout);
|
||||||
cacti_log('Device[' . $host['id'] . "] STATUS: Device '" . $host['hostname'] . "' is Down.", $print_data_to_stdout, 'POLLER', debug_level($host['id'], POLLER_VERBOSITY_MEDIUM));
|
cacti_log('Device[' . $host['id'] . "] STATUS: Device '" . $host['hostname'] . "' is Down.",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host['id'],
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -777,7 +843,9 @@ function collect_device_data(array &$item, array &$error_ds, int $script_timeout
|
|||||||
switch ($item['action']) {
|
switch ($item['action']) {
|
||||||
case POLLER_ACTION_SNMP:
|
case POLLER_ACTION_SNMP:
|
||||||
if (($item['snmp_version'] == 0) || (($item['snmp_community'] == '') && ($item['snmp_version'] != 3))) {
|
if (($item['snmp_version'] == 0) || (($item['snmp_community'] == '') && ($item['snmp_version'] != 3))) {
|
||||||
cacti_log("Device[$host_id] DS[$ds] ERROR: Invalid SNMP Data Source. Please either delete it from the database, or correct it.", $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] DS[$ds] ERROR: Invalid SNMP Data Source. Please either delete it from the database, or correct it.",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
$output = 'U';
|
$output = 'U';
|
||||||
} else {
|
} else {
|
||||||
$session = open_snmp_session($host_id, $item);
|
$session = open_snmp_session($host_id, $item);
|
||||||
@@ -790,7 +858,9 @@ function collect_device_data(array &$item, array &$error_ds, int $script_timeout
|
|||||||
$error_ds[$ds] = $ds;
|
$error_ds[$ds] = $ds;
|
||||||
|
|
||||||
if (read_config_option('spine_log_level') == 2) {
|
if (read_config_option('spine_log_level') == 2) {
|
||||||
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] OID:" . $item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER');
|
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] OID:" . $item['arg1'] . ", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
|
|
||||||
$output = 'U';
|
$output = 'U';
|
||||||
@@ -804,14 +874,30 @@ function collect_device_data(array &$item, array &$error_ds, int $script_timeout
|
|||||||
$error_ds[$ds] = $ds;
|
$error_ds[$ds] = $ds;
|
||||||
|
|
||||||
if (read_config_option('spine_log_level') == 2) {
|
if (read_config_option('spine_log_level') == 2) {
|
||||||
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] OID:" . $item['arg1'] . ', output: U', $print_data_to_stdout, 'POLLER');
|
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] OID:" . $item['arg1'] . ', output: U',
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$total_time = (microtime(true) - $thread_start) * 1000;
|
$total_time = (microtime(true) - $thread_start) * 1000;
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DS[$ds] TT[" . round($total_time, 2) . '] SNMP: v' . $item['snmp_version'] . ': ' . $item['hostname'] . ', dsname: ' . $item['rrd_name'] . ', oid: ' . $item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DS[$ds] TT[" . round($total_time,
|
||||||
|
2) .
|
||||||
|
'] SNMP: v' .
|
||||||
|
$item['snmp_version'] .
|
||||||
|
': ' .
|
||||||
|
$item['hostname'] .
|
||||||
|
', dsname: ' .
|
||||||
|
$item['rrd_name'] .
|
||||||
|
', oid: ' .
|
||||||
|
$item['arg1'] .
|
||||||
|
", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case POLLER_ACTION_SCRIPT:
|
case POLLER_ACTION_SCRIPT:
|
||||||
@@ -821,21 +907,30 @@ function collect_device_data(array &$item, array &$error_ds, int $script_timeout
|
|||||||
$error_ds[$ds] = $ds;
|
$error_ds[$ds] = $ds;
|
||||||
|
|
||||||
if (read_config_option('spine_log_level') == 2) {
|
if (read_config_option('spine_log_level') == 2) {
|
||||||
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SCRIPT: " . $item['arg1'] . ', output: U', $print_data_to_stdout, 'POLLER');
|
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SCRIPT: " . $item['arg1'] . ', output: U',
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
} elseif (!is_numeric($output)) {
|
} elseif (!is_numeric($output)) {
|
||||||
if (prepare_validate_result($output) == false) {
|
if (prepare_validate_result($output) == false) {
|
||||||
$error_ds[$ds] = $ds;
|
$error_ds[$ds] = $ds;
|
||||||
|
|
||||||
if (read_config_option('spine_log_level') == 2) {
|
if (read_config_option('spine_log_level') == 2) {
|
||||||
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SCRIPT: " . $item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER');
|
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SCRIPT: " . $item['arg1'] . ", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$total_time = (microtime(true) - $thread_start) * 1000;
|
$total_time = (microtime(true) - $thread_start) * 1000;
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DS[$ds] TT[" . round($total_time, 2) . '] SCRIPT: ' . $item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DS[$ds] TT[" . round($total_time,
|
||||||
|
2) . '] SCRIPT: ' . $item['arg1'] . ", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case POLLER_ACTION_SCRIPT_PHP:
|
case POLLER_ACTION_SCRIPT_PHP:
|
||||||
@@ -845,27 +940,38 @@ function collect_device_data(array &$item, array &$error_ds, int $script_timeout
|
|||||||
$error_ds[$ds] = $ds;
|
$error_ds[$ds] = $ds;
|
||||||
|
|
||||||
if (read_config_option('spine_log_level') == 2) {
|
if (read_config_option('spine_log_level') == 2) {
|
||||||
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SERVER: " . $item['arg1'] . ', output: U', $print_data_to_stdout, 'POLLER');
|
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SERVER: " . $item['arg1'] . ', output: U',
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
} elseif (!is_numeric($output)) {
|
} elseif (!is_numeric($output)) {
|
||||||
if (prepare_validate_result($output) == false) {
|
if (prepare_validate_result($output) == false) {
|
||||||
$error_ds[$ds] = $ds;
|
$error_ds[$ds] = $ds;
|
||||||
|
|
||||||
if (read_config_option('spine_log_level') == 2) {
|
if (read_config_option('spine_log_level') == 2) {
|
||||||
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SERVER: " . $item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER');
|
cacti_log("WARNING: Invalid Response, Device[$host_id] DS[$ds] SERVER: " . $item['arg1'] . ", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$total_time = (microtime(true) - $thread_start) * 1000;
|
$total_time = (microtime(true) - $thread_start) * 1000;
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DS[$ds] TT[" . round($total_time, 2) . '] SERVER: ' . $item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DS[$ds] TT[" . round($total_time,
|
||||||
|
2) . '] SERVER: ' . $item['arg1'] . ", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$error_ds[$ds] = $ds;
|
$error_ds[$ds] = $ds;
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DS[$ds] ERROR: Invalid polling option: " . $item['action'], $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] DS[$ds] ERROR: Invalid polling option: " . $item['action'],
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
@@ -892,7 +998,11 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
|
|
||||||
update_host_status(HOST_UP, $host_id, $ping, $host['availability_method'], $print_data_to_stdout);
|
update_host_status(HOST_UP, $host_id, $ping, $host['availability_method'], $print_data_to_stdout);
|
||||||
|
|
||||||
cacti_log("Device[$host_id] STATUS: Device '" . $item['hostname'] . "' is UP.", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_DEBUG));
|
cacti_log("Device[$host_id] STATUS: Device '" . $item['hostname'] . "' is UP.",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_DEBUG));
|
||||||
|
|
||||||
if ($mibs && $host['availability_method'] != 0 && $host['availability_method'] != 3) {
|
if ($mibs && $host['availability_method'] != 0 && $host['availability_method'] != 3) {
|
||||||
update_system_mibs($host_id);
|
update_system_mibs($host_id);
|
||||||
@@ -901,7 +1011,11 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
$host_down = true;
|
$host_down = true;
|
||||||
update_host_status(HOST_DOWN, $host_id, $ping, $host['availability_method'], $print_data_to_stdout);
|
update_host_status(HOST_DOWN, $host_id, $ping, $host['availability_method'], $print_data_to_stdout);
|
||||||
|
|
||||||
cacti_log("Device[$host_id] STATUS: Device '" . $item['hostname'] . "' is Down.", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_DEBUG));
|
cacti_log("Device[$host_id] STATUS: Device '" . $item['hostname'] . "' is Down.",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_DEBUG));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($host_down == false) {
|
if ($host_down == false) {
|
||||||
@@ -914,7 +1028,15 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (cacti_sizeof($reindex)) {
|
if (cacti_sizeof($reindex)) {
|
||||||
cacti_log("Device[$host_id] RECACHE: Processing " . cacti_sizeof($reindex) . " items in the auto reindex cache for '" . $item['hostname'] . "'.", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_DEBUG));
|
cacti_log("Device[$host_id] RECACHE: Processing " .
|
||||||
|
cacti_sizeof($reindex) .
|
||||||
|
" items in the auto reindex cache for '" .
|
||||||
|
$item['hostname'] .
|
||||||
|
"'.",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_DEBUG));
|
||||||
|
|
||||||
foreach ($reindex as $index_item) {
|
foreach ($reindex as $index_item) {
|
||||||
$assert_fail = false;
|
$assert_fail = false;
|
||||||
@@ -948,7 +1070,21 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
$output = 'U';
|
$output = 'U';
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE OID: ' . $index_item['arg1'] . ', (assert:' . $index_item['assert_value'] . ' ' . $index_item['op'] . ' output:' . $output . ')', $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE OID: ' .
|
||||||
|
$index_item['arg1'] .
|
||||||
|
', (assert:' .
|
||||||
|
$index_item['assert_value'] .
|
||||||
|
' ' .
|
||||||
|
$index_item['op'] .
|
||||||
|
' output:' .
|
||||||
|
$output .
|
||||||
|
')',
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case POLLER_ACTION_SCRIPT:
|
case POLLER_ACTION_SCRIPT:
|
||||||
@@ -962,15 +1098,35 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
$strout = strlen($output);
|
$strout = strlen($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE Warning: Result from Script not valid. Partial Result: ' . substr($output, 0, $strout), $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE Warning: Result from Script not valid. Partial Result: ' .
|
||||||
|
substr($output,
|
||||||
|
0,
|
||||||
|
$strout),
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE SCRIPT: ' . $index_item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE SCRIPT: ' .
|
||||||
|
$index_item['arg1'] .
|
||||||
|
", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case POLLER_ACTION_SCRIPT_PHP:
|
case POLLER_ACTION_SCRIPT_PHP:
|
||||||
$output = trim(str_replace("\n", '', exec_poll_php($index_item['arg1'], $using_proc_function, $pipes, $cactiphp)));
|
$output = trim(str_replace("\n",
|
||||||
|
'',
|
||||||
|
exec_poll_php($index_item['arg1'],
|
||||||
|
$using_proc_function,
|
||||||
|
$pipes,
|
||||||
|
$cactiphp)));
|
||||||
|
|
||||||
if (!is_numeric($output)) {
|
if (!is_numeric($output)) {
|
||||||
if (prepare_validate_result($output) == false) {
|
if (prepare_validate_result($output) == false) {
|
||||||
@@ -980,11 +1136,26 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
$strout = strlen($output);
|
$strout = strlen($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE WARNING: Result from Script Server not valid. Partial Result: ' . substr($output, 0, $strout), $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
('] RECACHE WARNING: Result from Script Server not valid. Partial ' .
|
||||||
|
'Result: ') . substr($output,
|
||||||
|
0,
|
||||||
|
$strout),
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE SERVER: ' . $index_item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE SERVER: ' .
|
||||||
|
$index_item['arg1'] .
|
||||||
|
", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case POLLER_ACTION_SNMP_COUNT:
|
case POLLER_ACTION_SNMP_COUNT:
|
||||||
@@ -996,7 +1167,16 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
$output = 'U';
|
$output = 'U';
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE OID COUNT: ' . $index_item['arg1'] . ', output: ' . $output, $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE OID COUNT: ' .
|
||||||
|
$index_item['arg1'] .
|
||||||
|
', output: ' .
|
||||||
|
$output,
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case POLLER_ACTION_SCRIPT_COUNT:
|
case POLLER_ACTION_SCRIPT_COUNT:
|
||||||
@@ -1004,20 +1184,41 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
$script_index_array = exec_into_array($index_item['arg1']);
|
$script_index_array = exec_into_array($index_item['arg1']);
|
||||||
$output = cacti_sizeof($script_index_array);
|
$output = cacti_sizeof($script_index_array);
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE CMD COUNT: ' . $index_item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE CMD COUNT: ' .
|
||||||
|
$index_item['arg1'] .
|
||||||
|
", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case POLLER_ACTION_SCRIPT_PHP_COUNT:
|
case POLLER_ACTION_SCRIPT_PHP_COUNT:
|
||||||
$output = exec_into_array($index_item['arg1']);
|
$output = exec_into_array($index_item['arg1']);
|
||||||
$output = cacti_sizeof($output);
|
$output = cacti_sizeof($output);
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE SERVER COUNT: ' . $index_item['arg1'] . ", output: $output", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_MEDIUM));
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE SERVER COUNT: ' .
|
||||||
|
$index_item['arg1'] .
|
||||||
|
", output: $output",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_MEDIUM));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
$output = '';
|
$output = '';
|
||||||
|
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . '] RECACHE ERROR: Invalid reindex option: ' . $index_item['action'], $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
'] RECACHE ERROR: Invalid reindex option: ' .
|
||||||
|
$index_item['action'],
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assert the result with the expected value in the
|
/* assert the result with the expected value in the
|
||||||
@@ -1025,7 +1226,14 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
*/
|
*/
|
||||||
// TODO: remove magic ":" from poller_command["command"]; this may interfere with scripts
|
// TODO: remove magic ":" from poller_command["command"]; this may interfere with scripts
|
||||||
if (($index_item['op'] == '=') && ($index_item['assert_value'] != trim($output))) {
|
if (($index_item['op'] == '=') && ($index_item['assert_value'] != trim($output))) {
|
||||||
cacti_log("Device[$host_id] HT[1] DQ[" . $index_item['data_query_id'] . "] RECACHE ASSERT FAILED '" . $index_item['assert_value'] . '=' . trim($output), $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] HT[1] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
"] RECACHE ASSERT FAILED '" .
|
||||||
|
$index_item['assert_value'] .
|
||||||
|
'=' .
|
||||||
|
trim($output),
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
db_execute_prepared('REPLACE INTO poller_command
|
db_execute_prepared('REPLACE INTO poller_command
|
||||||
(poller_id, time, action, command)
|
(poller_id, time, action, command)
|
||||||
@@ -1037,7 +1245,14 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
|
|
||||||
$assert_fail = true;
|
$assert_fail = true;
|
||||||
} elseif (($index_item['op'] == '>') && ($index_item['assert_value'] < trim($output))) {
|
} elseif (($index_item['op'] == '>') && ($index_item['assert_value'] < trim($output))) {
|
||||||
cacti_log("Device[$host_id] HT[1] DQ[" . $index_item['data_query_id'] . "] RECACHE ASSERT FAILED '" . $index_item['assert_value'] . '>' . trim($output), $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] HT[1] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
"] RECACHE ASSERT FAILED '" .
|
||||||
|
$index_item['assert_value'] .
|
||||||
|
'>' .
|
||||||
|
trim($output),
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
db_execute_prepared('REPLACE INTO poller_command
|
db_execute_prepared('REPLACE INTO poller_command
|
||||||
(poller_id, time, action, command)
|
(poller_id, time, action, command)
|
||||||
@@ -1049,7 +1264,14 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
|
|
||||||
$assert_fail = true;
|
$assert_fail = true;
|
||||||
} elseif (($index_item['op'] == '<') && ($index_item['assert_value'] > trim($output))) {
|
} elseif (($index_item['op'] == '<') && ($index_item['assert_value'] > trim($output))) {
|
||||||
cacti_log("Device[$host_id] DQ[" . $index_item['data_query_id'] . "] RECACHE ASSERT FAILED '" . $index_item['assert_value'] . '<' . trim($output), $print_data_to_stdout, 'POLLER');
|
cacti_log("Device[$host_id] DQ[" .
|
||||||
|
$index_item['data_query_id'] .
|
||||||
|
"] RECACHE ASSERT FAILED '" .
|
||||||
|
$index_item['assert_value'] .
|
||||||
|
'<' .
|
||||||
|
trim($output),
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
db_execute_prepared('REPLACE INTO poller_command
|
db_execute_prepared('REPLACE INTO poller_command
|
||||||
(poller_id, time, action, command)
|
(poller_id, time, action, command)
|
||||||
@@ -1077,12 +1299,18 @@ function ping_and_reindex_check(array &$item, bool $mibs, int $script_timeout) :
|
|||||||
|
|
||||||
// spike kill logic
|
// spike kill logic
|
||||||
if (($assert_fail) &&
|
if (($assert_fail) &&
|
||||||
(($index_item['op'] == '<') || ($index_item['arg1'] == '.1.3.6.1.2.1.1.3.0' || $index_item['arg1'] == '.1.3.6.1.6.3.10.2.1.3.0'))) {
|
(($index_item['op'] == '<') ||
|
||||||
|
($index_item['arg1'] == '.1.3.6.1.2.1.1.3.0' ||
|
||||||
|
$index_item['arg1'] == '.1.3.6.1.6.3.10.2.1.3.0'))) {
|
||||||
// don't spike kill unless we are certain
|
// don't spike kill unless we are certain
|
||||||
if (!empty($output)) {
|
if (!empty($output)) {
|
||||||
$set_spike_kill = true;
|
$set_spike_kill = true;
|
||||||
|
|
||||||
cacti_log("Device[$host_id] NOTICE: Spike Kill in Effect for '" . $item['hostname'] . "'.", $print_data_to_stdout, 'POLLER', debug_level($host_id, POLLER_VERBOSITY_DEBUG));
|
cacti_log("Device[$host_id] NOTICE: Spike Kill in Effect for '" . $item['hostname'] . "'.",
|
||||||
|
$print_data_to_stdout,
|
||||||
|
'POLLER',
|
||||||
|
debug_level($host_id,
|
||||||
|
POLLER_VERBOSITY_DEBUG));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -129,7 +129,10 @@ if (cacti_sizeof($idbyhost)) {
|
|||||||
// proc_open returns false if the child could not be spawned; fall back to
|
// proc_open returns false if the child could not be spawned; fall back to
|
||||||
// the non-proc path rather than reading from non-existent pipes
|
// the non-proc path rather than reading from non-existent pipes
|
||||||
if (!is_resource($cactiphp)) {
|
if (!is_resource($cactiphp)) {
|
||||||
cacti_log('WARNING: Unable to start PHP Script Server, falling back to direct execution', false, 'POLLER', POLLER_VERBOSITY_LOW);
|
cacti_log('WARNING: Unable to start PHP Script Server, falling back to direct execution',
|
||||||
|
false,
|
||||||
|
'POLLER',
|
||||||
|
POLLER_VERBOSITY_LOW);
|
||||||
|
|
||||||
$using_proc_function = false;
|
$using_proc_function = false;
|
||||||
$pipes = false;
|
$pipes = false;
|
||||||
|
|||||||
+145
-31
@@ -67,7 +67,10 @@ function sig_handler(int $signo) : void {
|
|||||||
if (cacti_sizeof($running_processes)) {
|
if (cacti_sizeof($running_processes)) {
|
||||||
foreach ($running_processes as $process) {
|
foreach ($running_processes as $process) {
|
||||||
if (function_exists('posix_kill')) {
|
if (function_exists('posix_kill')) {
|
||||||
cacti_log("WARNING: Termination poller process with pid '" . $process['pid'] . "'", true, 'POLLER', POLLER_VERBOSITY_LOW);
|
cacti_log("WARNING: Termination poller process with pid '" . $process['pid'] . "'",
|
||||||
|
true,
|
||||||
|
'POLLER',
|
||||||
|
POLLER_VERBOSITY_LOW);
|
||||||
cacti_process_kill((int) $process['pid'], SIGTERM, 'POLLER');
|
cacti_process_kill((int) $process['pid'], SIGTERM, 'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -397,7 +400,12 @@ if ($debug) {
|
|||||||
$poller_seconds_sincerun = 'Never';
|
$poller_seconds_sincerun = 'Never';
|
||||||
$poller_seconds_sincerun = round($poller_start - $poller_lastrun, 2);
|
$poller_seconds_sincerun = round($poller_start - $poller_lastrun, 2);
|
||||||
|
|
||||||
cacti_log("NOTE: Poller Int: '$poller_interval', $task_type Int: '$cron_interval', Time Since Last: '$poller_seconds_sincerun', Max Runtime '" . MAX_POLLER_RUNTIME . "', Poller Runs: '$poller_runs'", true, 'POLLER', $level);
|
cacti_log("NOTE: Poller Int: '$poller_interval', $task_type Int: '$cron_interval', Time Since Last: '$poller_seconds_sincerun', Max Runtime '" .
|
||||||
|
MAX_POLLER_RUNTIME .
|
||||||
|
"', Poller Runs: '$poller_runs'",
|
||||||
|
true,
|
||||||
|
'POLLER',
|
||||||
|
$level);
|
||||||
|
|
||||||
// our cron can run at either 1 or 5 minute intervals
|
// our cron can run at either 1 or 5 minute intervals
|
||||||
if ($poller_interval <= 60) {
|
if ($poller_interval <= 60) {
|
||||||
@@ -410,7 +418,12 @@ if ($poller_interval <= 60) {
|
|||||||
if ($poller_lastrun > 0 && $force === false) {
|
if ($poller_lastrun > 0 && $force === false) {
|
||||||
// give the user some flexibility to run a little moe often
|
// give the user some flexibility to run a little moe often
|
||||||
if ((($poller_start - $poller_lastrun) * 1.3) < MAX_POLLER_RUNTIME) {
|
if ((($poller_start - $poller_lastrun) * 1.3) < MAX_POLLER_RUNTIME) {
|
||||||
cacti_log("NOTE: $task_type is configured to run too often! The Poller Interval is '$poller_interval' seconds, with a minimum $task_type period of '$min_period' seconds, but only " . number_format_i18n($poller_start - $poller_lastrun, 1) . ' seconds have passed since the poller last ran.', true, 'POLLER', $level);
|
cacti_log("NOTE: $task_type is configured to run too often! The Poller Interval is '$poller_interval' seconds, with a minimum $task_type period of '$min_period' seconds, but only " .
|
||||||
|
number_format_i18n($poller_start - $poller_lastrun,
|
||||||
|
1) . ' seconds have passed since the poller last ran.',
|
||||||
|
true,
|
||||||
|
'POLLER',
|
||||||
|
$level);
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -420,8 +433,21 @@ if ($poller_lastrun > 0 && $force === false) {
|
|||||||
* the poller is actually ran, if so, issue a warning
|
* the poller is actually ran, if so, issue a warning
|
||||||
*/
|
*/
|
||||||
if ((($poller_start - $poller_lastrun - 10) > MAX_POLLER_RUNTIME) && ($poller_lastrun > 0)) {
|
if ((($poller_start - $poller_lastrun - 10) > MAX_POLLER_RUNTIME) && ($poller_lastrun > 0)) {
|
||||||
cacti_log("WARNING: $task_type is out of sync with the Poller Interval! The Poller Interval is '$poller_interval' seconds, with a maximum of a '$min_period' second $task_type, but " . number_format_i18n($poller_start - $poller_lastrun, 1) . ' seconds have passed since the last poll!', true, 'POLLER');
|
cacti_log("WARNING: $task_type is out of sync with the Poller Interval! The Poller Interval is '$poller_interval' seconds, with a maximum of a '$min_period' second $task_type, but " .
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: %s is out of sync with the Poller Interval for Poller[%d]! The Poller Interval is %d seconds, with a maximum of a %d seconds, but %d seconds have passed since the last poll!', $task_type, $poller_id, $poller_interval, $min_period, number_format_i18n($poller_start - $poller_lastrun, 1)));
|
number_format_i18n($poller_start - $poller_lastrun,
|
||||||
|
1) . ' seconds have passed since the last poll!',
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: %s is out of sync with the Poller Interval for Poller[%d]! ' .
|
||||||
|
'The Poller Interval is %d seconds, with a maximum of a %d seconds, ' .
|
||||||
|
'but %d seconds have passed since the last poll!',
|
||||||
|
$task_type,
|
||||||
|
$poller_id,
|
||||||
|
$poller_interval,
|
||||||
|
$min_period,
|
||||||
|
number_format_i18n($poller_start - $poller_lastrun,
|
||||||
|
1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// used for current implementation for individual pollers
|
// used for current implementation for individual pollers
|
||||||
@@ -581,7 +607,11 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
$first_host = 0;
|
$first_host = 0;
|
||||||
$last_host = 0;
|
$last_host = 0;
|
||||||
$rrds_processed = 0;
|
$rrds_processed = 0;
|
||||||
$webroot = addslashes((CACTI_SERVER_OS == 'win32') ? strtr(cacti_strtolower(substr(__DIR__, 0, 1)) . substr(__DIR__, 1),'\\', '/') : __DIR__);
|
$webroot = addslashes((CACTI_SERVER_OS == 'win32') ? strtr(cacti_strtolower(substr(__DIR__,
|
||||||
|
0,
|
||||||
|
1)) . substr(__DIR__,
|
||||||
|
1),'\\',
|
||||||
|
'/') : __DIR__);
|
||||||
|
|
||||||
// update web paths for the poller
|
// update web paths for the poller
|
||||||
set_config_option('path_webroot', $webroot);
|
set_config_option('path_webroot', $webroot);
|
||||||
@@ -609,8 +639,13 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
[$poller_id], '', true, $poller_db_cnn_id);
|
[$poller_id], '', true, $poller_db_cnn_id);
|
||||||
|
|
||||||
if ($running_processes) {
|
if ($running_processes) {
|
||||||
cacti_log("WARNING: There are $running_processes processes detected as overrunning a polling cycle, please investigate", true, 'POLLER');
|
cacti_log("WARNING: There are $running_processes processes detected as overrunning a polling cycle, please investigate",
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: There are %d processes detected as overrunning a polling cycle for Poller[%d], please investigate.', $running_processes, $poller_id));
|
true,
|
||||||
|
'POLLER');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: There are %d processes detected as overrunning a polling cycle for Poller[%d], please investigate.',
|
||||||
|
$running_processes,
|
||||||
|
$poller_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
db_execute_prepared('DELETE FROM poller_time
|
db_execute_prepared('DELETE FROM poller_time
|
||||||
@@ -668,7 +703,11 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
if ($po_debounce == 0 || debounce_run_notification('poller_output_not_empty', $po_debounce)) {
|
if ($po_debounce == 0 || debounce_run_notification('poller_output_not_empty', $po_debounce)) {
|
||||||
cacti_log("WARNING: Poller Output Table not Empty. Issues: $count, $issue_list", true, 'POLLER');
|
cacti_log("WARNING: Poller Output Table not Empty. Issues: $count, $issue_list", true, 'POLLER');
|
||||||
|
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: Poller Output Table not empty for Poller[%d]. Issues: %d, %s.', $poller_id, $count, $issue_list));
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: Poller Output Table not empty for Poller[%d]. Issues: %d, %s.',
|
||||||
|
$poller_id,
|
||||||
|
$count,
|
||||||
|
$issue_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
db_execute_prepared('DELETE po ' . $issues_sql, $issues_param);
|
db_execute_prepared('DELETE po ' . $issues_sql, $issues_param);
|
||||||
@@ -686,7 +725,8 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
// The swapped-in copy inherits the engine, so only convert when it is
|
// The swapped-in copy inherits the engine, so only convert when it is
|
||||||
// not already MEMORY. This drops a metadata-locking ALTER from every
|
// not already MEMORY. This drops a metadata-locking ALTER from every
|
||||||
// poll cycle in the steady state.
|
// poll cycle in the steady state.
|
||||||
if (db_fetch_cell("SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'poller_output'") != 'MEMORY') {
|
if (db_fetch_cell('SELECT ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA = ' .
|
||||||
|
"DATABASE() AND TABLE_NAME = 'poller_output'") != 'MEMORY') {
|
||||||
db_execute('ALTER TABLE poller_output ENGINE=MEMORY');
|
db_execute('ALTER TABLE poller_output ENGINE=MEMORY');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,9 +753,14 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
|
|
||||||
// exit poller if spine is selected and file does not exist
|
// exit poller if spine is selected and file does not exist
|
||||||
if (($poller_type == '2') && (!file_exists(read_config_option('path_spine')))) {
|
if (($poller_type == '2') && (!file_exists(read_config_option('path_spine')))) {
|
||||||
cacti_log('ERROR: The spine path: ' . read_config_option('path_spine') . ' is invalid. Poller can not continue!', true, 'POLLER');
|
cacti_log('ERROR: The spine path: ' . read_config_option('path_spine') . ' is invalid. Poller can not continue!',
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
admin_email(__('Cacti System Warning'), __('ERROR: The spine path: %s is invalid for Poller[%d]. Poller can not continue!', read_config_option('path_spine'), $poller_id));
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('ERROR: The spine path: %s is invalid for Poller[%d]. Poller can not continue!',
|
||||||
|
read_config_option('path_spine'),
|
||||||
|
$poller_id));
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -788,7 +833,9 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
$host_count ++;
|
$host_count ++;
|
||||||
|
|
||||||
if ($change_proc) {
|
if ($change_proc) {
|
||||||
exec_background($command_string, "$extra_args --poller=$poller_id --first=$first_host --last=$last_host" . ($mibs ? ' --mibs' : ''), $extra_parms);
|
exec_background($command_string,
|
||||||
|
"$extra_args --poller=$poller_id --first=$first_host --last=$last_host" . ($mibs ? ' --mibs' : ''),
|
||||||
|
$extra_parms);
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
|
|
||||||
$host_count = 1;
|
$host_count = 1;
|
||||||
@@ -804,7 +851,9 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
if ($host_count > 1 && isset($item['id'])) {
|
if ($host_count > 1 && isset($item['id'])) {
|
||||||
$last_host = $item['id'];
|
$last_host = $item['id'];
|
||||||
|
|
||||||
exec_background($command_string, "$extra_args --poller=$poller_id --first=$first_host --last=$last_host" . ($mibs ? ' --mibs' : ''), $extra_parms);
|
exec_background($command_string,
|
||||||
|
"$extra_args --poller=$poller_id --first=$first_host --last=$last_host" . ($mibs ? ' --mibs' : ''),
|
||||||
|
$extra_parms);
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
|
|
||||||
$started_processes++;
|
$started_processes++;
|
||||||
@@ -845,7 +894,10 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
||||||
($poller_id == '1' ? $total_polling_hosts - 1 : $total_polling_hosts), $hosts_per_process, $num_polling_items, $rrds_processed);
|
($poller_id == '1' ? $total_polling_hosts - 1 : $total_polling_hosts),
|
||||||
|
$hosts_per_process,
|
||||||
|
$num_polling_items,
|
||||||
|
$rrds_processed);
|
||||||
|
|
||||||
poller_run_stats($loop_start);
|
poller_run_stats($loop_start);
|
||||||
|
|
||||||
@@ -867,7 +919,10 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
// end the process if the runtime exceeds MAX_POLLER_RUNTIME
|
// end the process if the runtime exceeds MAX_POLLER_RUNTIME
|
||||||
if (($poller_start + MAX_POLLER_RUNTIME) < time()) {
|
if (($poller_start + MAX_POLLER_RUNTIME) < time()) {
|
||||||
cacti_log('Maximum runtime of ' . MAX_POLLER_RUNTIME . ' seconds exceeded. Exiting.', true, 'POLLER');
|
cacti_log('Maximum runtime of ' . MAX_POLLER_RUNTIME . ' seconds exceeded. Exiting.', true, 'POLLER');
|
||||||
admin_email(__('Cacti System Warning'), __('Maximum runtime of %d seconds exceeded for Poller[%d]. Exiting.', MAX_POLLER_RUNTIME, $poller_id));
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('Maximum runtime of %d seconds exceeded for Poller[%d]. Exiting.',
|
||||||
|
MAX_POLLER_RUNTIME,
|
||||||
|
$poller_id));
|
||||||
|
|
||||||
// generate a snmp notification
|
// generate a snmp notification
|
||||||
snmpagent_poller_exiting();
|
snmpagent_poller_exiting();
|
||||||
@@ -875,7 +930,10 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
api_plugin_hook_function('poller_exiting');
|
api_plugin_hook_function('poller_exiting');
|
||||||
|
|
||||||
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
||||||
($poller_id == '1' ? $total_polling_hosts - 1 : $total_polling_hosts), $hosts_per_process, $num_polling_items, $rrds_processed);
|
($poller_id == '1' ? $total_polling_hosts - 1 : $total_polling_hosts),
|
||||||
|
$hosts_per_process,
|
||||||
|
$num_polling_items,
|
||||||
|
$rrds_processed);
|
||||||
|
|
||||||
poller_run_stats($loop_start);
|
poller_run_stats($loop_start);
|
||||||
|
|
||||||
@@ -894,7 +952,10 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
} else {
|
} else {
|
||||||
if ($poller_id > 1) {
|
if ($poller_id > 1) {
|
||||||
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
||||||
($poller_id === 1 ? $total_polling_hosts - 1 : $total_polling_hosts), $hosts_per_process, $num_polling_items, $rrds_processed);
|
($poller_id === 1 ? $total_polling_hosts - 1 : $total_polling_hosts),
|
||||||
|
$hosts_per_process,
|
||||||
|
$num_polling_items,
|
||||||
|
$rrds_processed);
|
||||||
|
|
||||||
poller_run_stats($loop_start);
|
poller_run_stats($loop_start);
|
||||||
|
|
||||||
@@ -1025,7 +1086,10 @@ while ($poller_runs_completed < $poller_runs) {
|
|||||||
|
|
||||||
if ($logged === false) {
|
if ($logged === false) {
|
||||||
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
log_cacti_stats($loop_start, $method, $concurrent_processes, $max_threads,
|
||||||
($poller_id == '1' ? $total_polling_hosts - 1 : $total_polling_hosts), $hosts_per_process, $num_polling_items, $rrds_processed);
|
($poller_id == '1' ? $total_polling_hosts - 1 : $total_polling_hosts),
|
||||||
|
$hosts_per_process,
|
||||||
|
$num_polling_items,
|
||||||
|
$rrds_processed);
|
||||||
|
|
||||||
poller_run_stats($loop_start);
|
poller_run_stats($loop_start);
|
||||||
}
|
}
|
||||||
@@ -1129,7 +1193,16 @@ function bad_index_check(bool $mibs) : void {
|
|||||||
$devices = explode(',', $bad_index_devices);
|
$devices = explode(',', $bad_index_devices);
|
||||||
$device_str = 'Device[' . implode('], Device[', $devices) . ']';
|
$device_str = 'Device[' . implode('], Device[', $devices) . ']';
|
||||||
|
|
||||||
cacti_log('WARNING: You have ' . cacti_sizeof($devices) . ' Devices with bad SNMP Indexes. Devices: ' . $device_str . ' totalling ' . $bad_indexes . ' Data Sources. Please Either Re-Index, Delete or Disable these Data Sources.', false, 'POLLER');
|
cacti_log('WARNING: You have ' .
|
||||||
|
cacti_sizeof($devices) .
|
||||||
|
' Devices with bad SNMP Indexes. Devices: ' .
|
||||||
|
$device_str .
|
||||||
|
' totalling ' .
|
||||||
|
$bad_indexes .
|
||||||
|
(' Data Sources. Please Either Re-Index, Delete or Disable these Data ' .
|
||||||
|
'Sources.'),
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1190,7 +1263,11 @@ function poller_replicate_check() : void {
|
|||||||
if (cacti_sizeof($pollers)) {
|
if (cacti_sizeof($pollers)) {
|
||||||
foreach ($pollers as $poller) {
|
foreach ($pollers as $poller) {
|
||||||
$command_string = cacti_escapeshellcmd((string) read_config_option('path_php_binary'));
|
$command_string = cacti_escapeshellcmd((string) read_config_option('path_php_binary'));
|
||||||
$extra_args = '-q ' . cacti_escapeshellarg(CACTI_PATH_CLI . '/poller_replicate.php') . ' --poller=' . $poller['id'];
|
$extra_args = '-q ' .
|
||||||
|
cacti_escapeshellarg(CACTI_PATH_CLI .
|
||||||
|
'/poller_replicate.php') .
|
||||||
|
' --poller=' .
|
||||||
|
$poller['id'];
|
||||||
exec_background($command_string, $extra_args);
|
exec_background($command_string, $extra_args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1209,12 +1286,18 @@ function poller_enabled_check(int $poller_id) : void {
|
|||||||
$should_exit = false;
|
$should_exit = false;
|
||||||
|
|
||||||
if ($system_enabled == '') {
|
if ($system_enabled == '') {
|
||||||
cacti_log('WARNING: System Polling is Disabled! Therefore, data collection from the poller will be suspended till re-enabled.', true, 'SYSTEM');
|
cacti_log('WARNING: System Polling is Disabled! Therefore, data collection from ' .
|
||||||
|
'the poller will be suspended till re-enabled.',
|
||||||
|
true,
|
||||||
|
'SYSTEM');
|
||||||
$should_exit = true;
|
$should_exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($poller_disabled == 'on') {
|
if ($poller_disabled == 'on') {
|
||||||
cacti_log('WARNING: Poller ' . $poller_id . ' is Disabled. Therefore, data collection for this Poller will be suspended till it\'s re-enabled.', true, 'SYSTEM');
|
cacti_log('WARNING: Poller ' . $poller_id . (' is Disabled. Therefore, data collection for this Poller will be ' .
|
||||||
|
'suspended till it\'s re-enabled.'),
|
||||||
|
true,
|
||||||
|
'SYSTEM');
|
||||||
$should_exit = true;
|
$should_exit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1331,7 +1414,10 @@ function log_cacti_stats(float $loop_start, string $method, int $concurrent_proc
|
|||||||
$totalErrors
|
$totalErrors
|
||||||
];
|
];
|
||||||
|
|
||||||
$cacti_stats = vsprintf('Time:%01.4f Method:%s Processes:%s Threads:%s Hosts:%s HostsPerProcess:%s DataSources:%s RRDsProcessed:%s ErrorHosts:%s TotalErrors:%s', $perf_data);
|
$cacti_stats = vsprintf('Time:%01.4f Method:%s Processes:%s Threads:%s Hosts:%s ' .
|
||||||
|
'HostsPerProcess:%s DataSources:%s RRDsProcessed:%s ErrorHosts:%s ' .
|
||||||
|
'TotalErrors:%s',
|
||||||
|
$perf_data);
|
||||||
cacti_log('STATS: ' . $cacti_stats , true, 'SYSTEM');
|
cacti_log('STATS: ' . $cacti_stats , true, 'SYSTEM');
|
||||||
|
|
||||||
// insert poller stats into the settings table
|
// insert poller stats into the settings table
|
||||||
@@ -1408,12 +1494,25 @@ function poller_run_stats(float $loop_start) : bool {
|
|||||||
if ($count > 0) {
|
if ($count > 0) {
|
||||||
$ratio = round($sum / $count, 2);
|
$ratio = round($sum / $count, 2);
|
||||||
|
|
||||||
cacti_log(sprintf('24 Hour Average Poller run time is %0.2f seconds, min: %s , max: %s', $ratio, $min, $max), true, 'POLLER');
|
cacti_log(sprintf('24 Hour Average Poller run time is %0.2f seconds, min: %s , max: %s',
|
||||||
|
$ratio,
|
||||||
|
$min,
|
||||||
|
$max),
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
if ($ratio / $poller_interval > $threshold_24h / 100 && $threshold_24h > 0) {
|
if ($ratio / $poller_interval > $threshold_24h / 100 && $threshold_24h > 0) {
|
||||||
cacti_log(sprintf('WARNING: 24 Hour Poller Average run time reached more than %s percent of time limit.', $threshold_24h), true, 'POLLER');
|
cacti_log(sprintf('WARNING: 24 Hour Poller Average run time reached more than %s percent of time limit.',
|
||||||
|
$threshold_24h),
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: 24 Hour Poller[%d] Average run time threshold breached. It is %f seconds (more than %d % of threshold.)', $poller_id, $ratio, $threshold_24h));
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: 24 Hour Poller[%d] Average run time threshold breached. It ' .
|
||||||
|
'is %f seconds (more than %d % of threshold.)',
|
||||||
|
$poller_id,
|
||||||
|
$ratio,
|
||||||
|
$threshold_24h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1427,9 +1526,21 @@ function poller_run_stats(float $loop_start) : bool {
|
|||||||
[$poller_interval, $threshold_1h]);
|
[$poller_interval, $threshold_1h]);
|
||||||
|
|
||||||
if ($count > $threshold_1h_count && $threshold_1h_count > 0) {
|
if ($count > $threshold_1h_count && $threshold_1h_count > 0) {
|
||||||
cacti_log(sprintf('WARNING: In the last hour, the Poller run time exceeded the threshold %d times (limit %d) by %d percent of time limit.', $count, $threshold_1h_count, $threshold_1h) , true, 'POLLER');
|
cacti_log(sprintf('WARNING: In the last hour, the Poller run time exceeded the threshold ' .
|
||||||
|
'%d times (limit %d) by %d percent of time limit.',
|
||||||
|
$count,
|
||||||
|
$threshold_1h_count,
|
||||||
|
$threshold_1h) ,
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: In last hour Poller[%d] run time exceeded the threshold %d times (limit %d) by %d percent of the time limit.', $poller_id, $count, $threshold_1h_count, $threshold_1h));
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: In last hour Poller[%d] run time exceeded the threshold %d ' .
|
||||||
|
'times (limit %d) by %d percent of the time limit.',
|
||||||
|
$poller_id,
|
||||||
|
$count,
|
||||||
|
$threshold_1h_count,
|
||||||
|
$threshold_1h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1451,9 +1562,12 @@ function multiple_poller_boost_check() : void {
|
|||||||
AND id > 1');
|
AND id > 1');
|
||||||
|
|
||||||
if ($pollers > 0 && read_config_option('boost_rrd_update_enable') == '') {
|
if ($pollers > 0 && read_config_option('boost_rrd_update_enable') == '') {
|
||||||
cacti_log('NOTE: A second Cacti data collector has been added. Therefore, enabling boost automatically!', false, 'POLLER');
|
cacti_log('NOTE: A second Cacti data collector has been added. Therefore, enabling boost automatically!',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
admin_email(__('Cacti System Notification'), __('NOTE: A second Cacti data collector has been added. Therefore, enabling boost automatically!'));
|
admin_email(__('Cacti System Notification'),
|
||||||
|
__('NOTE: A second Cacti data collector has been added. Therefore, enabling boost automatically!'));
|
||||||
|
|
||||||
set_config_option('boost_rrd_update_enable', 'on');
|
set_config_option('boost_rrd_update_enable', 'on');
|
||||||
set_config_option('boost_rrd_update_system_enable', 'on');
|
set_config_option('boost_rrd_update_system_enable', 'on');
|
||||||
|
|||||||
+77
-15
@@ -53,8 +53,13 @@ if (POLLER_ID > 1) {
|
|||||||
if (CACTI_CONNECTION == 'online') {
|
if (CACTI_CONNECTION == 'online') {
|
||||||
db_force_remote_cnn();
|
db_force_remote_cnn();
|
||||||
} elseif (debounce_run_notification('db_offline')) {
|
} elseif (debounce_run_notification('db_offline')) {
|
||||||
cacti_log(sprintf('WARNING: Main Cacti database %s offline or in recovery. Can not run automation', $rdatabase_hostname), true, 'AUTOM8');
|
cacti_log(sprintf('WARNING: Main Cacti database %s offline or in recovery. Can not run automation',
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: Main Cacti database %s offline or in recovery', $rdatabase_hostname));
|
$rdatabase_hostname),
|
||||||
|
true,
|
||||||
|
'AUTOM8');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: Main Cacti database %s offline or in recovery',
|
||||||
|
$rdatabase_hostname));
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -232,7 +237,10 @@ if (!$master && $thread == 0) {
|
|||||||
[$network_id, $poller_id]);
|
[$network_id, $poller_id]);
|
||||||
|
|
||||||
if ($status != 'on' && !$force) {
|
if ($status != 'on' && !$force) {
|
||||||
cacti_log(automation_get_pid() . " WARNING: The Network ID: $network_id is disabled. You must use the 'force' option to force its execution.", true, 'AUTOM8');
|
cacti_log(automation_get_pid() .
|
||||||
|
" WARNING: The Network ID: $network_id is disabled. You must use the 'force' option to force its execution.",
|
||||||
|
true,
|
||||||
|
'AUTOM8');
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -253,7 +261,9 @@ if ($master) {
|
|||||||
if (cacti_sizeof($networks)) {
|
if (cacti_sizeof($networks)) {
|
||||||
foreach ($networks as $network) {
|
foreach ($networks as $network) {
|
||||||
if ($network['snmp_id'] == 0) {
|
if ($network['snmp_id'] == 0) {
|
||||||
cacti_log("ERROR: Automation can not run for Network '" . $network['name'] . "' since the SNMP ID is not set.", true, 'AUTOM8');
|
cacti_log("ERROR: Automation can not run for Network '" . $network['name'] . "' since the SNMP ID is not set.",
|
||||||
|
true,
|
||||||
|
'AUTOM8');
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -267,7 +277,15 @@ if ($master) {
|
|||||||
if (api_scheduler_is_time_to_start($network) || $force) {
|
if (api_scheduler_is_time_to_start($network) || $force) {
|
||||||
automation_debug("Launching Network Master for '" . $network['name'] . "'\n");
|
automation_debug("Launching Network Master for '" . $network['name'] . "'\n");
|
||||||
|
|
||||||
exec_background(read_config_option('path_php_binary'), '-q ' . read_config_option('path_webroot') . '/poller_automation.php --poller=' . $poller_id . ' --network=' . $network['id'] . ($force ? ' --force' : '') . ($debug ? ' --debug' : ''));
|
exec_background(read_config_option('path_php_binary'),
|
||||||
|
'-q ' .
|
||||||
|
read_config_option('path_webroot') .
|
||||||
|
'/poller_automation.php --poller=' .
|
||||||
|
$poller_id .
|
||||||
|
' --network=' .
|
||||||
|
$network['id'] .
|
||||||
|
($force ? ' --force' : '') .
|
||||||
|
($debug ? ' --debug' : ''));
|
||||||
|
|
||||||
$launched++;
|
$launched++;
|
||||||
|
|
||||||
@@ -349,7 +367,14 @@ if ($master === false && $thread == 0) {
|
|||||||
|
|
||||||
while ($curthread <= $threads) {
|
while ($curthread <= $threads) {
|
||||||
automation_debug("Launching Thread $curthread\n");
|
automation_debug("Launching Thread $curthread\n");
|
||||||
exec_background(read_config_option('path_php_binary'), '-q ' . read_config_option('path_webroot') . '/poller_automation.php --poller=' . $poller_id . " --thread=$curthread --network=$network_id" . ($force ? ' --force' : '') . ($debug ? ' --debug' : ''));
|
exec_background(read_config_option('path_php_binary'),
|
||||||
|
'-q ' .
|
||||||
|
read_config_option('path_webroot') .
|
||||||
|
'/poller_automation.php --poller=' .
|
||||||
|
$poller_id .
|
||||||
|
" --thread=$curthread --network=$network_id" .
|
||||||
|
($force ? ' --force' : '') .
|
||||||
|
($debug ? ' --debug' : ''));
|
||||||
$curthread++;
|
$curthread++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,10 +501,18 @@ function discoverDevices(int $network_id, int $thread) : bool {
|
|||||||
if (cacti_sizeof($device) && isset($device['ip_address'])) {
|
if (cacti_sizeof($device) && isset($device['ip_address'])) {
|
||||||
$count++;
|
$count++;
|
||||||
|
|
||||||
cacti_log(automation_get_pid() . ' NOTE: Found device IP address \'' . $device['ip_address'] . '\' to check', false, 'AUTOM8', POLLER_VERBOSITY_MEDIUM);
|
cacti_log(automation_get_pid() . ' NOTE: Found device IP address \'' . $device['ip_address'] . '\' to check',
|
||||||
|
false,
|
||||||
|
'AUTOM8',
|
||||||
|
POLLER_VERBOSITY_MEDIUM);
|
||||||
|
|
||||||
if (!filter_var($device['ip_address'], FILTER_VALIDATE_IP)) {
|
if (!filter_var($device['ip_address'], FILTER_VALIDATE_IP)) {
|
||||||
cacti_log(automation_get_pid() . ' WARNING: IP address \'' . $device['ip_address'] . '\' is not a valid IP address.', false, 'AUTOM8');
|
cacti_log(automation_get_pid() .
|
||||||
|
' WARNING: IP address \'' .
|
||||||
|
$device['ip_address'] .
|
||||||
|
'\' is not a valid IP address.',
|
||||||
|
false,
|
||||||
|
'AUTOM8');
|
||||||
|
|
||||||
markIPDone($device['ip_address'], $network_id);
|
markIPDone($device['ip_address'], $network_id);
|
||||||
|
|
||||||
@@ -918,7 +951,8 @@ function discoverDevices(int $network_id, int $thread) : bool {
|
|||||||
|
|
||||||
automation_debug("\n");
|
automation_debug("\n");
|
||||||
} else {
|
} else {
|
||||||
automation_debug(", Status: Ignoring Address (PHP Bug does not allow us to ping .255 as it thinks its a broadcast IP)!\n");
|
automation_debug(', Status: Ignoring Address (PHP Bug does not allow us to ping .255 as ' .
|
||||||
|
"it thinks its a broadcast IP)!\n");
|
||||||
markIPDone($device['ip_address'], $network_id);
|
markIPDone($device['ip_address'], $network_id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -947,7 +981,22 @@ function discoverDevices(int $network_id, int $thread) : bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log(automation_get_pid() . ' Network ' . $network['name'] . " Thread $thread Finished, " . $stats['scanned'] . ' IPs Scanned, ' . $stats['ping'] . ' IPs Responded to Ping, ' . $stats['snmp'] . ' Responded to SNMP, ' . $stats['added'] . ' Device Added, ' . $count_graph . ' Graphs Added to Cacti', true, 'AUTOM8');
|
cacti_log(automation_get_pid() .
|
||||||
|
' Network ' .
|
||||||
|
$network['name'] .
|
||||||
|
" Thread $thread Finished, " .
|
||||||
|
$stats['scanned'] .
|
||||||
|
' IPs Scanned, ' .
|
||||||
|
$stats['ping'] .
|
||||||
|
' IPs Responded to Ping, ' .
|
||||||
|
$stats['snmp'] .
|
||||||
|
' Responded to SNMP, ' .
|
||||||
|
$stats['added'] .
|
||||||
|
' Device Added, ' .
|
||||||
|
$count_graph .
|
||||||
|
' Graphs Added to Cacti',
|
||||||
|
true,
|
||||||
|
'AUTOM8');
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1106,7 +1155,9 @@ function reportNetworkStatus(int $network_id, array $old_devices) : bool {
|
|||||||
$admin_user = read_config_option('admin_user');
|
$admin_user = read_config_option('admin_user');
|
||||||
|
|
||||||
if ($admin_user == '') {
|
if ($admin_user == '') {
|
||||||
cacti_log('WARNING: Unable to send Automation Notification Email. No Primary Admin User Account specified.', false, 'POLLER');
|
cacti_log('WARNING: Unable to send Automation Notification Email. No Primary Admin User Account specified.',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1117,18 +1168,27 @@ function reportNetworkStatus(int $network_id, array $old_devices) : bool {
|
|||||||
[$admin_user]);
|
[$admin_user]);
|
||||||
|
|
||||||
if (!cacti_sizeof($details)) {
|
if (!cacti_sizeof($details)) {
|
||||||
cacti_log('WARNING: Unable to send Automation Notification Email. The Primary Admin User Account does not exist.', false, 'POLLER');
|
cacti_log('WARNING: Unable to send Automation Notification Email. The Primary ' .
|
||||||
|
'Admin User Account does not exist.',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($details['notification_email'] == '') {
|
if ($details['notification_email'] == '') {
|
||||||
cacti_log('WARNING: Unable to send Automation Notification Email. The Primary Admin User Account does not have an Email Address.', false, 'POLLER');
|
cacti_log('WARNING: Unable to send Automation Notification Email. The Primary ' .
|
||||||
|
'Admin User Account does not have an Email Address.',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$email = ($details['full_name'] != '' ? $details['full_name'] : __('Cacti Primary Admin')) . ' <' . $details['notification_email'] . '>';
|
$email = ($details['full_name'] != '' ? $details['full_name'] : __('Cacti Primary Admin')) .
|
||||||
|
' <' .
|
||||||
|
$details['notification_email'] .
|
||||||
|
'>';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1232,7 +1292,9 @@ function reportNetworkStatus(int $network_id, array $old_devices) : bool {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (strlen($error)) {
|
if (strlen($error)) {
|
||||||
cacti_log("WARNING: Automation had problems sending to '$email' for $status. The error was '$error'", false, 'AUTOM8');
|
cacti_log("WARNING: Automation had problems sending to '$email' for $status. The error was '$error'",
|
||||||
|
false,
|
||||||
|
'AUTOM8');
|
||||||
} else {
|
} else {
|
||||||
cacti_log("NOTICE: Email Notification Sent to '$email' for $status.", false, 'AUTOM8');
|
cacti_log("NOTICE: Email Notification Sent to '$email' for $status.", false, 'AUTOM8');
|
||||||
}
|
}
|
||||||
|
|||||||
+98
-23
@@ -185,12 +185,20 @@ if ($child == false) {
|
|||||||
*/
|
*/
|
||||||
if ($boost_debug && $boost_log != '') {
|
if ($boost_debug && $boost_log != '') {
|
||||||
if (dirname($cacti_log) != dirname($boost_log)) {
|
if (dirname($cacti_log) != dirname($boost_log)) {
|
||||||
cacti_log(sprintf('WARNING: Boost Debug Log location:%s must be in the same directory as the Cacti Log location:%s. Change the path to a correct location', $boost_log, $cacti_log), true, 'BOOST');
|
cacti_log(sprintf('WARNING: Boost Debug Log location:%s must be in the same directory as ' .
|
||||||
|
'the Cacti Log location:%s. Change the path to a correct location',
|
||||||
|
$boost_log,
|
||||||
|
$cacti_log),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
} elseif (!file_exists($boost_log)) {
|
} elseif (!file_exists($boost_log)) {
|
||||||
if (is_writable(dirname($boost_log))) {
|
if (is_writable(dirname($boost_log))) {
|
||||||
touch($boost_log);
|
touch($boost_log);
|
||||||
} else {
|
} else {
|
||||||
cacti_log(sprintf('WARNING: Boost Debug Log %s is not writable. Change the path to a writable location', $boost_log), true, 'BOOST');
|
cacti_log(sprintf('WARNING: Boost Debug Log %s is not writable. Change the path to a writable location',
|
||||||
|
$boost_log),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -251,26 +259,42 @@ if ($child == false) {
|
|||||||
// under them.
|
// under them.
|
||||||
$startup_deadline = time() + 30;
|
$startup_deadline = time() + 30;
|
||||||
|
|
||||||
while (!boost_all_children_registered($expected_children, boost_processes_running(), boost_completed_children($run_id)) && time() < $startup_deadline) {
|
while (!boost_all_children_registered($expected_children,
|
||||||
|
boost_processes_running(),
|
||||||
|
boost_completed_children($run_id)) &&
|
||||||
|
time() < $startup_deadline) {
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!boost_all_children_registered($expected_children, boost_processes_running(), boost_completed_children($run_id))) {
|
if (!boost_all_children_registered($expected_children,
|
||||||
cacti_log(sprintf('WARNING: Boost startup barrier timed out; %d of %d children registered before draining.', boost_processes_running() + boost_completed_children($run_id), $expected_children), true, 'BOOST');
|
boost_processes_running(),
|
||||||
|
boost_completed_children($run_id))) {
|
||||||
|
cacti_log(sprintf('WARNING: Boost startup barrier timed out; %d of %d children registered before draining.',
|
||||||
|
boost_processes_running() + boost_completed_children($run_id),
|
||||||
|
$expected_children),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain until no child is running and every launched child has
|
// Drain until no child is running and every launched child has
|
||||||
// recorded a completion row, not merely when none are running -- a
|
// recorded a completion row, not merely when none are running -- a
|
||||||
// sibling may not have started yet.
|
// sibling may not have started yet.
|
||||||
while (boost_processes_running() > 0 || boost_completed_children($run_id) < $expected_children) {
|
while (boost_processes_running() > 0 || boost_completed_children($run_id) < $expected_children) {
|
||||||
boost_debug(sprintf('%d Processes Running, %d of %d Completed, Sleeping for 2 seconds.', boost_processes_running(), boost_completed_children($run_id), $expected_children));
|
boost_debug(sprintf('%d Processes Running, %d of %d Completed, Sleeping for 2 seconds.',
|
||||||
|
boost_processes_running(),
|
||||||
|
boost_completed_children($run_id),
|
||||||
|
$expected_children));
|
||||||
sleep(2);
|
sleep(2);
|
||||||
|
|
||||||
if (boost_processes_running() === 0 && boost_completed_children($run_id) < $expected_children) {
|
if (boost_processes_running() === 0 && boost_completed_children($run_id) < $expected_children) {
|
||||||
// All registered children exited but fewer completion rows than
|
// All registered children exited but fewer completion rows than
|
||||||
// expected: a child crashed before recording status. Stop waiting
|
// expected: a child crashed before recording status. Stop waiting
|
||||||
// so the parent does not spin forever.
|
// so the parent does not spin forever.
|
||||||
cacti_log(sprintf('WARNING: Boost drained with %d of %d completion rows; a child may have crashed.', boost_completed_children($run_id), $expected_children), true, 'BOOST');
|
cacti_log(sprintf('WARNING: Boost drained with %d of %d completion rows; a child may have crashed.',
|
||||||
|
boost_completed_children($run_id),
|
||||||
|
$expected_children),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -295,7 +319,11 @@ if ($child == false) {
|
|||||||
if ($failed_children > 0) {
|
if ($failed_children > 0) {
|
||||||
boost_log_statistics($rrd_updates);
|
boost_log_statistics($rrd_updates);
|
||||||
set_config_option('boost_last_run_time', $last_run_time);
|
set_config_option('boost_last_run_time', $last_run_time);
|
||||||
cacti_log(sprintf('WARNING: Boost retained archive tables because %d child process(es) reported an RRD update failure.', $failed_children), true, 'BOOST');
|
cacti_log(sprintf('WARNING: Boost retained archive tables because %d child process(es) ' .
|
||||||
|
'reported an RRD update failure.',
|
||||||
|
$failed_children),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
} elseif ($rrd_updates > 0) {
|
} elseif ($rrd_updates > 0) {
|
||||||
boost_log_statistics($rrd_updates);
|
boost_log_statistics($rrd_updates);
|
||||||
$next_run_time = $current_time + $seconds_offset;
|
$next_run_time = $current_time + $seconds_offset;
|
||||||
@@ -329,7 +357,12 @@ if ($child == false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cacti_log(sprintf('WARNING: Boost run only completed %d of %d shards; leaving archive tables in place for the next run to pick up.', boost_completed_children($run_id), $expected_children), true, 'BOOST');
|
cacti_log(sprintf('WARNING: Boost run only completed %d of %d shards; leaving archive ' .
|
||||||
|
'tables in place for the next run to pick up.',
|
||||||
|
boost_completed_children($run_id),
|
||||||
|
$expected_children),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
}
|
}
|
||||||
|
|
||||||
dsstats_boost_bottom();
|
dsstats_boost_bottom();
|
||||||
@@ -447,7 +480,11 @@ function boost_kill_running_processes() : void {
|
|||||||
if (cacti_sizeof($processes)) {
|
if (cacti_sizeof($processes)) {
|
||||||
foreach ($processes as $p) {
|
foreach ($processes as $p) {
|
||||||
if (cacti_process_still_running((int) $p['pid'])) {
|
if (cacti_process_still_running((int) $p['pid'])) {
|
||||||
cacti_log(sprintf('WARNING: Killing Boost %s PID %d due to another boost process starting.', ucfirst($p['taskname']), $p['pid']), true, 'BOOST');
|
cacti_log(sprintf('WARNING: Killing Boost %s PID %d due to another boost process starting.',
|
||||||
|
ucfirst($p['taskname']),
|
||||||
|
$p['pid']),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
|
|
||||||
cacti_process_kill((int) $p['pid'], SIGTERM, 'BOOST');
|
cacti_process_kill((int) $p['pid'], SIGTERM, 'BOOST');
|
||||||
}
|
}
|
||||||
@@ -506,7 +543,9 @@ function boost_prepare_process_table() : bool {
|
|||||||
if ($previous_start_time + $max_run_duration < $start_time) {
|
if ($previous_start_time + $max_run_duration < $start_time) {
|
||||||
cacti_log('WARNING: Detected Poller Boost Overrun, Possible Boost Poller Crash', true, 'BOOST SVR');
|
cacti_log('WARNING: Detected Poller Boost Overrun, Possible Boost Poller Crash', true, 'BOOST SVR');
|
||||||
|
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: Detected Poller Boost Overrun, Possible Boost Poller Crash', 'BOOST SVR'));
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: Detected Poller Boost Overrun, Possible Boost Poller Crash',
|
||||||
|
'BOOST SVR'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -970,7 +1009,9 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
set_config_option('rrdtool_version', $rrdtool_ins_version);
|
set_config_option('rrdtool_version', $rrdtool_ins_version);
|
||||||
$rrdtool_version = $rrdtool_ins_version;
|
$rrdtool_version = $rrdtool_ins_version;
|
||||||
} elseif ($rrdtool_ins_version === false) {
|
} elseif ($rrdtool_ins_version === false) {
|
||||||
cacti_log('WARNING: Unable to detect the installed RRDtool version; retaining the configured capability level.', true, 'BOOST');
|
cacti_log('WARNING: Unable to detect the installed RRDtool version; retaining the configured capability level.',
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1027,7 +1068,9 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
$sub_query_string = '';
|
$sub_query_string = '';
|
||||||
|
|
||||||
foreach ($archive_tables as $table) {
|
foreach ($archive_tables as $table) {
|
||||||
$sub_query_string .= ($sub_query_string != '' ? ' UNION ALL ' : '') . boost_archive_select_sql($table, $last_id, $child);
|
$sub_query_string .= ($sub_query_string != '' ? ' UNION ALL ' : '') . boost_archive_select_sql($table,
|
||||||
|
$last_id,
|
||||||
|
$child);
|
||||||
}
|
}
|
||||||
|
|
||||||
$query_string = 'SELECT * FROM (' . $sub_query_string . ') t ORDER BY local_data_id ASC, timestamp ASC, rrd_name ASC';
|
$query_string = 'SELECT * FROM (' . $sub_query_string . ') t ORDER BY local_data_id ASC, timestamp ASC, rrd_name ASC';
|
||||||
@@ -1076,7 +1119,9 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
|
|
||||||
// go through each poller_output_boost entries and process
|
// go through each poller_output_boost entries and process
|
||||||
foreach ($results as $item) {
|
foreach ($results as $item) {
|
||||||
if ($local_data_id == $item['local_data_id'] && cacti_sizeof($unused_data_source_names) && isset($unused_data_source_names[$item['rrd_name']])) {
|
if ($local_data_id == $item['local_data_id'] &&
|
||||||
|
cacti_sizeof($unused_data_source_names) &&
|
||||||
|
isset($unused_data_source_names[$item['rrd_name']])) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1101,7 +1146,8 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
*/
|
*/
|
||||||
if ($local_data_id != $item['local_data_id']) {
|
if ($local_data_id != $item['local_data_id']) {
|
||||||
// orphan filter applies to templated sources only; cached per data source
|
// orphan filter applies to templated sources only; cached per data source
|
||||||
$unused_data_source_names = $item['data_template_id'] > 0 ? poller_get_unused_data_source_names($item['local_data_id'], $unused_cache) : [];
|
$unused_data_source_names = $item['data_template_id'] > 0 ? poller_get_unused_data_source_names($item['local_data_id'],
|
||||||
|
$unused_cache) : [];
|
||||||
|
|
||||||
if ($unused_data_source_names === false) {
|
if ($unused_data_source_names === false) {
|
||||||
$updates_ok = false;
|
$updates_ok = false;
|
||||||
@@ -1193,7 +1239,14 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
|
|
||||||
// don't generate error messages if the RRD has already been updated
|
// don't generate error messages if the RRD has already been updated
|
||||||
if ($time < $last_update && cacti_version_compare(get_rrdtool_version(), '1.5', '<')) {
|
if ($time < $last_update && cacti_version_compare(get_rrdtool_version(), '1.5', '<')) {
|
||||||
cacti_log("WARNING: Stale Poller Data Found! Item Time:'" . $time . "', RRD Time:'" . $last_update . "' Ignoring Value!", true, 'BOOST', POLLER_VERBOSITY_HIGH);
|
cacti_log("WARNING: Stale Poller Data Found! Item Time:'" .
|
||||||
|
$time .
|
||||||
|
"', RRD Time:'" .
|
||||||
|
$last_update .
|
||||||
|
"' Ignoring Value!",
|
||||||
|
true,
|
||||||
|
'BOOST',
|
||||||
|
POLLER_VERBOSITY_HIGH);
|
||||||
|
|
||||||
$value = 'DNP';
|
$value = 'DNP';
|
||||||
} else {
|
} else {
|
||||||
@@ -1292,7 +1345,8 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
* We have to check for Non-Templated Data Source first as they may not include
|
* We have to check for Non-Templated Data Source first as they may not include
|
||||||
* a graph. So, for that case, we need the RRDfile to include all data sources
|
* a graph. So, for that case, we need the RRDfile to include all data sources
|
||||||
*/
|
*/
|
||||||
$nt_rrd_field_names = $item['data_template_id'] == 0 ? poller_get_nt_rrd_field_names($item['local_data_id'], $nt_cache) : [];
|
$nt_rrd_field_names = $item['data_template_id'] == 0 ? poller_get_nt_rrd_field_names($item['local_data_id'],
|
||||||
|
$nt_cache) : [];
|
||||||
|
|
||||||
if ($nt_rrd_field_names === false) {
|
if ($nt_rrd_field_names === false) {
|
||||||
$updates_ok = false;
|
$updates_ok = false;
|
||||||
@@ -1329,7 +1383,13 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
$buflen += 2;
|
$buflen += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost_debug("Parsed MULTI output field '" . $matches[0] . "' [map " . $matches[1] . '->' . $nt_rrd_field_names[$matches[1]] . ']');
|
boost_debug("Parsed MULTI output field '" .
|
||||||
|
$matches[0] .
|
||||||
|
"' [map " .
|
||||||
|
$matches[1] .
|
||||||
|
'->' .
|
||||||
|
$nt_rrd_field_names[$matches[1]] .
|
||||||
|
']');
|
||||||
}
|
}
|
||||||
|
|
||||||
$vals_in_buffer++;
|
$vals_in_buffer++;
|
||||||
@@ -1339,7 +1399,8 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($reset_template) {
|
if ($reset_template) {
|
||||||
$unused_data_source_names = $item['data_template_id'] > 0 ? poller_get_unused_data_source_names($item['local_data_id'], $unused_cache) : [];
|
$unused_data_source_names = $item['data_template_id'] > 0 ? poller_get_unused_data_source_names($item['local_data_id'],
|
||||||
|
$unused_cache) : [];
|
||||||
|
|
||||||
if ($unused_data_source_names === false) {
|
if ($unused_data_source_names === false) {
|
||||||
$updates_ok = false;
|
$updates_ok = false;
|
||||||
@@ -1400,7 +1461,12 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log(sprintf('WARNING: Invalid output! MULTI DS[%d] Encountered [%s] Expected[%s]', $item['local_data_id'], $value, $expected), true, 'POLLER');
|
cacti_log(sprintf('WARNING: Invalid output! MULTI DS[%d] Encountered [%s] Expected[%s]',
|
||||||
|
$item['local_data_id'],
|
||||||
|
$value,
|
||||||
|
$expected),
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1433,7 +1499,11 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
AND process_handler = ?',
|
AND process_handler = ?',
|
||||||
[$last_id, $child]);
|
[$last_id, $child]);
|
||||||
} else {
|
} else {
|
||||||
cacti_log(sprintf('WARNING: Boost retained shard %d through local data ID %d because one or more RRD updates failed.', $child, $last_id), true, 'BOOST');
|
cacti_log(sprintf('WARNING: Boost retained shard %d through local data ID %d because one or more RRD updates failed.',
|
||||||
|
$child,
|
||||||
|
$last_id),
|
||||||
|
true,
|
||||||
|
'BOOST');
|
||||||
}
|
}
|
||||||
|
|
||||||
boost_timer('delete', BOOST_TIMER_END);
|
boost_timer('delete', BOOST_TIMER_END);
|
||||||
@@ -1445,7 +1515,11 @@ function boost_process_local_data_ids(int $last_id, int $child, mixed $rrdtool_p
|
|||||||
return $updates_ok && $results !== false ? cacti_sizeof($results) : -1;
|
return $updates_ok && $results !== false ? cacti_sizeof($results) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function boost_process_output(int $local_data_id, array $outarray, string $rrd_path, array $rrd_tmplp, mixed $rrdtool_pipe) : bool {
|
function boost_process_output(int $local_data_id,
|
||||||
|
array $outarray,
|
||||||
|
string $rrd_path,
|
||||||
|
array $rrd_tmplp,
|
||||||
|
mixed $rrdtool_pipe) : bool {
|
||||||
$outbuf = '';
|
$outbuf = '';
|
||||||
|
|
||||||
if (cacti_sizeof($outarray)) {
|
if (cacti_sizeof($outarray)) {
|
||||||
@@ -1589,7 +1663,8 @@ function boost_log_child_statistics(int $rrd_updates, int $child) : void {
|
|||||||
|
|
||||||
foreach ($boost_stats_log as $area => $entry) {
|
foreach ($boost_stats_log as $area => $entry) {
|
||||||
if (isset($entry[BOOST_TIMER_TOTAL])) {
|
if (isset($entry[BOOST_TIMER_TOTAL])) {
|
||||||
$output[$area] = round($entry[BOOST_TIMER_TOTAL] - (($overhead * $entry[BOOST_TIMER_CYCLES]) / BOOST_TIMER_OVERHEAD_MULTIPLIER), 2);
|
$output[$area] = round($entry[BOOST_TIMER_TOTAL] - (($overhead * $entry[BOOST_TIMER_CYCLES]) / BOOST_TIMER_OVERHEAD_MULTIPLIER),
|
||||||
|
2);
|
||||||
}
|
}
|
||||||
|
|
||||||
$timer_cycles += $entry[BOOST_TIMER_CYCLES];
|
$timer_cycles += $entry[BOOST_TIMER_CYCLES];
|
||||||
|
|||||||
+20
-4
@@ -173,7 +173,11 @@ if ($host_id === false) {
|
|||||||
// take time to log performance data
|
// take time to log performance data
|
||||||
$recache = microtime(true);
|
$recache = microtime(true);
|
||||||
|
|
||||||
$recache_stats = sprintf('Poller:%s RecacheTime:%01.4f DevicesRecached:%s', $poller_id, round($recache - $start, 4), cacti_sizeof($hosts));
|
$recache_stats = sprintf('Poller:%s RecacheTime:%01.4f DevicesRecached:%s',
|
||||||
|
$poller_id,
|
||||||
|
round($recache - $start,
|
||||||
|
4),
|
||||||
|
cacti_sizeof($hosts));
|
||||||
|
|
||||||
if (cacti_sizeof($hosts)) {
|
if (cacti_sizeof($hosts)) {
|
||||||
cacti_log('STATS: ' . $recache_stats, true, 'RECACHE');
|
cacti_log('STATS: ' . $recache_stats, true, 'RECACHE');
|
||||||
@@ -238,7 +242,10 @@ if ($host_id === false) {
|
|||||||
cacti_log("Device[$device_id] NOTE: Recache Event Detected for Device", true, 'PCOMMAND');
|
cacti_log("Device[$device_id] NOTE: Recache Event Detected for Device", true, 'PCOMMAND');
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log("Device[$device_id] DQ[$data_query_id] RECACHE: Recache for Device started.", true, 'PCOMMAND', $verbosity);
|
cacti_log("Device[$device_id] DQ[$data_query_id] RECACHE: Recache for Device started.",
|
||||||
|
true,
|
||||||
|
'PCOMMAND',
|
||||||
|
$verbosity);
|
||||||
run_data_query($device_id, $data_query_id);
|
run_data_query($device_id, $data_query_id);
|
||||||
cacti_log("Device[$device_id] DQ[$data_query_id] RECACHE: Recached successfully.", true, 'PCOMMAND', $verbosity);
|
cacti_log("Device[$device_id] DQ[$data_query_id] RECACHE: Recached successfully.", true, 'PCOMMAND', $verbosity);
|
||||||
|
|
||||||
@@ -333,7 +340,12 @@ function commands_launch_child(int $host_id) : void {
|
|||||||
|
|
||||||
commands_debug(sprintf('Launching Commands Process Number %s for Type %s', $host_id, 'child'));
|
commands_debug(sprintf('Launching Commands Process Number %s for Type %s', $host_id, 'child'));
|
||||||
|
|
||||||
cacti_log(sprintf('NOTE: Launching Commands Process Number %s for Type %s', $host_id, 'child'), false, 'CLEANUP', POLLER_VERBOSITY_MEDIUM);
|
cacti_log(sprintf('NOTE: Launching Commands Process Number %s for Type %s',
|
||||||
|
$host_id,
|
||||||
|
'child'),
|
||||||
|
false,
|
||||||
|
'CLEANUP',
|
||||||
|
POLLER_VERBOSITY_MEDIUM);
|
||||||
|
|
||||||
exec_background($php_binary, CACTI_PATH_BASE . "/poller_commands.php --child=$host_id" . ($seebug ? ' --debug' : ''));
|
exec_background($php_binary, CACTI_PATH_BASE . "/poller_commands.php --child=$host_id" . ($seebug ? ' --debug' : ''));
|
||||||
}
|
}
|
||||||
@@ -423,7 +435,11 @@ function commands_kill_running_processes() : void {
|
|||||||
if (cacti_sizeof($processes)) {
|
if (cacti_sizeof($processes)) {
|
||||||
foreach ($processes as $p) {
|
foreach ($processes as $p) {
|
||||||
if (cacti_process_still_running((int) $p['pid'])) {
|
if (cacti_process_still_running((int) $p['pid'])) {
|
||||||
cacti_log(sprintf('WARNING: Killing Commands %s PID %d due to another due to signal or overrun.', ucfirst($p['taskname']), $p['pid']), false, 'CLEANUP');
|
cacti_log(sprintf('WARNING: Killing Commands %s PID %d due to another due to signal or overrun.',
|
||||||
|
ucfirst($p['taskname']),
|
||||||
|
$p['pid']),
|
||||||
|
false,
|
||||||
|
'CLEANUP');
|
||||||
|
|
||||||
cacti_process_kill((int) $p['pid'], SIGTERM, 'CLEANUP');
|
cacti_process_kill((int) $p['pid'], SIGTERM, 'CLEANUP');
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -286,7 +286,9 @@ function dsstats_master_handler(string $type, bool $force, bool $fpartition) : v
|
|||||||
dsstats_debug('Skipping Periodic Rollup - Boost will handle the Periodic Roll-up Cycle');
|
dsstats_debug('Skipping Periodic Rollup - Boost will handle the Periodic Roll-up Cycle');
|
||||||
} else {
|
} else {
|
||||||
if ($daily_interval == 'boost') {
|
if ($daily_interval == 'boost') {
|
||||||
cacti_log("WARNING: Daily update interval set to 'boost' and boost not enabled, resetting to default of 1 hour", false, 'DSSTATS');
|
cacti_log("WARNING: Daily update interval set to 'boost' and boost not enabled, resetting to default of 1 hour",
|
||||||
|
false,
|
||||||
|
'DSSTATS');
|
||||||
|
|
||||||
set_config_option('dsstats_daily_interval', 60);
|
set_config_option('dsstats_daily_interval', 60);
|
||||||
|
|
||||||
|
|||||||
+121
-23
@@ -159,7 +159,12 @@ $stats = device_recovery_sweep();
|
|||||||
$end = microtime(true);
|
$end = microtime(true);
|
||||||
|
|
||||||
if ($stats['devices'] > 0) {
|
if ($stats['devices'] > 0) {
|
||||||
cacti_log(sprintf('MAINT RECOVERY STATS: Time:%0.2f Checks:%s Recovered:%s', $stats['sweeptime'], $stats['devices'], $stats['recovered']), false, 'SYSTEM');
|
cacti_log(sprintf('MAINT RECOVERY STATS: Time:%0.2f Checks:%s Recovered:%s',
|
||||||
|
$stats['sweeptime'],
|
||||||
|
$stats['devices'],
|
||||||
|
$stats['recovered']),
|
||||||
|
false,
|
||||||
|
'SYSTEM');
|
||||||
}
|
}
|
||||||
|
|
||||||
cacti_log(sprintf('MAINT TOTAL STATS: Time:%0.2f', $end - $start), false, 'SYSTEM');
|
cacti_log(sprintf('MAINT TOTAL STATS: Time:%0.2f', $end - $start), false, 'SYSTEM');
|
||||||
@@ -290,8 +295,17 @@ function device_recovery_sweep() : array {
|
|||||||
$ping->host = $thost;
|
$ping->host = $thost;
|
||||||
$ping->port = $thost['ping_port'];
|
$ping->port = $thost['ping_port'];
|
||||||
|
|
||||||
if ($ping->ping($thost['availability_method'], $thost['ping_method'], $thost['ping_timeout'], $thost['ping_retries'])) {
|
if ($ping->ping($thost['availability_method'],
|
||||||
cacti_log(sprintf('RECOVERY STATS: Time:%0.2f Device[%s] STATUS: Device \'%s\' brought UP with Options Set [%s]', microtime(true) - $start, $thost['id'], $thost['hostname'], $names[$o['snmp_id']]), true, 'SYSTEM');
|
$thost['ping_method'],
|
||||||
|
$thost['ping_timeout'],
|
||||||
|
$thost['ping_retries'])) {
|
||||||
|
cacti_log(sprintf('RECOVERY STATS: Time:%0.2f Device[%s] STATUS: Device \'%s\' brought UP with Options Set [%s]',
|
||||||
|
microtime(true) - $start,
|
||||||
|
$thost['id'],
|
||||||
|
$thost['hostname'],
|
||||||
|
$names[$o['snmp_id']]),
|
||||||
|
true,
|
||||||
|
'SYSTEM');
|
||||||
|
|
||||||
$sql = 'UPDATE host SET ';
|
$sql = 'UPDATE host SET ';
|
||||||
$sql_params = [];
|
$sql_params = [];
|
||||||
@@ -314,7 +328,13 @@ function device_recovery_sweep() : array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$device_up && isset($thost['id'])) {
|
if (!$device_up && isset($thost['id'])) {
|
||||||
cacti_log(sprintf('RECOVERY STATS: Time:%0.2f Device[%s] STATUS: Device \'%s\' remains Down. No matching Options Sets.', microtime(true) - $start, $thost['id'], $thost['hostname']), true, 'SYSTEM');
|
cacti_log(sprintf('RECOVERY STATS: Time:%0.2f Device[%s] STATUS: Device \'%s\' remains ' .
|
||||||
|
'Down. No matching Options Sets.',
|
||||||
|
microtime(true) - $start,
|
||||||
|
$thost['id'],
|
||||||
|
$thost['hostname']),
|
||||||
|
true,
|
||||||
|
'SYSTEM');
|
||||||
db_execute_prepared('UPDATE host SET status_options_date = NOW() WHERE id = ?', [$thost['id']]);
|
db_execute_prepared('UPDATE host SET status_options_date = NOW() WHERE id = ?', [$thost['id']]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -516,7 +536,10 @@ function rrdfile_purge(bool $force) : void {
|
|||||||
|
|
||||||
$poller_end = microtime(true);
|
$poller_end = microtime(true);
|
||||||
set_config_option('rrdcleaner_last_run_time', time());
|
set_config_option('rrdcleaner_last_run_time', time());
|
||||||
$string = sprintf('RRDMAINT STATS: Time:%4.4f Purged:%s Archived:%s', ($poller_end - $poller_start), $purged, $archived);
|
$string = sprintf('RRDMAINT STATS: Time:%4.4f Purged:%s Archived:%s',
|
||||||
|
($poller_end - $poller_start),
|
||||||
|
$purged,
|
||||||
|
$archived);
|
||||||
cacti_log($string, true, 'SYSTEM');
|
cacti_log($string, true, 'SYSTEM');
|
||||||
} else {
|
} else {
|
||||||
maint_debug('No RRDfiles scheduled for arching or removal');
|
maint_debug('No RRDfiles scheduled for arching or removal');
|
||||||
@@ -609,7 +632,11 @@ function logrotate_rotatenow() : void {
|
|||||||
|
|
||||||
// record the start time
|
// record the start time
|
||||||
$poller_end = microtime(true);
|
$poller_end = microtime(true);
|
||||||
$string = sprintf('LOGMAINT STATS: Time:%4.4f, Rotated:%d, Removed:%d, Days Retained:%d', ($poller_end - $poller_start), $rotated, $cleaned, $days);
|
$string = sprintf('LOGMAINT STATS: Time:%4.4f, Rotated:%d, Removed:%d, Days Retained:%d',
|
||||||
|
($poller_end - $poller_start),
|
||||||
|
$rotated,
|
||||||
|
$cleaned,
|
||||||
|
$days);
|
||||||
|
|
||||||
cacti_log($string, true, 'SYSTEM');
|
cacti_log($string, true, 'SYSTEM');
|
||||||
}
|
}
|
||||||
@@ -668,13 +695,33 @@ function logrotate_file_rotate(string $name, string $log, object $date) : int {
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
cacti_log('Cacti Log Rotation - ERROR: Could not rename ' . $name . ' Log "' . basename($log) . '" to "' . basename($log) . '-' . $ext . '"', true, 'MAINT');
|
cacti_log('Cacti Log Rotation - ERROR: Could not rename ' .
|
||||||
|
$name .
|
||||||
|
' Log "' .
|
||||||
|
basename($log) .
|
||||||
|
'" to "' .
|
||||||
|
basename($log) .
|
||||||
|
'-' .
|
||||||
|
$ext .
|
||||||
|
'"',
|
||||||
|
true,
|
||||||
|
'MAINT');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cacti_log('Cacti Log Rotation - ERROR: Permissions issue. Please check your ' . $name . ' Log directory : ' . basename($log), true, 'MAINT');
|
cacti_log('Cacti Log Rotation - ERROR: Permissions issue. Please check your ' .
|
||||||
|
$name .
|
||||||
|
' Log directory : ' .
|
||||||
|
basename($log),
|
||||||
|
true,
|
||||||
|
'MAINT');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cacti_log('Cacti Log Rotation - ERROR: Permissions issue. Please check your ' . $name . ' Log as directory or file are not writable : ' . $log, true, 'MAINT');
|
cacti_log('Cacti Log Rotation - ERROR: Permissions issue. Please check your ' .
|
||||||
|
$name .
|
||||||
|
' Log as directory or file are not writable : ' .
|
||||||
|
$log,
|
||||||
|
true,
|
||||||
|
'MAINT');
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -730,7 +777,10 @@ function logrotate_file_clean(string $name, string $log, object $date, int $rota
|
|||||||
cacti_log('Cacti Log Rotation - ERROR: Can not purge ' . $name . ' Log : ' . $d, true, 'MAINT');
|
cacti_log('Cacti Log Rotation - ERROR: Can not purge ' . $name . ' Log : ' . $d, true, 'MAINT');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cacti_log('Cacti Log Rotation - NOTE: Not expired, keeping ' . $name . ' Log : ' . $d, true, 'MAINT', POLLER_VERBOSITY_HIGH);
|
cacti_log('Cacti Log Rotation - NOTE: Not expired, keeping ' . $name . ' Log : ' . $d,
|
||||||
|
true,
|
||||||
|
'MAINT',
|
||||||
|
POLLER_VERBOSITY_HIGH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -738,7 +788,10 @@ function logrotate_file_clean(string $name, string $log, object $date, int $rota
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($matches) {
|
if ($matches) {
|
||||||
cacti_log('Cacti Log Rotation - NOTE: File not in expected naming format, ignoring ' . $name . ' Log : ' . $d, true, 'MAINT', POLLER_VERBOSITY_DEBUG);
|
cacti_log('Cacti Log Rotation - NOTE: File not in expected naming format, ignoring ' . $name . ' Log : ' . $d,
|
||||||
|
true,
|
||||||
|
'MAINT',
|
||||||
|
POLLER_VERBOSITY_DEBUG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -886,7 +939,9 @@ function remove_files(array $file_array) : void {
|
|||||||
if (rrdtool_execute('archive ' . $file['name'], false, RRDTOOL_OUTPUT_BOOLEAN, $rrdtool_pipe, $logopt = 'MAINT')) {
|
if (rrdtool_execute('archive ' . $file['name'], false, RRDTOOL_OUTPUT_BOOLEAN, $rrdtool_pipe, $logopt = 'MAINT')) {
|
||||||
maint_debug("Moved: {file['name']} to: RRDproxy Archive");
|
maint_debug("Moved: {file['name']} to: RRDproxy Archive");
|
||||||
} else {
|
} else {
|
||||||
cacti_log("WARNING RRDfile Maintenance is unable to move {$file['name']} to the RRDproxy Archive!", true, 'MAINT');
|
cacti_log("WARNING RRDfile Maintenance is unable to move {$file['name']} to the RRDproxy Archive!",
|
||||||
|
true,
|
||||||
|
'MAINT');
|
||||||
}
|
}
|
||||||
|
|
||||||
$archived++;
|
$archived++;
|
||||||
@@ -1088,7 +1143,12 @@ function phpversion_check(bool $force = false) : void {
|
|||||||
$phpbad_ver = version_compare(PHP_VERSION,'7.4','<');
|
$phpbad_ver = version_compare(PHP_VERSION,'7.4','<');
|
||||||
|
|
||||||
if ($phpbad_ver && ($date_next < $date_now || $force)) {
|
if ($phpbad_ver && ($date_next < $date_now || $force)) {
|
||||||
cacti_log('WARNING: PHP Version "' . PHP_VERSION . '"will not be supported by the develop branch in the future. If you cannot upgrade to PHP 7.1 or higher, please switch branches', false, 'CACTI');
|
cacti_log('WARNING: PHP Version "' .
|
||||||
|
PHP_VERSION .
|
||||||
|
('"will not be supported by the develop branch in the future. If you ' .
|
||||||
|
'cannot upgrade to PHP 7.1 or higher, please switch branches'),
|
||||||
|
false,
|
||||||
|
'CACTI');
|
||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES ("phpver_last", ?)', [$now]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES ("phpver_last", ?)', [$now]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1112,25 +1172,63 @@ function cpu_cores_check() : void {
|
|||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_count, $cores]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_count, $cores]);
|
||||||
} elseif ($cores != $last_count && $last_notify < ($now - 86400)) {
|
} elseif ($cores != $last_count && $last_notify < ($now - 86400)) {
|
||||||
cacti_log('WARNING: CPU cores changed. Maybe you should adjust the Poller settings (Processes and threads)', true, 'POLLER');
|
cacti_log('WARNING: CPU cores changed. Maybe you should adjust the Poller settings (Processes and threads)',
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: CPU cores changed for poller %d with name %s. Maybe you should adjust the Poller settings (Processes and threads)', POLLER_ID, $poller_settings['name']));
|
true,
|
||||||
|
'POLLER');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: CPU cores changed for poller %d with name %s. Maybe you ' .
|
||||||
|
'should adjust the Poller settings (Processes and threads)',
|
||||||
|
POLLER_ID,
|
||||||
|
$poller_settings['name']));
|
||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_count, $cores]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_count, $cores]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($poller_type == 1 && $poller_settings['processes'] < 2 && $cores > $poller_settings['processes'] && $last_notify < ($now - 86400)) {
|
if ($poller_type == 1 &&
|
||||||
cacti_log('WARNING: Default setting number of processes. It looks like this cmd poller uses default settings. To achieve optimal performance, change poller settings (Processes)', true, 'POLLER');
|
$poller_settings['processes'] < 2 &&
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: Default number of processes on poller %d with name %s. It looks like this cmd poller uses default settings. To achieve optimal performance, change poller settings (Processes)', POLLER_ID, $poller_settings['name']));
|
$cores > $poller_settings['processes'] &&
|
||||||
|
$last_notify < ($now - 86400)) {
|
||||||
|
cacti_log('WARNING: Default setting number of processes. It looks like this cmd ' .
|
||||||
|
'poller uses default settings. To achieve optimal performance, change ' .
|
||||||
|
'poller settings (Processes)',
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: Default number of processes on poller %d with name %s. It ' .
|
||||||
|
'looks like this cmd poller uses default settings. To achieve optimal ' .
|
||||||
|
'performance, change poller settings (Processes)',
|
||||||
|
POLLER_ID,
|
||||||
|
$poller_settings['name']));
|
||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
||||||
} elseif ($poller_type == 2 && $poller_settings['threads'] <= 2 && $cores > $poller_settings['processes'] && $last_notify < ($now - 86400)) {
|
} elseif ($poller_type == 2 &&
|
||||||
cacti_log('WARNING: Default setting number of processes/threads. It looks like this spine poller uses default settings. To achieve optimal performance, change poller settings (Processes and threads)', true, 'POLLER');
|
$poller_settings['threads'] <= 2 &&
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: Default number of processes/threads on poller %d with name %s. It looks like this spine poller uses default settings. To achieve optimal performance, change poller settings (Processes and threads)', POLLER_ID, $poller_settings['name']));
|
$cores > $poller_settings['processes'] &&
|
||||||
|
$last_notify < ($now - 86400)) {
|
||||||
|
cacti_log('WARNING: Default setting number of processes/threads. It looks like ' .
|
||||||
|
'this spine poller uses default settings. To achieve optimal ' .
|
||||||
|
'performance, change poller settings (Processes and threads)',
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: Default number of processes/threads on poller %d with name ' .
|
||||||
|
'%s. It looks like this spine poller uses default settings. To achieve ' .
|
||||||
|
'optimal performance, change poller settings (Processes and threads)',
|
||||||
|
POLLER_ID,
|
||||||
|
$poller_settings['name']));
|
||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($poller_type == 1 && ($cores * 2) < $poller_settings['processes'] && $last_notify < ($now - 86400)) {
|
if ($poller_type == 1 && ($cores * 2) < $poller_settings['processes'] && $last_notify < ($now - 86400)) {
|
||||||
cacti_log('WARNING: Number of CMD poller processes is too high. To achieve optimal performance, change poller settings (Processes)', true, 'POLLER');
|
cacti_log('WARNING: Number of CMD poller processes is too high. To achieve ' .
|
||||||
admin_email(__('Cacti System Warning'), __('WARNING: Number of CMD poller processes on poller %d with name %s is too high. To achieve optimal performance, change poller settings (Processes)', POLLER_ID, $poller_settings['name']));
|
'optimal performance, change poller settings (Processes)',
|
||||||
|
true,
|
||||||
|
'POLLER');
|
||||||
|
admin_email(__('Cacti System Warning'),
|
||||||
|
__('WARNING: Number of CMD poller processes on poller %d with name %s is ' .
|
||||||
|
'too high. To achieve optimal performance, change poller settings ' .
|
||||||
|
'(Processes)',
|
||||||
|
POLLER_ID,
|
||||||
|
$poller_settings['name']));
|
||||||
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
db_execute_prepared('REPLACE INTO settings (name, value) VALUES (?, ?)', [$name_last, $now]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+12
-2
@@ -146,7 +146,12 @@ $max_threads = read_config_option('max_threads');
|
|||||||
|
|
||||||
// Determine Command Name
|
// Determine Command Name
|
||||||
$command_string = cacti_escapeshellcmd((string) read_config_option('path_php_binary'));
|
$command_string = cacti_escapeshellcmd((string) read_config_option('path_php_binary'));
|
||||||
$extra_args = '-q ' . cacti_escapeshellarg(CACTI_PATH_BASE . '/cmd_realtime.php') . ' ' . cacti_escapeshellarg($poller_id) . " $graph_id $interval";
|
$extra_args = '-q ' .
|
||||||
|
cacti_escapeshellarg(CACTI_PATH_BASE .
|
||||||
|
'/cmd_realtime.php') .
|
||||||
|
' ' .
|
||||||
|
cacti_escapeshellarg($poller_id) .
|
||||||
|
" $graph_id $interval";
|
||||||
|
|
||||||
// Determine if Realtime will work or not
|
// Determine if Realtime will work or not
|
||||||
$cache_dir = read_config_option('realtime_cache_path');
|
$cache_dir = read_config_option('realtime_cache_path');
|
||||||
@@ -218,7 +223,12 @@ function process_poller_output_rt(mixed $rrdtool_pipe, string $poller_id, int $i
|
|||||||
if (cacti_sizeof($results) > 0) {
|
if (cacti_sizeof($results) > 0) {
|
||||||
// create an array keyed off of each .rrd file
|
// create an array keyed off of each .rrd file
|
||||||
foreach ($results as $item) {
|
foreach ($results as $item) {
|
||||||
$rt_graph_path = read_config_option('realtime_cache_path') . '/user_' . $poller_id . '_' . $item['local_data_id'] . '.rrd';
|
$rt_graph_path = read_config_option('realtime_cache_path') .
|
||||||
|
'/user_' .
|
||||||
|
$poller_id .
|
||||||
|
'_' .
|
||||||
|
$item['local_data_id'] .
|
||||||
|
'.rrd';
|
||||||
$data_source_path = get_data_source_path($item['local_data_id'], true);
|
$data_source_path = get_data_source_path($item['local_data_id'], true);
|
||||||
|
|
||||||
// create rt rrd
|
// create rt rrd
|
||||||
|
|||||||
+16
-5
@@ -62,7 +62,8 @@ function sig_handler(int $signo) : void {
|
|||||||
cacti_log('RECOVERY WARNING: Recovery Poller terminated by user', false, 'POLLER');
|
cacti_log('RECOVERY WARNING: Recovery Poller terminated by user', false, 'POLLER');
|
||||||
|
|
||||||
// tell the main poller that we are done
|
// tell the main poller that we are done
|
||||||
db_execute("REPLACE INTO settings (name, value) VALUES ('boost_poller_status', 'terminated - end time:" . date('Y-m-d G:i:s') . "')");
|
db_execute(("REPLACE INTO settings (name, value) VALUES ('boost_poller_status', " .
|
||||||
|
"'terminated - end time:") . date('Y-m-d G:i:s') . "')");
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
default:
|
default:
|
||||||
@@ -93,7 +94,11 @@ function recovery_delete_acknowledged_rows(array $rows, mixed $conn) : bool {
|
|||||||
$params[] = $row['time'];
|
$params[] = $row['time'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (db_execute_prepared('DELETE FROM poller_output_boost WHERE ' . implode(' OR ', $clauses), $params, true, $conn) === false) {
|
if (db_execute_prepared('DELETE FROM poller_output_boost WHERE ' . implode(' OR ',
|
||||||
|
$clauses),
|
||||||
|
$params,
|
||||||
|
true,
|
||||||
|
$conn) === false) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -120,13 +125,17 @@ function recovery_transfer_rows(array $rows, mixed $remote_conn, mixed $local_co
|
|||||||
cacti_log('RECOVERY: Writing ' . $record_count . ' records to main.', false, 'POLLER');
|
cacti_log('RECOVERY: Writing ' . $record_count . ' records to main.', false, 'POLLER');
|
||||||
|
|
||||||
if (!boost_flush_output_batch($sql_array, $remote_conn)) {
|
if (!boost_flush_output_batch($sql_array, $remote_conn)) {
|
||||||
cacti_log('RECOVERY ERROR: Main collector did not acknowledge the Boost batch; retaining local rows.', false, 'POLLER');
|
cacti_log('RECOVERY ERROR: Main collector did not acknowledge the Boost batch; retaining local rows.',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!recovery_delete_acknowledged_rows($rows, $local_conn)) {
|
if (!recovery_delete_acknowledged_rows($rows, $local_conn)) {
|
||||||
cacti_log('RECOVERY ERROR: Unable to remove acknowledged local Boost rows; they will be retried idempotently.', false, 'POLLER');
|
cacti_log('RECOVERY ERROR: Unable to remove acknowledged local Boost rows; they will be retried idempotently.',
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -319,7 +328,9 @@ if ($run) {
|
|||||||
WHERE id= ?', [$poller_id], false, $remote_db_cnn_id);
|
WHERE id= ?', [$poller_id], false, $remote_db_cnn_id);
|
||||||
} else {
|
} else {
|
||||||
debug('Recovery process still running, exiting');
|
debug('Recovery process still running, exiting');
|
||||||
cacti_log('RECOVERY: Recovery process still running for Poller ' . $poller_id . '. PID is ' . $recovery_pid, false, 'POLLER');
|
cacti_log('RECOVERY: Recovery process still running for Poller ' . $poller_id . '. PID is ' . $recovery_pid,
|
||||||
|
false,
|
||||||
|
'POLLER');
|
||||||
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-1
@@ -203,7 +203,9 @@ function rrdcheck_master_handler(bool $forcerun = false) : void {
|
|||||||
rrdcheck_debug('Skipping Periodic Rollup - Boost will handle the Periodic Roll-up Cycle');
|
rrdcheck_debug('Skipping Periodic Rollup - Boost will handle the Periodic Roll-up Cycle');
|
||||||
} else {
|
} else {
|
||||||
if ($run_interval == 'boost') {
|
if ($run_interval == 'boost') {
|
||||||
cacti_log("WARNING: RRDcheck interval set to 'boost' and boost not enabled, resetting to default of 4 hours", false, 'RRDCHECK');
|
cacti_log("WARNING: RRDcheck interval set to 'boost' and boost not enabled, resetting to default of 4 hours",
|
||||||
|
false,
|
||||||
|
'RRDCHECK');
|
||||||
|
|
||||||
set_config_option('rrdcheck_interval', 240);
|
set_config_option('rrdcheck_interval', 240);
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,9 @@ function timeToRun() : bool {
|
|||||||
$baselower = $basetime - 300;
|
$baselower = $basetime - 300;
|
||||||
$now = time();
|
$now = time();
|
||||||
|
|
||||||
debug("LastRun:'$lastrun', Frequency:'$frequency', BaseTime:'" . date('Y-m-d H:i:s', $basetime) . "', BaseUpper:'$baseupper', BaseLower:'$baselower', Now:'" . date('Y-m-d H:i:s', $now) . "'");
|
debug("LastRun:'$lastrun', Frequency:'$frequency', BaseTime:'" . date('Y-m-d H:i:s',
|
||||||
|
$basetime) . "', BaseUpper:'$baseupper', BaseLower:'$baselower', Now:'" . date('Y-m-d H:i:s',
|
||||||
|
$now) . "'");
|
||||||
|
|
||||||
if ($frequency > 0 && ($now - $lastrun > $frequency)) {
|
if ($frequency > 0 && ($now - $lastrun > $frequency)) {
|
||||||
debug("Frequency is '$frequency' Seconds");
|
debug("Frequency is '$frequency' Seconds");
|
||||||
@@ -264,7 +266,11 @@ function kill_spikes(array $templates, int &$found) : int {
|
|||||||
debug("Removing Spikes from '$f'");
|
debug("Removing Spikes from '$f'");
|
||||||
|
|
||||||
$response = exec(cacti_escapeshellcmd((string) read_config_option('path_php_binary')) . ' -q ' .
|
$response = exec(cacti_escapeshellcmd((string) read_config_option('path_php_binary')) . ' -q ' .
|
||||||
cacti_escapeshellarg(CACTI_PATH_CLI . '/removespikes.php') . ' --rrdfile=' . cacti_escapeshellarg($f) . ($debug ? ' --debug' : ''));
|
cacti_escapeshellarg(CACTI_PATH_CLI .
|
||||||
|
'/removespikes.php') .
|
||||||
|
' --rrdfile=' .
|
||||||
|
cacti_escapeshellarg($f) .
|
||||||
|
($debug ? ' --debug' : ''));
|
||||||
|
|
||||||
if (substr_count((string) $response, 'Spikes Found and Remediated')) {
|
if (substr_count((string) $response, 'Spikes Found and Remediated')) {
|
||||||
$found++;
|
$found++;
|
||||||
|
|||||||
+106
-25
@@ -79,7 +79,9 @@ $fields_poller_edit = [
|
|||||||
'hostname' => [
|
'hostname' => [
|
||||||
'method' => 'textbox',
|
'method' => 'textbox',
|
||||||
'friendly_name' => __('Data Collector Hostname'),
|
'friendly_name' => __('Data Collector Hostname'),
|
||||||
'description' => __('The hostname for Data Collector. It may have to be a Fully Qualified Domain name for the remote Pollers to contact it for activities such as re-indexing, Real-time graphing, etc.'),
|
'description' => __('The hostname for Data Collector. It may have to be a Fully Qualified ' .
|
||||||
|
'Domain name for the remote Pollers to contact it for activities such ' .
|
||||||
|
'as re-indexing, Real-time graphing, etc.'),
|
||||||
'value' => '|arg1:hostname|',
|
'value' => '|arg1:hostname|',
|
||||||
'size' => '50',
|
'size' => '50',
|
||||||
'default' => '',
|
'default' => '',
|
||||||
@@ -88,7 +90,8 @@ $fields_poller_edit = [
|
|||||||
'log_level' => [
|
'log_level' => [
|
||||||
'method' => 'drop_array',
|
'method' => 'drop_array',
|
||||||
'friendly_name' => __('Custom Log Level'),
|
'friendly_name' => __('Custom Log Level'),
|
||||||
'description' => __('In Cases where you need to perform debugging for a single Data Collector Only, you can change it\'s log level here.'),
|
'description' => __('In Cases where you need to perform debugging for a single Data ' .
|
||||||
|
'Collector Only, you can change it\'s log level here.'),
|
||||||
'value' => '|arg1:log_level|',
|
'value' => '|arg1:log_level|',
|
||||||
'default' => '-1',
|
'default' => '-1',
|
||||||
'array' => $logfile_verbosity,
|
'array' => $logfile_verbosity,
|
||||||
@@ -135,7 +138,8 @@ $fields_poller_edit = [
|
|||||||
'sync_interval' => [
|
'sync_interval' => [
|
||||||
'method' => 'drop_array',
|
'method' => 'drop_array',
|
||||||
'friendly_name' => __('Sync Interval'),
|
'friendly_name' => __('Sync Interval'),
|
||||||
'description' => __('The polling sync interval in use. This setting will affect how often this poller is checked and updated.'),
|
'description' => __('The polling sync interval in use. This setting will affect how often ' .
|
||||||
|
'this poller is checked and updated.'),
|
||||||
'value' => '|arg1:sync_interval|',
|
'value' => '|arg1:sync_interval|',
|
||||||
'default' => read_config_option('poller_sync_interval'),
|
'default' => read_config_option('poller_sync_interval'),
|
||||||
'array' => $poller_sync_intervals,
|
'array' => $poller_sync_intervals,
|
||||||
@@ -201,12 +205,14 @@ $fields_poller_edit = [
|
|||||||
'spacerssl' => [
|
'spacerssl' => [
|
||||||
'method' => 'spacer',
|
'method' => 'spacer',
|
||||||
'friendly_name' => __('Remote Database SSL Information'),
|
'friendly_name' => __('Remote Database SSL Information'),
|
||||||
'description' => __('Starting in MariaDB 11.4 and above, SSL is autonegotiated between the client and server. So, this option may not be required')
|
'description' => __('Starting in MariaDB 11.4 and above, SSL is autonegotiated between the ' .
|
||||||
|
'client and server. So, this option may not be required')
|
||||||
],
|
],
|
||||||
'dbssl' => [
|
'dbssl' => [
|
||||||
'method' => 'checkbox',
|
'method' => 'checkbox',
|
||||||
'friendly_name' => __('Remote Database SSL'),
|
'friendly_name' => __('Remote Database SSL'),
|
||||||
'description' => __('If the remote database uses SSL to connect, and it\'s prior to MariaDB 11.4, check the checkbox below to enter the details.'),
|
'description' => __('If the remote database uses SSL to connect, and it\'s prior to ' .
|
||||||
|
'MariaDB 11.4, check the checkbox below to enter the details.'),
|
||||||
'value' => '|arg1:dbssl|',
|
'value' => '|arg1:dbssl|',
|
||||||
'default' => $database_ssl ? 'on' : ''
|
'default' => $database_ssl ? 'on' : ''
|
||||||
],
|
],
|
||||||
@@ -231,7 +237,10 @@ $fields_poller_edit = [
|
|||||||
'dbsslca' => [
|
'dbsslca' => [
|
||||||
'method' => 'textbox',
|
'method' => 'textbox',
|
||||||
'friendly_name' => __('Remote Database SSL Authority'),
|
'friendly_name' => __('Remote Database SSL Authority'),
|
||||||
'description' => __('The file holding the SSL Certificate Authority to use to connect to the remote database. This is an optional parameter that can be required by the database provider if they have started SSL using the --ssl-mode=VERIFY_CA option.'),
|
'description' => __('The file holding the SSL Certificate Authority to use to connect to ' .
|
||||||
|
'the remote database. This is an optional parameter that can be ' .
|
||||||
|
'required by the database provider if they have started SSL using the ' .
|
||||||
|
'--ssl-mode=VERIFY_CA option.'),
|
||||||
'value' => '|arg1:dbsslca|',
|
'value' => '|arg1:dbsslca|',
|
||||||
'size' => '50',
|
'size' => '50',
|
||||||
'default' => $database_ssl_ca,
|
'default' => $database_ssl_ca,
|
||||||
@@ -240,7 +249,12 @@ $fields_poller_edit = [
|
|||||||
'dbsslcapath' => [
|
'dbsslcapath' => [
|
||||||
'method' => 'textbox',
|
'method' => 'textbox',
|
||||||
'friendly_name' => __('Remote Database SSL Authorities directory'),
|
'friendly_name' => __('Remote Database SSL Authorities directory'),
|
||||||
'description' => __('The file path to the directory that contains the trusted SSL Certificate Authority certificates. This is an optional parameter that can used instead of giving the path to an individual Certificate Authority file. This parameter can be required by the database provider if they have started SSL using the --ssl-mode=VERIFY_CA option.'),
|
'description' => __('The file path to the directory that contains the trusted SSL ' .
|
||||||
|
'Certificate Authority certificates. This is an optional parameter ' .
|
||||||
|
'that can used instead of giving the path to an individual Certificate ' .
|
||||||
|
'Authority file. This parameter can be required by the database ' .
|
||||||
|
'provider if they have started SSL using the --ssl-mode=VERIFY_CA ' .
|
||||||
|
'option.'),
|
||||||
'value' => '|arg1:dbsslcapath|',
|
'value' => '|arg1:dbsslcapath|',
|
||||||
'size' => '50',
|
'size' => '50',
|
||||||
'default' => $database_ssl_capath,
|
'default' => $database_ssl_capath,
|
||||||
@@ -249,7 +263,9 @@ $fields_poller_edit = [
|
|||||||
'dbsslverifyservercert' => [
|
'dbsslverifyservercert' => [
|
||||||
'method' => 'checkbox',
|
'method' => 'checkbox',
|
||||||
'friendly_name' => __('Remote Database SSL'),
|
'friendly_name' => __('Remote Database SSL'),
|
||||||
'description' => __("Provides a way to disable verification of the server's SSL certificate Common Name against the server's hostname when connecting. This verification is enabled by default."),
|
'description' => __("Provides a way to disable verification of the server's SSL " .
|
||||||
|
"certificate Common Name against the server's hostname when " .
|
||||||
|
'connecting. This verification is enabled by default.'),
|
||||||
'value' => '|arg1:dbsslverifyservercert|',
|
'value' => '|arg1:dbsslverifyservercert|',
|
||||||
'default' => $database_ssl_verify_server_cert ? 'on' : ''
|
'default' => $database_ssl_verify_server_cert ? 'on' : ''
|
||||||
],
|
],
|
||||||
@@ -322,19 +338,32 @@ function form_save() : void {
|
|||||||
$save['notes'] = CactiValidator::validateInput(gnrv('notes'), 'notes', []);
|
$save['notes'] = CactiValidator::validateInput(gnrv('notes'), 'notes', []);
|
||||||
|
|
||||||
// Process settings
|
// Process settings
|
||||||
$save['processes'] = CactiValidator::validateInput(gnrv('processes'), 'processes', [new Assert\NotBlank(), new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
$save['processes'] = CactiValidator::validateInput(gnrv('processes'),
|
||||||
$save['threads'] = CactiValidator::validateInput(gnrv('threads'), 'threads', [new Assert\NotBlank(), new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
'processes',
|
||||||
|
[new Assert\NotBlank(),
|
||||||
|
new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
||||||
|
$save['threads'] = CactiValidator::validateInput(gnrv('threads'),
|
||||||
|
'threads',
|
||||||
|
[new Assert\NotBlank(),
|
||||||
|
new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
||||||
|
|
||||||
if ($save['id'] != 1) {
|
if ($save['id'] != 1) {
|
||||||
$save['sync_interval'] = CactiValidator::validateInput(gnrv('sync_interval'), 'sync_interval', [new Assert\NotBlank(), new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
$save['sync_interval'] = CactiValidator::validateInput(gnrv('sync_interval'),
|
||||||
|
'sync_interval',
|
||||||
|
[new Assert\NotBlank(),
|
||||||
|
new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
||||||
|
|
||||||
// Database settings
|
// Database settings
|
||||||
$save['dbdefault'] = CactiValidator::validateInput(gnrv('dbdefault'), 'dbdefault', []);
|
$save['dbdefault'] = CactiValidator::validateInput(gnrv('dbdefault'), 'dbdefault', []);
|
||||||
$save['dbhost'] = CactiValidator::validateInput(gnrv('dbhost'), 'dbhost', []);
|
$save['dbhost'] = CactiValidator::validateInput(gnrv('dbhost'), 'dbhost', []);
|
||||||
$save['dbuser'] = CactiValidator::validateInput(gnrv('dbuser'), 'dbuser', []);
|
$save['dbuser'] = CactiValidator::validateInput(gnrv('dbuser'), 'dbuser', []);
|
||||||
$save['dbpass'] = CactiValidator::validateInput(gnrv('dbpass'), 'dbpass', []);
|
$save['dbpass'] = CactiValidator::validateInput(gnrv('dbpass'), 'dbpass', []);
|
||||||
$save['dbport'] = CactiValidator::validateInput(gnrv('dbport'), 'dbport', [new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
$save['dbport'] = CactiValidator::validateInput(gnrv('dbport'),
|
||||||
$save['dbretries'] = CactiValidator::validateInput(gnrv('dbretries'), 'dbretries', [new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
'dbport',
|
||||||
|
[new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
||||||
|
$save['dbretries'] = CactiValidator::validateInput(gnrv('dbretries'),
|
||||||
|
'dbretries',
|
||||||
|
[new Assert\Regex(pattern: '/^[0-9]+$/')]);
|
||||||
$save['dbssl'] = isrv('dbssl') ? 'on' : '';
|
$save['dbssl'] = isrv('dbssl') ? 'on' : '';
|
||||||
$save['dbsslkey'] = CactiValidator::validateInput(gnrv('dbsslkey'), 'dbsslkey', []);
|
$save['dbsslkey'] = CactiValidator::validateInput(gnrv('dbsslkey'), 'dbsslkey', []);
|
||||||
$save['dbsslcert'] = CactiValidator::validateInput(gnrv('dbsslcert'), 'dbsslcert', []);
|
$save['dbsslcert'] = CactiValidator::validateInput(gnrv('dbsslcert'), 'dbsslcert', []);
|
||||||
@@ -347,13 +376,19 @@ function form_save() : void {
|
|||||||
$error = false;
|
$error = false;
|
||||||
|
|
||||||
if (poller_check_duplicate_poller_id($save['id'], $save['hostname'], 'hostname')) {
|
if (poller_check_duplicate_poller_id($save['id'], $save['hostname'], 'hostname')) {
|
||||||
raise_message('dupe_hostname', __esc('You have already used this hostname \'%s\'. Please enter a non-duplicate hostname.', $save['hostname']), MESSAGE_LEVEL_ERROR);
|
raise_message('dupe_hostname',
|
||||||
|
__esc('You have already used this hostname \'%s\'. Please enter a non-duplicate hostname.',
|
||||||
|
$save['hostname']),
|
||||||
|
MESSAGE_LEVEL_ERROR);
|
||||||
$error = true;
|
$error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($save['dbhost'])) {
|
if (isset($save['dbhost'])) {
|
||||||
if (poller_check_duplicate_poller_id($save['id'], $save['dbhost'], 'dbhost')) {
|
if (poller_check_duplicate_poller_id($save['id'], $save['dbhost'], 'dbhost')) {
|
||||||
raise_message('dupe_dbhost', __esc('You have already used this database hostname \'%s\'. Please enter a non-duplicate database hostname.', $save['hostname']), MESSAGE_LEVEL_ERROR);
|
raise_message('dupe_dbhost',
|
||||||
|
__esc('You have already used this database hostname \'%s\'. Please enter a non-duplicate database hostname.',
|
||||||
|
$save['hostname']),
|
||||||
|
MESSAGE_LEVEL_ERROR);
|
||||||
$error = true;
|
$error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -497,15 +532,24 @@ function form_actions() : void {
|
|||||||
db_execute('UPDATE poller_output_realtime SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
|
db_execute('UPDATE poller_output_realtime SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
|
||||||
db_execute('UPDATE poller_time SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
|
db_execute('UPDATE poller_time SET poller_id=1 WHERE ' . array_to_sql_or($selected_items, 'poller_id'));
|
||||||
|
|
||||||
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',', $selected_items) . ' deleted by user ' . $_SESSION[SESS_USER_ID], false, 'WEBUI');
|
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',',
|
||||||
|
$selected_items) . ' deleted by user ' . $_SESSION[SESS_USER_ID],
|
||||||
|
false,
|
||||||
|
'WEBUI');
|
||||||
} elseif (grv('drp_action') == POLLER_DISABLE) { // disable
|
} elseif (grv('drp_action') == POLLER_DISABLE) { // disable
|
||||||
db_execute('UPDATE poller SET disabled="on" WHERE ' . array_to_sql_or($selected_items, 'id'));
|
db_execute('UPDATE poller SET disabled="on" WHERE ' . array_to_sql_or($selected_items, 'id'));
|
||||||
|
|
||||||
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',', $selected_items) . ' disabled by user ' . $_SESSION[SESS_USER_ID], false, 'WEBUI');
|
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',',
|
||||||
|
$selected_items) . ' disabled by user ' . $_SESSION[SESS_USER_ID],
|
||||||
|
false,
|
||||||
|
'WEBUI');
|
||||||
} elseif (grv('drp_action') == POLLER_ENABLE) { // enable
|
} elseif (grv('drp_action') == POLLER_ENABLE) { // enable
|
||||||
db_execute('UPDATE poller SET disabled="" WHERE ' . array_to_sql_or($selected_items, 'id'));
|
db_execute('UPDATE poller SET disabled="" WHERE ' . array_to_sql_or($selected_items, 'id'));
|
||||||
|
|
||||||
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',', $selected_items) . ' enabled by user ' . $_SESSION[SESS_USER_ID], false, 'WEBUI');
|
cacti_log('NOTE: The poller(s) with the id(s): ' . implode(',',
|
||||||
|
$selected_items) . ' enabled by user ' . $_SESSION[SESS_USER_ID],
|
||||||
|
false,
|
||||||
|
'WEBUI');
|
||||||
} elseif (grv('drp_action') == POLLER_RESYNC || grv('drp_action') == POLLER_AUTHSYNC) { // full or auth sync
|
} elseif (grv('drp_action') == POLLER_RESYNC || grv('drp_action') == POLLER_AUTHSYNC) { // full or auth sync
|
||||||
cacti_session_close();
|
cacti_session_close();
|
||||||
|
|
||||||
@@ -563,9 +607,22 @@ function form_actions() : void {
|
|||||||
cacti_session_start();
|
cacti_session_start();
|
||||||
|
|
||||||
if (cacti_sizeof($failed)) {
|
if (cacti_sizeof($failed)) {
|
||||||
cacti_log('WARNING: Some Selected Remote Data Collectors in [' . implode(', ', $ids) . '] failed synchronization by user ' . get_username($_SESSION[SESS_USER_ID]) . ', Successful/Failed[' . cacti_sizeof($success) . '/' . cacti_sizeof($failed) . ']. See log for details.', false, 'WEBUI');
|
cacti_log('WARNING: Some Selected Remote Data Collectors in [' . implode(', ',
|
||||||
|
$ids) .
|
||||||
|
'] failed synchronization by user ' .
|
||||||
|
get_username($_SESSION[SESS_USER_ID]) .
|
||||||
|
', Successful/Failed[' .
|
||||||
|
cacti_sizeof($success) .
|
||||||
|
'/' .
|
||||||
|
cacti_sizeof($failed) .
|
||||||
|
']. See log for details.',
|
||||||
|
false,
|
||||||
|
'WEBUI');
|
||||||
} else {
|
} else {
|
||||||
cacti_log('NOTE: All Selected Remote Data Collectors in [' . implode(', ', $ids) . '] synchronized correctly by user ' . get_username($_SESSION[SESS_USER_ID]), false, 'WEBUI');
|
cacti_log('NOTE: All Selected Remote Data Collectors in [' . implode(', ',
|
||||||
|
$ids) . '] synchronized correctly by user ' . get_username($_SESSION[SESS_USER_ID]),
|
||||||
|
false,
|
||||||
|
'WEBUI');
|
||||||
}
|
}
|
||||||
} elseif (grv('drp_action') == '5') { // clear statistics
|
} elseif (grv('drp_action') == '5') { // clear statistics
|
||||||
foreach ($selected_items as $item) {
|
foreach ($selected_items as $item) {
|
||||||
@@ -710,7 +767,9 @@ function poller_edit() : void {
|
|||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
$tip_text = __('Remote Data Collectors must be able to communicate to the Main Data Collector, and vice versa. Use this button to verify that the Main Data Collector can communicate to this Remote Data Collector.');
|
$tip_text = __('Remote Data Collectors must be able to communicate to the Main Data ' .
|
||||||
|
'Collector, and vice versa. Use this button to verify that the Main ' .
|
||||||
|
'Data Collector can communicate to this Remote Data Collector.');
|
||||||
|
|
||||||
if (read_config_option('hide_form_description') == 'on') {
|
if (read_config_option('hide_form_description') == 'on') {
|
||||||
$tooltip = '<br><span class="formFieldDescription">' . $tip_text . '</span>';
|
$tooltip = '<br><span class="formFieldDescription">' . $tip_text . '</span>';
|
||||||
@@ -718,7 +777,14 @@ function poller_edit() : void {
|
|||||||
$tooltip = '<div class="formTooltip">' . str_replace("\n", '', display_tooltip($tip_text)) . '</div>';
|
$tooltip = '<div class="formTooltip">' . str_replace("\n", '', display_tooltip($tip_text)) . '</div>';
|
||||||
}
|
}
|
||||||
|
|
||||||
$row_html = '<div class="formRow odd"><div class="formColumnLeft"><div class="formFieldName">' . __('Test Database Connection') . $tooltip . '</div></div><div class="formColumnRight"><button type="button" class="ui-button ui-corner-all ui-widget" id="dbtest">' . __esc('Test Connection') . '</button><span id="results"></span></div></div>';
|
$row_html = ('<div class="formRow odd"><div class="formColumnLeft"><div ' .
|
||||||
|
'class="formFieldName">') .
|
||||||
|
__('Test Database Connection') .
|
||||||
|
$tooltip .
|
||||||
|
('</div></div><div class="formColumnRight"><button type="button" ' .
|
||||||
|
'class="ui-button ui-corner-all ui-widget" id="dbtest">') .
|
||||||
|
__esc('Test Connection') .
|
||||||
|
'</button><span id="results"></span></div></div>';
|
||||||
|
|
||||||
$pt = read_config_option('poller_type');
|
$pt = read_config_option('poller_type');
|
||||||
|
|
||||||
@@ -948,7 +1014,15 @@ function pollers() : void {
|
|||||||
$sql_order
|
$sql_order
|
||||||
$sql_limit");
|
$sql_limit");
|
||||||
|
|
||||||
$nav = html_nav_bar('pollers.php?filter=' . grv('filter'), MAX_DISPLAY_PAGES, grv('page'), $rows, $total_rows, 5, __('Pollers'), 'page', 'main');
|
$nav = html_nav_bar('pollers.php?filter=' . grv('filter'),
|
||||||
|
MAX_DISPLAY_PAGES,
|
||||||
|
grv('page'),
|
||||||
|
$rows,
|
||||||
|
$total_rows,
|
||||||
|
5,
|
||||||
|
__('Pollers'),
|
||||||
|
'page',
|
||||||
|
'main');
|
||||||
|
|
||||||
form_start('pollers.php', 'chk');
|
form_start('pollers.php', 'chk');
|
||||||
|
|
||||||
@@ -1071,7 +1145,10 @@ function pollers() : void {
|
|||||||
|
|
||||||
form_alternate_row('line' . $poller['id'], true, $disabled);
|
form_alternate_row('line' . $poller['id'], true, $disabled);
|
||||||
|
|
||||||
form_selectable_cell(filter_value($poller['name'], grv('filter'), 'pollers.php?action=edit&id=' . $poller['id']), $poller['id']);
|
form_selectable_cell(filter_value($poller['name'],
|
||||||
|
grv('filter'),
|
||||||
|
'pollers.php?action=edit&id=' . $poller['id']),
|
||||||
|
$poller['id']);
|
||||||
form_selectable_cell($poller['id'], $poller['id'], '', 'right');
|
form_selectable_cell($poller['id'], $poller['id'], '', 'right');
|
||||||
form_selectable_ecell($poller['hostname'], $poller['id'], '', 'right');
|
form_selectable_ecell($poller['hostname'], $poller['id'], '', 'right');
|
||||||
form_selectable_cell($poller_status[$poller['status']], $poller['id'], '', 'center');
|
form_selectable_cell($poller_status[$poller['status']], $poller['id'], '', 'center');
|
||||||
@@ -1096,7 +1173,11 @@ function pollers() : void {
|
|||||||
form_end_row();
|
form_end_row();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
print "<tr class='tableRow odd'><td colspan='" . (cacti_sizeof($display_text) + 1) . "'><em>" . __('No Data Collectors Found') . "</em></td></tr>\n";
|
print "<tr class='tableRow odd'><td colspan='" .
|
||||||
|
(cacti_sizeof($display_text) + 1) .
|
||||||
|
"'><em>" .
|
||||||
|
__('No Data Collectors Found') .
|
||||||
|
"</em></td></tr>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
html_end_box(false);
|
html_end_box(false);
|
||||||
|
|||||||
+13
-3
@@ -231,7 +231,13 @@ function remote_client_authorized() : bool {
|
|||||||
|
|
||||||
if (!$forward_match) {
|
if (!$forward_match) {
|
||||||
$safe_name = preg_replace('/[^a-zA-Z0-9.\-:]/', '', $client_name);
|
$safe_name = preg_replace('/[^a-zA-Z0-9.\-:]/', '', $client_name);
|
||||||
cacti_log('WARNING: PTR record for ' . $client_addr . ' resolves to ' . $safe_name . ' but forward lookup does not match. Rejecting.', false, 'SECURITY');
|
cacti_log('WARNING: PTR record for ' .
|
||||||
|
$client_addr .
|
||||||
|
' resolves to ' .
|
||||||
|
$safe_name .
|
||||||
|
' but forward lookup does not match. Rejecting.',
|
||||||
|
false,
|
||||||
|
'SECURITY');
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -424,7 +430,8 @@ function poll_for_data() : mixed {
|
|||||||
if (($item['snmp_version'] == 0) || (($item['snmp_community'] == '') && ($item['snmp_version'] != 3))) {
|
if (($item['snmp_version'] == 0) || (($item['snmp_community'] == '') && ($item['snmp_version'] != 3))) {
|
||||||
$output = 'U';
|
$output = 'U';
|
||||||
} else {
|
} else {
|
||||||
$host = db_fetch_row_prepared('SELECT ping_retries, max_oids FROM host WHERE hostname = ?', [$item['hostname']]);
|
$host = db_fetch_row_prepared('SELECT ping_retries, max_oids FROM host WHERE hostname = ?',
|
||||||
|
[$item['hostname']]);
|
||||||
$session = cacti_snmp_session($item['hostname'], $item['snmp_community'], $item['snmp_version'],
|
$session = cacti_snmp_session($item['hostname'], $item['snmp_community'], $item['snmp_version'],
|
||||||
$item['snmp_username'], $item['snmp_password'], $item['snmp_auth_protocol'], $item['snmp_priv_passphrase'],
|
$item['snmp_username'], $item['snmp_password'], $item['snmp_auth_protocol'], $item['snmp_priv_passphrase'],
|
||||||
$item['snmp_priv_protocol'], $item['snmp_context'], $item['snmp_engine_id'], $item['snmp_port'],
|
$item['snmp_priv_protocol'], $item['snmp_context'], $item['snmp_engine_id'], $item['snmp_port'],
|
||||||
@@ -487,7 +494,10 @@ function poll_for_data() : mixed {
|
|||||||
// proc_open returns false if the child could not be spawned; fall back to
|
// proc_open returns false if the child could not be spawned; fall back to
|
||||||
// the non-proc path rather than reading from non-existent pipes
|
// the non-proc path rather than reading from non-existent pipes
|
||||||
if (!is_resource($cactiphp)) {
|
if (!is_resource($cactiphp)) {
|
||||||
cacti_log('WARNING: Unable to start PHP Script Server, falling back to direct execution', false, 'POLLER', POLLER_VERBOSITY_LOW);
|
cacti_log('WARNING: Unable to start PHP Script Server, falling back to direct execution',
|
||||||
|
false,
|
||||||
|
'POLLER',
|
||||||
|
POLLER_VERBOSITY_LOW);
|
||||||
|
|
||||||
$using_proc_function = false;
|
$using_proc_function = false;
|
||||||
$pipes = false;
|
$pipes = false;
|
||||||
|
|||||||
+46
-13
@@ -147,7 +147,10 @@ $start = microtime(true);
|
|||||||
$include_file = '';
|
$include_file = '';
|
||||||
|
|
||||||
if (CACTI_SERVER_OS == 'win32') {
|
if (CACTI_SERVER_OS == 'win32') {
|
||||||
cacti_log('DEBUG: GETCWD: ' . cacti_strtolower(strtr((string) getcwd(),'\\','/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
|
cacti_log('DEBUG: GETCWD: ' . cacti_strtolower(strtr((string) getcwd(),'\\','/')),
|
||||||
|
false,
|
||||||
|
'PHPSVR',
|
||||||
|
POLLER_VERBOSITY_DEBUG);
|
||||||
cacti_log('DEBUG: DIRNAM: ' . cacti_strtolower(strtr(__DIR__,'\\','/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
|
cacti_log('DEBUG: DIRNAM: ' . cacti_strtolower(strtr(__DIR__,'\\','/')), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
|
||||||
} else {
|
} else {
|
||||||
cacti_log('DEBUG: GETCWD: ' . strtr((string) getcwd(),'\\','/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
|
cacti_log('DEBUG: GETCWD: ' . strtr((string) getcwd(),'\\','/'), false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
|
||||||
@@ -204,12 +207,18 @@ while (1) {
|
|||||||
|
|
||||||
if ($isParentRunning) {
|
if ($isParentRunning) {
|
||||||
if (!empty($parent_pid)) {
|
if (!empty($parent_pid)) {
|
||||||
cacti_log('WARNING: Input Expected, parent process ' . $parent_pid . ' should have sent non-blank line', false, 'PHPSVR', POLLER_VERBOSITY_DEBUG);
|
cacti_log('WARNING: Input Expected, parent process ' . $parent_pid . ' should have sent non-blank line',
|
||||||
|
false,
|
||||||
|
'PHPSVR',
|
||||||
|
POLLER_VERBOSITY_DEBUG);
|
||||||
} else {
|
} else {
|
||||||
cacti_log('WARNING: Input Expected, unable to check parent process', false, 'PHPSVR', POLLER_VERBOSITY_MEDIUM);
|
cacti_log('WARNING: Input Expected, unable to check parent process', false, 'PHPSVR', POLLER_VERBOSITY_MEDIUM);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cacti_log('WARNING: Parent (' . $parent_pid . ') of Script Server (' . getmypid() . ') has been lost, forcing exit', false, 'PHPSVR', POLLER_VERBOSITY_HIGH);
|
cacti_log('WARNING: Parent (' . $parent_pid . ') of Script Server (' . getmypid() . ') has been lost, forcing exit',
|
||||||
|
false,
|
||||||
|
'PHPSVR',
|
||||||
|
POLLER_VERBOSITY_HIGH);
|
||||||
$input_string = 'quit';
|
$input_string = 'quit';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,7 +327,15 @@ while (1) {
|
|||||||
|
|
||||||
$ctr++;
|
$ctr++;
|
||||||
} else {
|
} else {
|
||||||
cacti_log("WARNING: Function does not exist INC: '" . basename($include_file) . "' FUNC: '" . $function . "' PARMS: '" . $parameters . "'", false, 'PHPSVR');
|
cacti_log("WARNING: Function does not exist INC: '" .
|
||||||
|
basename($include_file) .
|
||||||
|
"' FUNC: '" .
|
||||||
|
$function .
|
||||||
|
"' PARMS: '" .
|
||||||
|
$parameters .
|
||||||
|
"'",
|
||||||
|
false,
|
||||||
|
'PHPSVR');
|
||||||
fputs(STDOUT, "U\n");
|
fputs(STDOUT, "U\n");
|
||||||
fflush(STDOUT);
|
fflush(STDOUT);
|
||||||
}
|
}
|
||||||
@@ -327,7 +344,9 @@ while (1) {
|
|||||||
|
|
||||||
// end the process if the runtime exceeds MAX_POLLER_RUNTIME
|
// end the process if the runtime exceeds MAX_POLLER_RUNTIME
|
||||||
if (($start + MAX_POLLER_RUNTIME) < time()) {
|
if (($start + MAX_POLLER_RUNTIME) < time()) {
|
||||||
cacti_log('Maximum runtime of ' . MAX_POLLER_RUNTIME . ' seconds exceeded for the Script Server. Exiting.', true, 'PHPSVR');
|
cacti_log('Maximum runtime of ' . MAX_POLLER_RUNTIME . ' seconds exceeded for the Script Server. Exiting.',
|
||||||
|
true,
|
||||||
|
'PHPSVR');
|
||||||
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
@@ -470,12 +489,20 @@ function sig_handler(int $signo) : void {
|
|||||||
case SIGABRT:
|
case SIGABRT:
|
||||||
case SIGQUIT:
|
case SIGQUIT:
|
||||||
case SIGSEGV:
|
case SIGSEGV:
|
||||||
cacti_log("WARNING: Script Server terminated with signal '$signo' in file:'" . basename($include_file) . "', function:'$function', params:'$parameters'", false, 'PHPSVR', POLLER_VERBOSITY_MEDIUM);
|
cacti_log("WARNING: Script Server terminated with signal '$signo' in file:'" .
|
||||||
|
basename($include_file) .
|
||||||
|
"', function:'$function', params:'$parameters'",
|
||||||
|
false,
|
||||||
|
'PHPSVR',
|
||||||
|
POLLER_VERBOSITY_MEDIUM);
|
||||||
db_close();
|
db_close();
|
||||||
|
|
||||||
exit;
|
exit;
|
||||||
default:
|
default:
|
||||||
cacti_log("WARNING: Script Server received signal '$signo' in file:'$include_file', function:'$function', params:'$parameters'", false, 'PHPSVR', POLLER_VERBOSITY_HIGH);
|
cacti_log("WARNING: Script Server received signal '$signo' in file:'$include_file', function:'$function', params:'$parameters'",
|
||||||
|
false,
|
||||||
|
'PHPSVR',
|
||||||
|
POLLER_VERBOSITY_HIGH);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -500,13 +527,18 @@ function display_help() : void {
|
|||||||
display_version();
|
display_version();
|
||||||
|
|
||||||
print PHP_EOL;
|
print PHP_EOL;
|
||||||
print 'usage: script_server.php [environ poller_id] | [ --environ=S --poller=N --mode [--force-level=N] ]' . PHP_EOL . PHP_EOL;
|
print ('usage: script_server.php [environ poller_id] | [ --environ=S ' .
|
||||||
|
'--poller=N --mode [--force-level=N] ]') . PHP_EOL . PHP_EOL;
|
||||||
print 'Cacti\'s Script Server. The Script Server provides a memory resident server for executing php' . PHP_EOL;
|
print 'Cacti\'s Script Server. The Script Server provides a memory resident server for executing php' . PHP_EOL;
|
||||||
print 'scripts saving reducing the time to process the scripts through pre-compiling them for all consumers.' . PHP_EOL;
|
print ('scripts saving reducing the time to process the scripts through ' .
|
||||||
print 'The Script Server can be called using two methods. The first method is the legacy method. When using' . PHP_EOL;
|
'pre-compiling them for all consumers.') . PHP_EOL;
|
||||||
print 'the legacy method, the first argument will be the environment, and the second will be the poller id.' . PHP_EOL . PHP_EOL;
|
print ('The Script Server can be called using two methods. The first method ' .
|
||||||
|
'is the legacy method. When using') . PHP_EOL;
|
||||||
|
print ('the legacy method, the first argument will be the environment, and ' .
|
||||||
|
'the second will be the poller id.') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'The modern calling method has multiple options processed by getopt. Those options include:' . PHP_EOL . PHP_EOL;
|
print ('The modern calling method has multiple options processed by getopt. ' .
|
||||||
|
'Those options include:') . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print ' --environ=S The default being \'cmd\', and options being \'spine\', \'cmd\', and \'realtime\'' . PHP_EOL;
|
print ' --environ=S The default being \'cmd\', and options being \'spine\', \'cmd\', and \'realtime\'' . PHP_EOL;
|
||||||
print ' --poller=N The poller id for the Data Collector in use' . PHP_EOL;
|
print ' --poller=N The poller id for the Data Collector in use' . PHP_EOL;
|
||||||
@@ -514,7 +546,8 @@ function display_help() : void {
|
|||||||
print ' --mode=S Force a Database mode \'online\' or \'offline\'. This is only relevant for' . PHP_EOL;
|
print ' --mode=S Force a Database mode \'online\' or \'offline\'. This is only relevant for' . PHP_EOL;
|
||||||
print ' Remote Data Collectors.' . PHP_EOL . PHP_EOL;
|
print ' Remote Data Collectors.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'If no options are passed to the Script Server, it assumes that the environ is \'cmd\' and the poller id' . PHP_EOL;
|
print ('If no options are passed to the Script Server, it assumes that the ' .
|
||||||
|
'environ is \'cmd\' and the poller id') . PHP_EOL;
|
||||||
print 'is 1 or the Main Data Collector.' . PHP_EOL . PHP_EOL;
|
print 'is 1 or the Main Data Collector.' . PHP_EOL . PHP_EOL;
|
||||||
|
|
||||||
print 'It is common that when developing Cacti Data Input methods one will use the Script Server to test' . PHP_EOL;
|
print 'It is common that when developing Cacti Data Input methods one will use the Script Server to test' . PHP_EOL;
|
||||||
|
|||||||
@@ -54,7 +54,9 @@ if ($mibcache_changed !== null || file_exists($path_mibcache) === false) {
|
|||||||
foreach ($objects as &$object) {
|
foreach ($objects as &$object) {
|
||||||
$oids[] = $object['oid'];
|
$oids[] = $object['oid'];
|
||||||
|
|
||||||
$object = ($object['otype'] == 'DATA' && $object['max-access'] != 'not-accessible') ? ['type' => $object['type'], 'value' => $object['value']] : false;
|
$object = ($object['otype'] == 'DATA' &&
|
||||||
|
$object['max-access'] != 'not-accessible') ? ['type' => $object['type'],
|
||||||
|
'value' => $object['value']] : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// natural sorting with MySQL is not available - especially not for OIDs
|
// natural sorting with MySQL is not available - especially not for OIDs
|
||||||
@@ -99,7 +101,10 @@ if ($mibcache_changed !== null || file_exists($path_mibcache) === false) {
|
|||||||
fclose($lock);
|
fclose($lock);
|
||||||
unlink($path_mibcache_lock);
|
unlink($path_mibcache_lock);
|
||||||
} else {
|
} else {
|
||||||
cacti_log('WARNING: Unable to open MIB cache lock file; skipping cache rebuild to avoid clobbering a concurrent writer.', false, 'SNMPAGENT');
|
cacti_log('WARNING: Unable to open MIB cache lock file; skipping cache rebuild ' .
|
||||||
|
'to avoid clobbering a concurrent writer.',
|
||||||
|
false,
|
||||||
|
'SNMPAGENT');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-2
@@ -107,7 +107,13 @@ while (true) {
|
|||||||
$oid = trim((string) fgets(STDIN));
|
$oid = trim((string) fgets(STDIN));
|
||||||
|
|
||||||
if ($data = cache_read($oid)) {
|
if ($data = cache_read($oid)) {
|
||||||
fwrite(STDOUT, $oid . $eol . (isset($smi_base_datatypes[$data['type']]) ? $smi_base_datatypes[$data['type']] : 'INTEGER') . $eol . $data['value'] . $eol);
|
fwrite(STDOUT,
|
||||||
|
$oid .
|
||||||
|
$eol .
|
||||||
|
(isset($smi_base_datatypes[$data['type']]) ? $smi_base_datatypes[$data['type']] : 'INTEGER') .
|
||||||
|
$eol .
|
||||||
|
$data['value'] .
|
||||||
|
$eol);
|
||||||
} else {
|
} else {
|
||||||
fwrite(STDOUT, 'NONE' . $eol);
|
fwrite(STDOUT, 'NONE' . $eol);
|
||||||
}
|
}
|
||||||
@@ -118,7 +124,13 @@ while (true) {
|
|||||||
|
|
||||||
if ($next_oid = cache_get_next($oid)) {
|
if ($next_oid = cache_get_next($oid)) {
|
||||||
if ($data = cache_read($next_oid)) {
|
if ($data = cache_read($next_oid)) {
|
||||||
fwrite(STDOUT, $next_oid . $eol . (isset($smi_base_datatypes[$data['type']]) ? $smi_base_datatypes[$data['type']] : 'INTEGER') . $eol . $data['value'] . $eol);
|
fwrite(STDOUT,
|
||||||
|
$next_oid .
|
||||||
|
$eol .
|
||||||
|
(isset($smi_base_datatypes[$data['type']]) ? $smi_base_datatypes[$data['type']] : 'INTEGER') .
|
||||||
|
$eol .
|
||||||
|
$data['value'] .
|
||||||
|
$eol);
|
||||||
} else {
|
} else {
|
||||||
fwrite(STDOUT, 'NONE' . $eol);
|
fwrite(STDOUT, 'NONE' . $eol);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
+-------------------------------------------------------------------------+
|
+-------------------------------------------------------------------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
require_once dirname(__DIR__) . '/Helpers/PhpSource.php';
|
||||||
|
|
||||||
if (!function_exists('boostSource')) {
|
if (!function_exists('boostSource')) {
|
||||||
function boostSource(string $path): string {
|
function boostSource(string $path): string {
|
||||||
$source = file_get_contents(CACTI_PATH_BASE . '/' . $path);
|
$source = file_get_contents(CACTI_PATH_BASE . '/' . $path);
|
||||||
@@ -76,7 +78,7 @@ test('Recovery status SQL remains valid when ANSI_QUOTES is enabled', function (
|
|||||||
test('Scheduled Boost retains shard ownership after an RRD update failure', function () {
|
test('Scheduled Boost retains shard ownership after an RRD update failure', function () {
|
||||||
$poller = boostSource('poller_boost.php');
|
$poller = boostSource('poller_boost.php');
|
||||||
|
|
||||||
expect($poller)->toContain('function boost_process_output(int $local_data_id, array $outarray, string $rrd_path, array $rrd_tmplp, mixed $rrdtool_pipe) : bool');
|
expect($poller)->toContainPhp('function boost_process_output(int $local_data_id, array $outarray, string $rrd_path, array $rrd_tmplp, mixed $rrdtool_pipe) : bool');
|
||||||
expect($poller)->toContain('if ($updates_ok && $results !== false)');
|
expect($poller)->toContain('if ($updates_ok && $results !== false)');
|
||||||
expect($poller)->toContain('return $updates_ok && $results !== false ? cacti_sizeof($results) : -1;');
|
expect($poller)->toContain('return $updates_ok && $results !== false ? cacti_sizeof($results) : -1;');
|
||||||
expect($poller)->toContain('if ($pass_rows < 0)');
|
expect($poller)->toContain('if ($pass_rows < 0)');
|
||||||
@@ -125,11 +127,11 @@ test('Remote tuples are quoted by their destination connection', function () {
|
|||||||
$cmd = boostSource('cmd.php');
|
$cmd = boostSource('cmd.php');
|
||||||
$recovery = boostSource('poller_recovery.php');
|
$recovery = boostSource('poller_recovery.php');
|
||||||
|
|
||||||
expect($cmd)->toContain("db_qstr(\$item['rrd_name'], \$poller_db_cnn_id)");
|
expect($cmd)->toContainPhp("db_qstr(\$item['rrd_name'], \$poller_db_cnn_id)");
|
||||||
expect($cmd)->toContain('db_qstr($output, $poller_db_cnn_id)');
|
expect($cmd)->toContainPhp('db_qstr($output, $poller_db_cnn_id)');
|
||||||
expect($cmd)->toContain("db_qstr('U', \$poller_db_cnn_id)");
|
expect($cmd)->toContainPhp("db_qstr('U', \$poller_db_cnn_id)");
|
||||||
expect($cmd)->toContain("IFNULL(s.disabled, \\'\\') != \\'on\\'");
|
expect($cmd)->toContain("IFNULL(s.disabled, \\'\\') != \\'on\\'");
|
||||||
expect($recovery)->toContain("db_qstr(\$row['rrd_name'], \$remote_conn)");
|
expect($recovery)->toContainPhp("db_qstr(\$row['rrd_name'], \$remote_conn)");
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Graph cache names are opaque and writes are atomically published', function () {
|
test('Graph cache names are opaque and writes are atomically published', function () {
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
// Copyright (C) 2004-2026 The Cacti Group. GPL-2.0-or-later.
|
||||||
|
|
||||||
|
namespace Cacti\Tests\Helpers;
|
||||||
|
|
||||||
|
/** Source contracts ignore formatting, while retaining token kinds and literals. */
|
||||||
|
final class PhpSource {
|
||||||
|
public static function normalizeWhitespace(string $source) : string {
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
foreach (token_get_all($source) as $token) {
|
||||||
|
$id = is_array($token) ? $token[0] : 0;
|
||||||
|
$text = is_array($token) ? $token[1] : $token;
|
||||||
|
|
||||||
|
if (in_array($id, [T_WHITESPACE, T_COMMENT, T_DOC_COMMENT], true)) {
|
||||||
|
if (!str_ends_with($output, ' ')) {
|
||||||
|
$output .= ' ';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$output .= $text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function encode(string $source, bool $fragment = false) : array {
|
||||||
|
if ($fragment) {
|
||||||
|
$source = '<?php ' . $source;
|
||||||
|
}
|
||||||
|
|
||||||
|
$encoded = [];
|
||||||
|
$offsets = [];
|
||||||
|
$offset = 0;
|
||||||
|
|
||||||
|
foreach (token_get_all($source) as $token) {
|
||||||
|
$id = is_array($token) ? $token[0] : 0;
|
||||||
|
$text = is_array($token) ? $token[1] : $token;
|
||||||
|
|
||||||
|
if (!in_array($id, [T_OPEN_TAG, T_WHITESPACE, T_COMMENT, T_DOC_COMMENT], true)) {
|
||||||
|
$encoded[] = json_encode([$id, $text], JSON_THROW_ON_ERROR);
|
||||||
|
$offsets[] = $offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
$offset += strlen($text);
|
||||||
|
}
|
||||||
|
|
||||||
|
return [implode("\n", $encoded), $offsets];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function position(string $source, string $fragment) : int|false {
|
||||||
|
[$encoded, $offsets] = self::encode($source);
|
||||||
|
[$needle] = self::encode($fragment, true);
|
||||||
|
$match = self::match($encoded, $needle);
|
||||||
|
|
||||||
|
return $match === false ? false : $offsets[substr_count(substr($encoded, 0, $match), "\n")];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function count(string $source, string $fragment) : int {
|
||||||
|
[$encoded] = self::encode($source);
|
||||||
|
[$needle] = self::encode($fragment, true);
|
||||||
|
$count = 0;
|
||||||
|
$offset = 0;
|
||||||
|
|
||||||
|
while (($match = self::match($encoded, $needle, $offset)) !== false) {
|
||||||
|
$count++;
|
||||||
|
$offset = $match + strlen($needle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $count;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function match(string $source, string $needle, int $offset = 0) : int|false {
|
||||||
|
if ($needle === '') {
|
||||||
|
throw new \InvalidArgumentException('A PHP source contract needs at least one token.');
|
||||||
|
}
|
||||||
|
|
||||||
|
while (($match = strpos($source, $needle, $offset)) !== false) {
|
||||||
|
$end = $match + strlen($needle);
|
||||||
|
|
||||||
|
if (($match === 0 || $source[$match - 1] === "\n") &&
|
||||||
|
($end === strlen($source) || $source[$end] === "\n")) {
|
||||||
|
return $match;
|
||||||
|
}
|
||||||
|
|
||||||
|
$offset = $match + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect()->extend('toContainPhp', function (string $fragment) {
|
||||||
|
\PHPUnit\Framework\Assert::assertNotFalse(
|
||||||
|
PhpSource::position($this->value, $fragment),
|
||||||
|
'Expected PHP token sequence: ' . $fragment
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
});
|
||||||
@@ -53,14 +53,34 @@ test('archive-table drop is gated on shard completeness, not the status sum', fu
|
|||||||
test('partial-completion path logs a warning instead of silently keeping the tables', function () use ($boostPollerPath) {
|
test('partial-completion path logs a warning instead of silently keeping the tables', function () use ($boostPollerPath) {
|
||||||
$contents = file_get_contents($boostPollerPath);
|
$contents = file_get_contents($boostPollerPath);
|
||||||
|
|
||||||
$drop_pos = strpos($contents, 'DROP TABLE IF EXISTS `$table`');
|
$parser = (new \PhpParser\ParserFactory())->createForNewestSupportedVersion();
|
||||||
expect($drop_pos)->not->toBeFalse();
|
$finder = new \PhpParser\NodeFinder();
|
||||||
|
$printer = new \PhpParser\PrettyPrinter\Standard();
|
||||||
|
$branches = $finder->findInstanceOf($parser->parse($contents), \PhpParser\Node\Stmt\If_::class);
|
||||||
|
$gate = null;
|
||||||
|
|
||||||
// Search a window around the drop for the else branch that must log when
|
foreach ($branches as $branch) {
|
||||||
// completeness is not met.
|
$condition = $printer->prettyPrintExpr($branch->cond);
|
||||||
$window = substr($contents, max(0, $drop_pos - 200), 1200);
|
|
||||||
|
|
||||||
expect($window)->toContain('leaving archive tables in place for the next run to pick up');
|
if (str_contains($condition, 'boost_completed_children($run_id) >= $expected_children')) {
|
||||||
|
$gate = $branch;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect($gate)->not->toBeNull();
|
||||||
|
expect($gate->else)->not->toBeNull();
|
||||||
|
$logs = $finder->find($gate->else->stmts, fn ($node) => $node instanceof \PhpParser\Node\Expr\FuncCall &&
|
||||||
|
$node->name instanceof \PhpParser\Node\Name &&
|
||||||
|
$node->name->toString() === 'cacti_log'
|
||||||
|
);
|
||||||
|
expect($logs)->toHaveCount(1);
|
||||||
|
$format = array_values($logs)[0]->args[0]->value;
|
||||||
|
expect($format)->toBeInstanceOf(\PhpParser\Node\Expr\FuncCall::class);
|
||||||
|
expect($format->name->toString())->toBe('sprintf');
|
||||||
|
$message = (new \PhpParser\ConstExprEvaluator())->evaluateDirectly($format->args[0]->value);
|
||||||
|
expect($message)->toContain('leaving archive tables in place for the next run to pick up');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('boost_completed_children and expected_children are still computed the same way the drain loop uses', function () use ($boostPollerPath) {
|
test('boost_completed_children and expected_children are still computed the same way the drain loop uses', function () use ($boostPollerPath) {
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
// Copyright (C) 2004-2026 The Cacti Group. GPL-2.0-or-later.
|
||||||
|
|
||||||
|
require_once dirname(__DIR__, 2) . '/Helpers/PhpSource.php';
|
||||||
|
|
||||||
|
use Cacti\Tests\Helpers\PhpSource;
|
||||||
|
|
||||||
|
test('PHP source contracts tolerate whitespace without changing literal contents', function () {
|
||||||
|
$source = "<?php guard(\n\t\$path, /* boundary */\n\t'line\\n literal');";
|
||||||
|
|
||||||
|
expect(PhpSource::position($source, "guard(\$path, 'line\\n literal')"))->toBe(6)
|
||||||
|
->and(PhpSource::position($source, "guard(\$path, 'line literal')"))->toBeFalse();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('PHP source contracts reject text in comments or quoted strings', function () {
|
||||||
|
$source = '<?php /* guard($path); */ $message = \'guard($path);\';';
|
||||||
|
|
||||||
|
expect(PhpSource::count($source, 'guard($path)'))->toBe(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('PHP source contracts retain argument order and original byte offsets', function () {
|
||||||
|
$source = "<?php guard(\n\t\$path, \$base);\nguard(\$base, \$path);";
|
||||||
|
|
||||||
|
expect(PhpSource::count($source, 'guard($path, $base)'))->toBe(1)
|
||||||
|
->and(PhpSource::position($source, 'guard($base, $path)'))->toBe(strrpos($source, 'guard'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('PHP whitespace normalization preserves literal contents and removes comment-only contracts', function () {
|
||||||
|
$source = '<?php $value = "one two\\n";' . "\n" .
|
||||||
|
'/* db_qstr("comment only"); */ db_qstr(' . "\n\t" . '$value' . "\n" . ');';
|
||||||
|
$normalized = \Cacti\Tests\Helpers\PhpSource::normalizeWhitespace($source);
|
||||||
|
expect($normalized)->toContain('"one two\\n"');
|
||||||
|
expect($normalized)->not->toContain('comment only');
|
||||||
|
expect($normalized)->toContain('db_qstr( $value );');
|
||||||
|
});
|
||||||
@@ -32,8 +32,10 @@
|
|||||||
* https://github.com/Cacti/cacti/issues/6647
|
* https://github.com/Cacti/cacti/issues/6647
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$pollerPath = __DIR__ . '/../../../../poller_spikekill.php';
|
require_once dirname(__DIR__, 3) . '/Helpers/PhpSource.php';
|
||||||
$spikeLib = __DIR__ . '/../../../../lib/spikekill.php';
|
|
||||||
|
$pollerPath = __DIR__ . '/../../../../poller_spikekill.php';
|
||||||
|
$spikeLib = __DIR__ . '/../../../../lib/spikekill.php';
|
||||||
$globalSettings = __DIR__ . '/../../../../include/global_settings.php';
|
$globalSettings = __DIR__ . '/../../../../include/global_settings.php';
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -65,7 +67,7 @@ test('poller_spikekill.php --rrdfile argument uses cacti_escapeshellarg not raw
|
|||||||
$src = file_get_contents($pollerPath);
|
$src = file_get_contents($pollerPath);
|
||||||
|
|
||||||
// Ensure the full safe pattern is present.
|
// Ensure the full safe pattern is present.
|
||||||
expect($src)->toContain("' --rrdfile=' . cacti_escapeshellarg(\$f)");
|
expect($src)->toContainPhp("' --rrdfile=' . cacti_escapeshellarg(\$f)");
|
||||||
});
|
});
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -12,14 +12,34 @@ test('database repair clears every direct graph reference to a missing CDEF', fu
|
|||||||
|
|
||||||
expect($source)->not->toBeFalse();
|
expect($source)->not->toBeFalse();
|
||||||
|
|
||||||
|
$parser = (new \PhpParser\ParserFactory())->createForNewestSupportedVersion();
|
||||||
|
$nodes = $parser->parse($source);
|
||||||
|
$constantString = static function (\PhpParser\Node $node) use (&$constantString): ?string {
|
||||||
|
if ($node instanceof \PhpParser\Node\Scalar\String_) {
|
||||||
|
return $node->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($node instanceof \PhpParser\Node\Expr\BinaryOp\Concat) {
|
||||||
|
$left = $constantString($node->left);
|
||||||
|
$right = $constantString($node->right);
|
||||||
|
|
||||||
|
return $left !== null && $right !== null ? $left . $right : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
$calls = (new \PhpParser\NodeFinder())->find($nodes, static fn ($node) => $node instanceof \PhpParser\Node\Expr\FuncCall &&
|
||||||
|
$node->name instanceof \PhpParser\Node\Name &&
|
||||||
|
in_array($node->name->toString(), ['db_fetch_cell', 'db_execute'], true));
|
||||||
|
$queries = array_map(static fn ($call) => $constantString($call->args[0]->value), $calls);
|
||||||
|
|
||||||
foreach (['graph_templates_item', 'aggregate_graph_templates_item', 'aggregate_graphs_graph_item'] as $table) {
|
foreach (['graph_templates_item', 'aggregate_graph_templates_item', 'aggregate_graphs_graph_item'] as $table) {
|
||||||
expect($source)->toContain($table);
|
expect($queries)->toContain("SELECT COUNT(*) FROM $table AS source LEFT JOIN cdef ON source.cdef_id = cdef.id WHERE source.cdef_id > 0 AND cdef.id IS NULL");
|
||||||
|
$clear = $table === 'graph_templates_item' ? 'cdef_id = 0' : "cdef_id = 0, t_cdef_id = ''";
|
||||||
|
expect($queries)->toContain("UPDATE $table SET $clear WHERE cdef_id > 0 AND cdef_id NOT IN (SELECT id FROM cdef)");
|
||||||
}
|
}
|
||||||
|
|
||||||
expect($source)->toContain('LEFT JOIN cdef ON source.cdef_id = cdef.id')
|
expect($source)->toContain('Found $invalid_references graph item references')
|
||||||
->and($source)->toContain('cdef_id NOT IN (SELECT id FROM cdef)')
|
|
||||||
->and($source)->toContain("cdef_id = 0, t_cdef_id = ''")
|
|
||||||
->and($source)->toContain('Found $invalid_references graph item references')
|
|
||||||
->and($source)->toContain('Found and repaired $fixed_references of $invalid_references');
|
->and($source)->toContain('Found and repaired $fixed_references of $invalid_references');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
class location match
|
class location match
|
||||||
cmd_exec ./cactid.php exec('pgrep -a php | grep cactid.php', $output);
|
cmd_exec ./cactid.php exec('pgrep -a php | grep cactid.php', $output);
|
||||||
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_PLUGINS . '/' . $pname . '/database_upgrade.php --type=large --force-ver=' . $old, $output, $return_var);
|
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_PLUGINS . '/' . $pname . '/database_upgrade.php --type=large --force-ver=' . $old,
|
||||||
cmd_exec ./cli/audit_database.php $db_shell = trim((string) shell_exec('which mysql'));
|
cmd_exec ./cli/audit_database.php $db_shell = trim((string) shell_exec('which mysql'));
|
||||||
cmd_exec ./cli/audit_database.php exec($cmd, $output, $error);
|
cmd_exec ./cli/audit_database.php exec($cmd, $output, $error);
|
||||||
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_CLI . '/upgrade_database.php --debug', $output, $return_var);
|
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_CLI . '/upgrade_database.php --debug', $output, $return_var);
|
||||||
|
|||||||
|
@@ -1,6 +1,6 @@
|
|||||||
category location match
|
category location match
|
||||||
cmd_exec ./cactid.php exec('pgrep -a php | grep cactid.php', $output);
|
cmd_exec ./cactid.php exec('pgrep -a php | grep cactid.php', $output);
|
||||||
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_PLUGINS . '/' . $pname . '/database_upgrade.php --type=large --force-ver=' . $old, $output, $return_var);
|
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_PLUGINS . '/' . $pname . '/database_upgrade.php --type=large --force-ver=' . $old,
|
||||||
cmd_exec ./cli/audit_database.php $db_shell = trim((string) shell_exec('which mysql'));
|
cmd_exec ./cli/audit_database.php $db_shell = trim((string) shell_exec('which mysql'));
|
||||||
cmd_exec ./cli/audit_database.php exec($cmd, $output, $error);
|
cmd_exec ./cli/audit_database.php exec($cmd, $output, $error);
|
||||||
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_CLI . '/upgrade_database.php --debug', $output, $return_var);
|
cmd_exec ./cli/audit_database.php exec('php ' . CACTI_PATH_CLI . '/upgrade_database.php --debug', $output, $return_var);
|
||||||
|
|||||||
|
@@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
// Copyright (C) 2004-2026 The Cacti Group. GPL-2.0-or-later.
|
||||||
|
|
||||||
|
require dirname(__DIR__, 2) . '/include/vendor/autoload.php';
|
||||||
|
|
||||||
|
/** Compare parsed behavior, preserving literal values and argument order. */
|
||||||
|
function formatting_ast($value) {
|
||||||
|
if ($value instanceof PhpParser\Node\Expr\BinaryOp\Concat) {
|
||||||
|
$left = formatting_ast($value->left);
|
||||||
|
$right = formatting_ast($value->right);
|
||||||
|
|
||||||
|
if (($left['type'] ?? '') === 'Scalar_String' && ($right['type'] ?? '') === 'Scalar_String') {
|
||||||
|
return ['type' => 'Scalar_String', 'value' => $left['value'] . $right['value']];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['type' => $value->getType(), 'left' => $left, 'right' => $right];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($value instanceof PhpParser\Node) {
|
||||||
|
$result = ['type' => $value->getType()];
|
||||||
|
|
||||||
|
foreach ($value->getSubNodeNames() as $name) {
|
||||||
|
$result[$name] = formatting_ast($value->$name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($value)) {
|
||||||
|
return array_map('formatting_ast', $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatting_git(array $arguments) : string {
|
||||||
|
$process = proc_open(array_merge(['git'], $arguments), [1 => ['pipe', 'w'], 2 => ['pipe', 'w']], $pipes);
|
||||||
|
|
||||||
|
if (!is_resource($process)) {
|
||||||
|
throw new RuntimeException('Could not start Git');
|
||||||
|
}
|
||||||
|
$output = stream_get_contents($pipes[1]);
|
||||||
|
$error = stream_get_contents($pipes[2]);
|
||||||
|
fclose($pipes[1]);
|
||||||
|
fclose($pipes[2]);
|
||||||
|
|
||||||
|
if (proc_close($process) !== 0) {
|
||||||
|
throw new RuntimeException($error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parser = (new PhpParser\ParserFactory())->createForNewestSupportedVersion();
|
||||||
|
$options = getopt('', ['base:', 'self-test']);
|
||||||
|
|
||||||
|
if (isset($options['self-test'])) {
|
||||||
|
$cases = [
|
||||||
|
['guard($a, $b);', "/* comment */ guard(\n\t\$a, \$b);", true],
|
||||||
|
['echo "one two";', 'echo "one " . "two";', true],
|
||||||
|
['echo "one two";', 'echo "one " . "t" . "wo";', true],
|
||||||
|
['echo "one two";', 'echo "one two";', false],
|
||||||
|
['guard($a, $b);', 'guard($b, $a);', false],
|
||||||
|
['if ($ok) save();', 'if (!$ok) save();', false],
|
||||||
|
['echo $a . $b . "end";', 'echo $a . ($b . "end");', false],
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($cases as [$before, $after, $equal]) {
|
||||||
|
$actual = formatting_ast($parser->parse('<?php ' . $before)) === formatting_ast($parser->parse('<?php ' . $after));
|
||||||
|
|
||||||
|
if ($actual !== $equal) {
|
||||||
|
throw new RuntimeException('Formatting checker regression: ' . $before);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print count($cases) . " formatting checker contracts passed.\n";
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($options['base'])) {
|
||||||
|
fwrite(STDERR, "Usage: php tests/tools/check_php_formatting.php --base COMMIT\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
$base = trim(formatting_git(['merge-base', $options['base'], 'HEAD']));
|
||||||
|
$files = array_filter(explode("\n", trim(formatting_git([
|
||||||
|
'-c', 'core.quotePath=false', 'diff', '--no-ext-diff', '--no-textconv', '--name-only',
|
||||||
|
$base, 'HEAD', '--', '*.php', ':(exclude)tests/**', ':(exclude)include/vendor/**'
|
||||||
|
]))));
|
||||||
|
$failed = false;
|
||||||
|
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$before = formatting_ast($parser->parse(formatting_git(['show', $base . ':' . $file])));
|
||||||
|
$after = formatting_ast($parser->parse(file_get_contents($file)));
|
||||||
|
|
||||||
|
if ($before !== $after) {
|
||||||
|
fwrite(STDERR, $file . ": parsed behavior differs; add behavior tests and measure coverage.\n");
|
||||||
|
$failed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print count($files) . " production PHP files checked for preserved behavior.\n";
|
||||||
|
exit($failed ? 1 : 0);
|
||||||
Reference in new issue
Block a user