Files
cacti/lib/dsdebug.php
T
Mark Brugnoli-Vinten 6e1b8431b7 Fixes for Issues 1781, 1782 and 1784 (#1785)
* Fixes for Issues 1781, 1782 and 1784

This patch corrects the following issues:

- #1782 During Install, changing the Theme from Modern to another theme has no
        effect
- #1784 During Install, changing the Language from one to another has no
        effect
- #1781 Installer does not warn when mysql optimizations not set

As part of #1781's fixes, a new warning icon is displayed instead of a thumbs
up or down.  Additionally, recommendations have been revamped so that the ones
which are optionally (and some even state can be ignored) are now optional!

Also, introduced the correct calculation for innodb instances by taking the
buffer size during a previous recommendation and calculating from that.  If
the buffer size is never found or the calcuation finds less than 1 instances
are recommended, a minimum of 1 is set.

The main reason for #1782 and #1784's issues were caused by renaming index.php
to install.php as part of the recent security update (see PR #1747).  Updated
the javascript to use the correct install.php and then removed some extra data
that was being returned outside of StepData unnecessarily.

* Further fixes

This update corrects a number of issues with the database upgrading code, adds
the 'debug' plugin from cigamit, improves database functions to be more
consistent with errors across all functions and various installer based fixes
for the display and update of database upgrades.

It also brings a more visual response to the cli/upgrade_database.php so that
end users are not left wondering if something is happening.  Also, reviewed
all upgrade scripts to ensure that an upgrade from 0.8.8 through to 1.2.0 is
possible even if a previous database upgrade have been done.

* Fix QA issue with 'path_cactilog'

Due to some code reshuffle and testing, found that the above setting was being
read via read_config_option() before there was a database open so no path was
ever detected unless the force option was used.
2018-08-05 10:43:01 -05:00

279 lines
9.7 KiB
PHP

<?php
/*
+-------------------------------------------------------------------------+
| Copyright (C) 2004-2018 The Cacti Group |
| |
| This program is free software; you can redistribute it and/or |
| modify it under the terms of the GNU General Public License |
| as published by the Free Software Foundation; either version 2 |
| of the License, or (at your option) any later version. |
| |
| This program is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU General Public License for more details. |
+-------------------------------------------------------------------------+
| Cacti: The Complete RRDtool-based Graphing Solution |
+-------------------------------------------------------------------------+
| This code is designed, written, and maintained by the Cacti Group. See |
| about.php and/or the AUTHORS file for specific developer information. |
+-------------------------------------------------------------------------+
| http://www.cacti.net/ |
+-------------------------------------------------------------------------+
*/
/* dsstats_debug - this simple routine print's a standard message to the console
when running in debug mode.
@returns - NULL */
function dsdebug_debug($message) {
global $debug;
if ($debug) {
print 'DSDEBUG: ' . $message . "\n";
}
}
/* log_dsstats_statistics - provides generic timing message to both the Cacti log and the settings
table so that the statistcs can be graphed as well.
@arg $type - (string) the type of statistics to log, either 'HOURLY', 'DAILY' or 'MAJOR'.
@returns - null */
function log_dsdebug_statistics($type) {
global $start;
/* take time and log performance data */
$end = microtime(true);
$cacti_stats = sprintf('Time:%01.4f ', round($end-$start,4));
/* take time and log performance data */
$start = microtime(true);
/* log to the database */
set_config_option('stats_dsdebug_' . $type, $cacti_stats);
/* log to the logfile */
cacti_log('DSDEBUG STATS: Type:' . $type . ', ' . $cacti_stats , true, 'SYSTEM');
}
/* dsstats_error_handler - this routine logs all PHP error transactions
to make sure they are properly logged.
@arg $errno - (int) The errornum reported by the system
@arg $errmsg - (string) The error message provides by the error
@arg $filename - (string) The filename that encountered the error
@arg $linenum - (int) The line number where the error occurred
@arg $vars - (mixed) The current state of PHP variables.
@returns - (bool) always returns true for some reason */
function dsdebug_error_handler($errno, $errmsg, $filename, $linenum, $vars) {
if (read_config_option('log_verbosity') >= POLLER_VERBOSITY_DEBUG) {
/* define all error types */
$errortype = array(
E_ERROR => 'Error',
E_WARNING => 'Warning',
E_PARSE => 'Parsing Error',
E_NOTICE => 'Notice',
E_CORE_ERROR => 'Core Error',
E_CORE_WARNING => 'Core Warning',
E_COMPILE_ERROR => 'Compile Error',
E_COMPILE_WARNING => 'Compile Warning',
E_USER_ERROR => 'User Error',
E_USER_WARNING => 'User Warning',
E_USER_NOTICE => 'User Notice',
E_STRICT => 'Runtime Notice'
);
if (defined('E_RECOVERABLE_ERROR')) {
$errortype[E_RECOVERABLE_ERROR] = 'Catchable Fatal Error';
}
/* create an error string for the log */
$err = "ERRNO:'" . $errno . "' TYPE:'" . $errortype[$errno] .
"' MESSAGE:'" . $errmsg . "' IN FILE:'" . $filename .
"' LINE NO:'" . $linenum . "'";
/* let's ignore some lesser issues */
if (substr_count($errmsg, 'date_default_timezone')) return;
if (substr_count($errmsg, 'Only variables')) return;
/* log the error to the Cacti log */
cacti_log('PROGERR: ' . $err, false, 'DSDEBUG');
}
return;
}
function dsdebug_poller_output(&$rrd_update_array) {
global $config, $ds_types, $ds_last, $ds_steps, $ds_multi;
/* suppress warnings */
if (defined('E_DEPRECATED')) {
error_reporting(E_ALL ^ E_DEPRECATED);
} else {
error_reporting(E_ALL);
}
/* install the dsstats error handler */
set_error_handler('dsdebug_error_handler');
/* do not make any calculations unless enabled */
$checks = db_fetch_assoc('SELECT * FROM data_debug WHERE `done` = 0');
if (sizeof($checks)) {
if (sizeof($rrd_update_array) > 0) {
foreach ($checks as $c) {
foreach($rrd_update_array as $item) {
if ($c['datasource'] == $item['local_data_id']) {
if (isset($item['times'][key($item['times'])])) {
$c['info'] = unserialize($c['info']);
$c['info']['last_result'] = $item['times'][key($item['times'])];
$c['info'] = serialize($c['info']);
db_execute_prepared('UPDATE data_debug SET `info` = ? WHERE `id` = ?', array($c['info'], $c['id']));
}
}
}
}
}
}
/* restore original error handler */
restore_error_handler();
}
function dsdebug_poller_bottom () {
global $config;
/* install the dsstats error handler */
set_error_handler('dsdebug_error_handler');
$checks = db_fetch_assoc('SELECT * FROM data_debug WHERE `done` = 0');
if (!empty($checks)) {
clearstatcache();
foreach ($checks as $c) {
$c['issue'] = array();
$info = unserialize($c['info']);
$dtd = db_fetch_row_prepared('SELECT * from data_template_data WHERE local_data_id = ?', array($c['datasource']));
if (!isset($dtd['local_data_id'])) {
$c['issue'][] = __('Data Source does not exist','DSDEBUG');
$c['done'] = 1;
} else {
if (read_config_option('boost_rrd_update_enable') == 'on') {
boost_process_poller_output($c['datasource']);
}
$real_pth = str_replace('<path_rra>', $config['rra_path'], $dtd['data_source_path']);
// rrd_folder_writable
$info['rrd_folder_writable'] = (is_resource_writable(dirname($real_pth) . '/') ? 1 : 0);
// rrd_exists
$info['rrd_exists'] = (file_exists($real_pth) ? 1 : 0);
// rrd_writable
$info['rrd_writable'] = (is_resource_writable($real_pth) ? 1 : 0);
// active
$info['active'] = $dtd['active'];
// owner
if ($config['cacti_server_os'] == 'win32') {
$info['owner'] = '<unable to determine on windows>';
} else {
$o = posix_getpwuid(fileowner($real_pth));
$o = $o['name'];
$g = posix_getgrgid(filegroup($real_pth));
$g = $g['name'];
$info['owner'] = $o . ':' . $g;
}
// poller_runas
$info['runas_poller'] = get_running_user();
// convert_name
$info['convert_name'] = (strpos('|', get_data_source_title($c['datasource'])) === FALSE ? 1 : 0);
// last_result (processed by hook)
if (is_array($info['last_result']) && !empty($info['last_result']) && $info['valid_data'] == '') {
$info['valid_data'] = 1;
foreach ($info['last_result'] as $k => $l) {
if ($l == 'U') {
cacti_log("Bad Data Found", false, 'DSDEBUG');
$info['valid_data'] = 0;
}
}
}
// rrd_match
$rrdinfo = rrdtool_function_info($c['datasource']);
$comp = rrdtool_cacti_compare($c['datasource'], $rrdinfo);
$info['rrd_match'] = (is_array($comp) && empty($comp) ? 1 : 0);
$info['rrd_match_array'] = $comp;
$info['rrd_info'] = $rrdinfo;
// rra_timestamp
if ($info['rra_timestamp'] != '' && isset($rrdinfo['last_update']) && $info['rra_timestamp'] != $rrdinfo['last_update']) {
$info['rra_timestamp2'] = $rrdinfo['last_update'];
}
if (isset($rrdinfo['last_update']) && $info['rra_timestamp'] == '') {
$info['rra_timestamp'] = $rrdinfo['last_update'];
}
$c['done'] = 1;
$f = array();
foreach ($info as $k => $v) {
if ($v === '') {
$c['done'] = 0;
$f[] = $k;
}
}
if ($c['started'] < time() - ($dtd['rrd_step'] * 5)) {
$c['done'] = 1;
$c['issue'][] = __('Debug not completed after 5 pollings');
$c['issue'][] = __('Failed fields: ') . implode($f, ', ');
}
if ($c['done'] == 1) {
// Try to determine issue
// Not set as Active
if ($info['active'] != 'on') {
$c['issue'][] = __('Data Source is not set as Active');
}
// File Permissions
if ((!$info['rrd_exists'] || !$info['rrd_writable']) && !$info['rrd_folder_writable']) {
$c['issue'][] = __('RRD Folder is not writable by Poller. RRD Owner: ') . $o . __(' Poller RunAs: ') . $info['poller_runas'];
} elseif (!$info['rrd_writable']) {
$c['issue'][] = __('RRD File is not writable by Poller. RRD Owner: ') . $o . __(' Poller RunAs: ') . $info['poller_runas'];
}
if ($info['rrd_match'] == 0) {
$c['issue'][] = __('RRD File does not match Data Profile');
}
if ($info['rra_timestamp2'] == '') {
$c['issue'][] = __('RRD File not updated after polling');
}
if (is_array($info['last_result']) && !empty($info['last_result'])) {
foreach ($info['last_result'] as $k => $l) {
if ($l == 'U') {
$c['issue'][] = __('Data Source returned Bad Results for ' . $k);
}
}
} elseif ($info['last_result'] == '') {
$c['issue'][] = __('Data Source was not polled');
}
if ($c['issue'] == '') {
$c['issue'][] = __('No issues found');
}
}
}
$info = serialize($info);
db_execute_prepared('UPDATE data_debug SET `done` = ?, `info` = ?, `issue` = ? WHERE id = ?', array($c['done'], $info, trim(implode("\n", $c['issue'])), $c['id']));
}
}
restore_error_handler();
}