__('Run Check'),
2 => __('Delete Check')
];
ini_set('memory_limit', '-1');
set_default_action();
draw_data_debug_filter(false);
if (in_array(grv('action'), ['run_repair', 'run_debug'], true)) {
csrf_require_post();
}
switch (grv('action')) {
case 'actions':
form_actions();
break;
case 'run_debug':
$id = gfrv('id');
if ($id > 0) {
$selected_items = [$id];
debug_delete($selected_items);
debug_rerun($selected_items);
raise_message('rerun', __('Data Source debug started.'), MESSAGE_LEVEL_INFO);
header('Location: data_debug.php?action=view&id=' . gfrv('id'));
} else {
raise_message('repair_error', __('Data Source debug received an invalid Data Source ID.'), MESSAGE_LEVEL_ERROR);
}
break;
case 'run_repair':
$id = gfrv('id');
if ($id > 0) {
if (dsdebug_run_repair($id)) {
raise_message('repair', __('All RRDfile repairs succeeded.'), MESSAGE_LEVEL_INFO);
} else {
raise_message('repair', __('One or more RRDfile repairs failed. See Cacti log for errors.'), MESSAGE_LEVEL_ERROR);
}
$selected_items = [$id];
debug_delete($selected_items);
debug_rerun($selected_items);
raise_message('rerun', __('Automatic Data Source debug being rerun after repair.'), MESSAGE_LEVEL_INFO);
header('Location: data_debug.php?action=view&id=' . gfrv('id'));
} else {
raise_message('repair_error', __('Data Source repair received an invalid Data Source ID.'), MESSAGE_LEVEL_ERROR);
}
break;
case 'view':
$id = gfrv('id');
$debug_status = debug_process_status($id);
if ($debug_status == 'notset') {
$selected_items = [$id];
debug_delete($selected_items);
debug_rerun($selected_items);
$debug_status = 'waiting';
}
if ($debug_status == 'waiting' || $debug_status == 'analysis') {
$refresh = [
'seconds' => 30,
'page' => 'data_debug.php?action=view&id=' . $id,
'logout' => 'false'
];
set_page_refresh($refresh);
}
top_header();
debug_view();
bottom_footer();
break;
case 'ajax_hosts':
$sql_where = '';
if (gfrv('site_id') > 0) {
$sql_where = 'site_id = ' . gfrv('site_id');
}
get_allowed_ajax_hosts(true, true, $sql_where);
break;
case 'ajax_hosts_noany':
$sql_where = '';
if (gfrv('site_id') > 0) {
$sql_where = 'site_id = ' . gfrv('site_id');
}
get_allowed_ajax_hosts(false, true, $sql_where);
break;
case 'runall':
debug_runall_filtered();
// Fall through: render the refreshed list after running the selected sources.
default:
$refresh = [
'seconds' => grv('refresh'),
'page' => 'data_debug.php',
'logout' => 'false'
];
set_page_refresh($refresh);
top_header();
debug_wizard();
bottom_footer();
break;
}
function debug_runall_filtered() : void {
$info = [
'rrd_folder_writable' => '',
'rrd_exists' => '',
'rrd_writable' => '',
'active' => '',
'owner' => '',
'runas_poller' => '',
'runas_website' => get_running_user(),
'last_result' => '',
'valid_data' => '',
'rra_timestamp' => '',
'rra_timestamp2' => '',
'rrd_match' => ''
];
$info = serialize($info);
$sql_where = '';
$sql_params = [];
$dd_join = '';
$now = time();
debug_get_filter($sql_where, $sql_params, $dd_join);
db_execute_prepared("DELETE dd
FROM data_debug AS dd
INNER JOIN data_local AS dl
ON dd.datasource = dl.id
INNER JOIN data_template_data AS dtd
ON dl.id=dtd.local_data_id
INNER JOIN data_template AS dt
ON dt.id=dl.data_template_id
INNER JOIN host AS h
ON h.id = dl.host_id
$sql_where",
$sql_params);
$new_params = [$now, $info, $_SESSION[SESS_USER_ID]];
$sql_params = $new_params + $sql_params;
db_execute_prepared("INSERT INTO data_debug
(started, done, info, user, datasource)
SELECT ?, '0', ?, ?, dl.id
FROM data_local AS dl
INNER JOIN data_template_data AS dtd
ON dl.id=dtd.local_data_id
INNER JOIN data_template AS dt
ON dt.id=dl.data_template_id
INNER JOIN host AS h
ON h.id = dl.host_id
$sql_where",
$sql_params);
}
function debug_process_status(int $id) : string {
$status = db_fetch_row_prepared('SELECT done, IFNULL(issue, "waiting") AS issue
FROM data_debug
WHERE datasource = ?',
[$id]);
if (cacti_sizeof($status) == 0) {
return 'notset';
}
if ($status['issue'] == 'waiting') {
return 'waiting';
}
if ($status['done'] == 1) {
return 'complete';
} else {
return 'analysis';
}
}
function form_actions() : void {
global $actions, $assoc_actions;
// ================= input validation =================
gfrv('id');
gfrv('drp_action', FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => '/^([a-zA-Z0-9_]+)$/']]);
// ================= input validation =================
$selected_items = [];
if (isrv('save_list')) {
// loop through each of the lists selected on the previous page and get more info about them
foreach ($_POST as $var=>$val) {
if (preg_match('/^chk_([0-9]+)$/', $var, $matches)) {
// ================= input validation =================
input_validate_input_number($matches[1], 'chk[1]');
// ====================================================
$selected_items[] = $matches[1];
}
}
// if we are to save this form, instead of display it
if (isrv('save_list')) {
if (grv('drp_action') == '2') { // delete
debug_delete($selected_items);
header('Location: data_debug.php?debug=-1');
} elseif (grv('drp_action') == '1') { // Rerun
debug_rerun($selected_items);
header('Location: data_debug.php?debug=1');
}
exit;
}
}
}
function debug_rerun(array $selected_items) : void {
$info = [
'rrd_folder_writable' => '',
'rrd_exists' => '',
'rrd_writable' => '',
'active' => '',
'owner' => '',
'runas_poller' => '',
'runas_website' => get_running_user(),
'last_result' => '',
'valid_data' => '',
'rra_timestamp' => '',
'rra_timestamp2' => '',
'rrd_match' => ''
];
$info = serialize($info);
if (!empty($selected_items)) {
foreach ($selected_items as $id) {
$exists = db_fetch_cell_prepared('SELECT id
FROM data_debug
WHERE datasource = ?',
[$id]);
if (!$exists) {
$save = [];
$save['id'] = 0;
$save['datasource'] = $id;
$save['info'] = $info;
$save['started'] = time();
$save['user'] = intval($_SESSION[SESS_USER_ID]);
$id = sql_save($save, 'data_debug');
} else {
$stime = time();
db_execute_prepared('UPDATE data_debug
SET started = ?,
done = 0,
info = ?,
issue = ""
WHERE id = ?',
[$stime, $info, $exists]);
}
}
}
}
function debug_delete(array $selected_items) : void {
if (!empty($selected_items)) {
foreach ($selected_items as $id) {
db_execute_prepared('DELETE
FROM data_debug
WHERE datasource = ?',
[$id]);
}
}
}
function debug_get_filter(string &$sql_where, array &$sql_params, string &$dd_join) : void {
// form the 'where' clause for our main sql query
if (grv('rfilter') != '') {
$sql_where = 'WHERE (dtd.name_cache RLIKE ? OR dtd.local_data_id RLIKE ? OR dt.name RLIKE ?)';
$sql_params[] = grv('rfilter');
$sql_params[] = grv('rfilter');
$sql_params[] = grv('rfilter');
}
if (ierv('host_id')) {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' (dl.host_id = 0 OR dl.host_id IS NULL)';
} elseif (grv('host_id') > 0) {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dl.host_id = ?';
$sql_params[] = grv('host_id');
}
if (ierv('site_id')) {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' (h.site_id = 0 OR h.site_id IS NULL)';
} elseif (grv('site_id') > 0) {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' h.site_id = ?';
$sql_params[] = grv('site_id');
}
if (grv('template_id') == '0') {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dtd.data_template_id = 0';
} elseif (grv('template_id') > 0) {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dtd.data_template_id = ?';
$sql_params[] = grv('template_id');
}
if (grv('profile') > '-1') {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dtd.data_source_profile_id = ?';
$sql_params[] = grv('profile');
}
if (grv('status') == '0') {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dd.issue != ""';
} elseif (grv('status') == '1') {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dtd.active = "on"';
} elseif (grv('status') != '-1') {
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dtd.active = ""';
}
if (grv('debug') == '-1') {
$dd_join = 'LEFT';
} elseif (grv('debug') == 0) {
$dd_join = 'LEFT';
$sql_where .= ($sql_where != '' ? ' AND' : 'WHERE') . ' dd.datasource IS NULL';
} else {
$dd_join = 'INNER';
}
}
function debug_wizard() : void {
global $actions;
$display_text = [
'name_cache' => [
'display' => __('Data Source'),
'sort' => 'ASC',
'tip' => __('The Data Source to Debug'),
],
'username' => [
'display' => __('User'),
'sort' => 'ASC',
'tip' => __('The User who requested the Debug.'),
],
'started' => [
'display' => __('Started'),
'sort' => 'DESC',
'align' => 'right',
'tip' => __('The Date that the Debug was Started.'),
],
'local_data_id' => [
'display' => __('ID'),
'sort' => 'ASC',
'align' => 'right',
'tip' => __('The Data Source internal ID.'),
],
'nosort1' => [
'display' => __('Status'),
'sort' => 'ASC',
'align' => 'center',
'tip' => __('The Status of the Data Source Debug Check.'),
],
'nosort2' => [
'display' => __('Writable'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the Data Collector or the Web Site have Write access.'),
],
'nosort3' => [
'display' => __('Exists'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the Data Source is located in the Poller Cache.'),
],
'nosort4' => [
'display' => __('Active'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the Data Source is Enabled.'),
],
'nosort5' => [
'display' => __('RRD Match'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the RRDfile matches the Data Source Template.'),
],
'nosort6' => [
'display' => __('Valid Data'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the RRDfile has been getting good recent Data.'),
],
'nosort7' => [
'display' => __('RRD Updated'),
'align' => 'center',
'sort' => '',
'tip' => __('Determines if the RRDfile has been written to properly.'),
],
'nosort8' => [
'display' => __('Issues'),
'align' => 'right',
'sort' => '',
'tip' => __('Summary of issues found for the Data Source.'),
]
];
if (isrv('purge')) {
db_execute('TRUNCATE TABLE data_debug');
}
// fill in the current date for printing in the log
if (defined('CACTI_DATE_TIME_FORMAT')) {
$datefmt = CACTI_DATE_TIME_FORMAT;
} else {
$datefmt = 'Y-m-d H:i:s';
}
draw_data_debug_filter(true);
$total_rows = 0;
$checks = [];
if (grv('rows') == '-1') {
$rows = read_config_option('num_rows_table');
} else {
$rows = grv('rows');
}
$sql_where = '';
$sql_params = [];
$dd_join = '';
debug_get_filter($sql_where, $sql_params, $dd_join);
$total_rows = db_fetch_cell_prepared("SELECT COUNT(*)
FROM data_local AS dl
INNER JOIN data_template_data AS dtd
ON dl.id=dtd.local_data_id
INNER JOIN data_template AS dt
ON dt.id=dl.data_template_id
INNER JOIN host AS h
ON h.id = dl.host_id
$dd_join JOIN data_debug AS dd
ON dl.id = dd.datasource
$sql_where",
$sql_params);
$sql_order = get_order_string();
$sql_limit = ' LIMIT ' . ($rows * (grv('page') - 1)) . ',' . $rows;
$checks = db_fetch_assoc_prepared("SELECT dd.*, dtd.local_data_id,
dtd.name_cache, u.username
FROM data_local AS dl
INNER JOIN data_template_data AS dtd
ON dl.id=dtd.local_data_id
INNER JOIN data_template AS dt
ON dt.id=dl.data_template_id
INNER JOIN host AS h
ON h.id = dl.host_id
$dd_join JOIN data_debug AS dd
ON dl.id = dd.datasource
LEFT JOIN user_auth AS u
ON u.id = dd.user
$sql_where
$sql_order
$sql_limit",
$sql_params);
$nav = html_nav_bar('data_debug.php', MAX_DISPLAY_PAGES, grv('page'), $rows, $total_rows, cacti_sizeof($display_text) + 1, __('Data Sources'), 'page', 'main');
form_start('data_debug.php', 'chk');
print $nav;
html_start_box('', '100%', false, 3, 'center', '');
html_header_sort_checkbox($display_text, grv('sort_column'), grv('sort_direction'), false);
if (cacti_sizeof($checks)) {
foreach ($checks as $check) {
if (isset($check['info']) && $check['info'] != '') {
$info = cacti_unserialize($check['info']);
} else {
$info = '';
}
if (isset($check['issue']) && $check['issue'] != '') {
$issues = explode("\n", $check['issue']);
} else {
$issues = [];
}
$iline = '';
if (cacti_sizeof($issues)) {
$iline = $issues[0];
}
$issue_title = implode('
',$issues);
form_alternate_row('line' . $check['local_data_id']);
$url = 'data_debug.php?action=view&id=' . $check['local_data_id'];
form_selectable_cell(filter_value($check['name_cache'], grv('rfilter'), $url), $check['local_data_id']);
if (!empty($check['datasource'])) {
form_selectable_ecell($check['username'], $check['local_data_id']);
form_selectable_cell(date($datefmt, $check['started']), $check['local_data_id'], '', 'right');
form_selectable_cell($check['local_data_id'], $check['local_data_id'], '', 'right');
form_selectable_cell(debug_icon(($check['done'] ? ($iline != '' ? 'off' : 'on') : '')), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['rrd_writable']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['rrd_exists']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['active']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['rrd_match']), $check['local_data_id'], '', 'center');
form_selectable_cell(debug_icon($info['valid_data']), $check['local_data_id'], '', 'center');
if ($check['done'] && $info['rrd_writable'] == '') {
form_selectable_cell(debug_icon('blah'), $check['local_data_id'], '', 'center');
} else {
form_selectable_cell(debug_icon(($info['rra_timestamp2'] != '' ? 1 : '')), $check['local_data_id'], '', 'center');
}
form_selectable_cell(filter_value($iline != '' ? __('Issues') : __('N/A'), '', '#', $issue_title), $check['local_data_id'], '', 'right');
} else {
form_selectable_cell('-', $check['local_data_id']);
form_selectable_cell(__('Not Debugging'), $check['local_data_id'], '', 'right');
form_selectable_cell($check['local_data_id'], $check['local_data_id'], '', 'right');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'center');
form_selectable_cell('-', $check['local_data_id'], '', 'right');
}
form_checkbox_cell($check['local_data_id'], $check['local_data_id']);
form_end_row();
}
} else {
print "