523 lines
17 KiB
PHP
523 lines
17 KiB
PHP
<?php
|
|
/**
|
|
* Observium
|
|
*
|
|
* This file is part of Observium.
|
|
*
|
|
* @package observium
|
|
* @subpackage web
|
|
* @copyright (C) 2006-2013 Adam Armstrong, (C) 2013-2021 Observium Limited
|
|
*
|
|
*/
|
|
|
|
/**
|
|
* Humanize status indicator.
|
|
*
|
|
* Returns a the $status array with processed information:
|
|
* sensor_state (TRUE: state sensor, FALSE: normal sensor)
|
|
* human_value, sensor_symbol, state_name, state_event, event_class
|
|
*
|
|
* @param array $status
|
|
* @return array $status
|
|
*
|
|
*/
|
|
// TESTME needs unit testing
|
|
function humanize_status(&$status)
|
|
{
|
|
global $config;
|
|
|
|
// Exit if already humanized
|
|
if ($status['humanized']) { return; }
|
|
|
|
if (isset($config['entity_events'][$status['status_event']]))
|
|
{
|
|
$status = array_merge($status, $config['entity_events'][$status['status_event']]);
|
|
} else {
|
|
$status['event_class'] = 'label label-primary';
|
|
$status['row_class'] = '';
|
|
}
|
|
if ($status['status_deleted'])
|
|
{
|
|
$status['row_class'] = 'disabled';
|
|
}
|
|
|
|
$device = &$GLOBALS['cache']['devices']['id'][$status['device_id']];
|
|
if ((isset($device['status']) && !$device['status']) ||
|
|
(isset($device['disabled']) && $device['disabled'])) {
|
|
$status['row_class'] = $status['row_class'] !== 'disabled' ? 'error' : $status['row_class'];
|
|
}
|
|
// this is pseudo class only for js selectors
|
|
$status['row_class'] .= ' entity-status';
|
|
|
|
// Set humanized entry in the array so we can tell later
|
|
$status['humanized'] = TRUE;
|
|
}
|
|
|
|
function generate_status_query($vars, $query_count = FALSE) {
|
|
|
|
if ($query_count) {
|
|
$sql = "SELECT COUNT(*) FROM `status`";
|
|
} else {
|
|
$sql = "SELECT * FROM `status`";
|
|
|
|
if ($vars['sort'] == 'hostname' || $vars['sort'] == 'device' || $vars['sort'] == 'device_id') {
|
|
$sql .= ' LEFT JOIN `devices` USING(`device_id`)';
|
|
}
|
|
}
|
|
|
|
//$sql .= " WHERE 1";
|
|
$sql .= " WHERE `status_deleted` = 0";
|
|
|
|
// Build query
|
|
foreach($vars as $var => $value) {
|
|
switch ($var) {
|
|
case "group":
|
|
case "group_id":
|
|
$values = get_group_entities($value, 'status');
|
|
$sql .= generate_query_values($values, 'status.status_id');
|
|
break;
|
|
case 'device_group_id':
|
|
case 'device_group':
|
|
$values = get_group_entities($value, 'device');
|
|
$sql .= generate_query_values($values, 'status.device_id');
|
|
break;
|
|
case "device":
|
|
case "device_id":
|
|
$sql .= generate_query_values($value, 'status.device_id');
|
|
break;
|
|
case "id":
|
|
case 'status_id':
|
|
$sql .= generate_query_values($value, 'status.status_id');
|
|
break;
|
|
case "entity_id":
|
|
$sql .= generate_query_values($value, 'measured_entity');
|
|
break;
|
|
case "entity_type":
|
|
$sql .= generate_query_values($value, 'measured_class');
|
|
break;
|
|
case 'entity_state':
|
|
case "measured_state":
|
|
$sql .= build_entity_measured_where('status', [ 'measured_state' => $value ]);
|
|
break;
|
|
case "class":
|
|
case 'entPhysicalClass':
|
|
$sql .= generate_query_values($value, 'entPhysicalClass');
|
|
break;
|
|
case "event":
|
|
case "status_event":
|
|
$sql .= generate_query_values($value, 'status_event');
|
|
break;
|
|
case "status":
|
|
case "status_name":
|
|
$sql .= generate_query_values($value, 'status_name');
|
|
break;
|
|
case "descr":
|
|
case "status_descr":
|
|
$sql .= generate_query_values($value, 'status_descr', '%LIKE%');
|
|
break;
|
|
case 'type':
|
|
case "status_type":
|
|
$sql .= generate_query_values($value, 'status_type', '%LIKE%');
|
|
break;
|
|
}
|
|
}
|
|
//$sql .= $GLOBALS['cache']['where']['devices_permitted'];
|
|
$sql .= generate_query_permitted(array('device', 'status'));
|
|
|
|
// If need count, just return sql without sorting
|
|
if ($query_count) {
|
|
return $sql;
|
|
}
|
|
|
|
switch ($vars['sort_order']) {
|
|
case 'desc':
|
|
$sort_order = 'DESC';
|
|
$sort_neg = 'ASC';
|
|
break;
|
|
case 'reset':
|
|
unset($vars['sort'], $vars['sort_order']);
|
|
// no break here
|
|
default:
|
|
$sort_order = 'ASC';
|
|
$sort_neg = 'DESC';
|
|
}
|
|
|
|
|
|
switch($vars['sort']) {
|
|
case 'device':
|
|
$sql .= ' ORDER BY `hostname` '.$sort_order;
|
|
break;
|
|
case 'descr':
|
|
$sql .= ' ORDER BY `status_descr` '.$sort_order;
|
|
break;
|
|
case 'class':
|
|
$sql .= ' ORDER BY `entPhysicalClass` '.$sort_order;
|
|
break;
|
|
case 'event':
|
|
$sql .= ' ORDER BY `status_event` '.$sort_order;
|
|
break;
|
|
case 'status':
|
|
$sql .= ' ORDER BY `status_name` '.$sort_order;
|
|
break;
|
|
case 'last_change':
|
|
$sql .= ' ORDER BY `status_last_change` '.$sort_neg;
|
|
break;
|
|
default:
|
|
$sql .= ' ORDER BY `measured_entity_label`, `status_descr` '.$sort_order;
|
|
}
|
|
|
|
return $sql;
|
|
}
|
|
|
|
|
|
function print_status_table($vars)
|
|
{
|
|
|
|
pagination($vars, 0, TRUE); // Get default pagesize/pageno
|
|
|
|
$sql = generate_status_query($vars);
|
|
|
|
$status_list = array();
|
|
foreach(dbFetchRows($sql) as $status) {
|
|
//if (isset($GLOBALS['cache']['devices']['id'][$status['device_id']]))
|
|
//{
|
|
$status['hostname'] = $GLOBALS['cache']['devices']['id'][$status['device_id']]['hostname'];
|
|
$status_list[] = $status;
|
|
//}
|
|
}
|
|
|
|
//$status_count = count($status_list); // This is count incorrect, when pagination used!
|
|
$status_count = dbFetchCell(generate_status_query($vars, TRUE));
|
|
|
|
// Pagination
|
|
$pagination_html = pagination($vars, $status_count);
|
|
echo $pagination_html;
|
|
|
|
if ($vars['pageno'])
|
|
{
|
|
$status_list = array_chunk($status_list, $vars['pagesize']);
|
|
$status_list = $status_list[$vars['pageno'] - 1];
|
|
}
|
|
// End Pagination
|
|
|
|
echo generate_box_open();
|
|
|
|
print_status_table_header($vars);
|
|
|
|
foreach($status_list as $status)
|
|
{
|
|
print_status_row($status, $vars);
|
|
}
|
|
|
|
echo("</tbody></table>");
|
|
|
|
echo generate_box_close();
|
|
|
|
echo $pagination_html;
|
|
}
|
|
|
|
function print_status_table_header($vars)
|
|
{
|
|
if ($vars['view'] == "graphs" || isset($vars['id']))
|
|
{
|
|
$stripe_class = "table-striped-two";
|
|
} else {
|
|
$stripe_class = "table-striped";
|
|
}
|
|
|
|
echo('<table class="table ' . $stripe_class . ' table-condensed ">' . PHP_EOL);
|
|
$cols = array(
|
|
array(NULL, 'class="state-marker"'),
|
|
'device' => array('Device', 'style="width: 250px;"'),
|
|
//array(NULL, 'class="no-width"'), // Measure entity link
|
|
'descr' => array('Description'),
|
|
'mib' => array('MIB::Object'),
|
|
'class' => array('Physical Class', 'style="width: 100px;"'),
|
|
array('History', 'style="width: 90px;"'),
|
|
'last_change' => array('Last changed', 'style="width: 80px;"'),
|
|
'event' => array('Event', 'style="width: 60px; text-align: right;"'),
|
|
'status' => array('Status', 'style="width: 80px; text-align: right;"'),
|
|
);
|
|
|
|
if ($vars['page'] == "device") { unset($cols['device']); }
|
|
if ($vars['page'] != "device" || $vars['tab'] == "overview") { unset($cols['mib']); unset($cols['object']); }
|
|
|
|
echo(get_table_header($cols, $vars));
|
|
echo('<tbody>' . PHP_EOL);
|
|
}
|
|
|
|
function print_status_row($status, $vars)
|
|
{
|
|
echo generate_status_row($status, $vars);
|
|
}
|
|
|
|
function generate_status_row($status, $vars) {
|
|
|
|
$table_cols = 7;
|
|
|
|
humanize_status($status);
|
|
|
|
// FIXME - make this "four graphs in popup" a function/include and "small graph" a function.
|
|
// FIXME - DUPLICATED IN device/overview/status
|
|
|
|
$graph_array = array();
|
|
$graph_array['to'] = get_time();
|
|
$graph_array['id'] = $status['status_id'];
|
|
$graph_array['type'] = "status_graph";
|
|
$graph_array['legend'] = "no";
|
|
$graph_array['width'] = 80;
|
|
$graph_array['height'] = 20;
|
|
$graph_array['bg'] = 'ffffff00';
|
|
$graph_array['from'] = get_time('day');
|
|
|
|
//$status_misc = '<span class="label">' . $status['entPhysicalClass'] . '</span>';
|
|
$short = $vars['page'] === "device" && $vars['tab'] === "overview";
|
|
$hide_style = $status['status_event'] === 'ignore' && $short ? ' style="display: none;"' : '';
|
|
|
|
$row = '<tr class="' . $status['row_class'] . '"'.$hide_style.'>
|
|
<td class="state-marker"></td>';
|
|
|
|
if ($vars['page'] !== "device" && $vars['popup'] != TRUE)
|
|
{
|
|
$row .= '<td class="entity">' . generate_device_link($status) . '</td>';
|
|
$table_cols++;
|
|
}
|
|
|
|
if ($status['status_event'] && $status['status_name'])
|
|
{
|
|
$mini_graph = generate_graph_tag($graph_array);
|
|
} else {
|
|
// Do not show "Draw Error" minigraph
|
|
$mini_graph = '';
|
|
}
|
|
|
|
// Measured link & icon
|
|
/* Disabled because it breaks the overview table layout
|
|
$row .= ' <td style="padding-right: 0px;" class="no-width vertical-align">'; // minify column if empty
|
|
if ($status['measured_entity'] &&
|
|
(!isset($vars['measured_icon']) || $vars['measured_icon'])) // hide measured icon if not required
|
|
{
|
|
$row .= generate_entity_icon_link($status['measured_class'], $status['measured_entity']);
|
|
}
|
|
$row .= '</td>';
|
|
$table_cols++;
|
|
*/
|
|
|
|
$row .= '<td class="entity">' . generate_entity_link('status', $status) . '</td>';
|
|
|
|
// FIXME -- Generify this. It's not just for sensors.
|
|
if ($vars['page'] === "device" && $vars['tab'] !== "overview")
|
|
{
|
|
$row .= ' <td>' . (!safe_empty($status['status_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$status['status_mib'].'/" target="_blank">' .nicecase($status['status_mib']) .'</a>' : '') .
|
|
( ( !safe_empty($status['status_mib']) && !safe_empty($status['status_object'])) ? '::' : '') .
|
|
(!safe_empty($status['status_mib']) ? '<a href="'.OBSERVIUM_MIBS_URL.'/'.$status['status_mib'].'/#'.$status['status_object'].'" target="_blank">' . $status['status_object'] .'</a>' : '') .
|
|
'.'.$status['status_index'].'</td>' . PHP_EOL;
|
|
$table_cols++;
|
|
}
|
|
|
|
if ($vars['tab'] !== "overview")
|
|
{
|
|
$row .= '<td><span class="label">' . $status['entPhysicalClass'] . '</span></td>';
|
|
$table_cols++;
|
|
}
|
|
$row .= '<td style="width: 90px; text-align: right;">' . generate_entity_link('status', $status, $mini_graph, NULL, FALSE) . '</td>';
|
|
if ($vars['tab'] !== "overview")
|
|
{
|
|
$row .= '<td style="white-space: nowrap">' . generate_tooltip_link('', format_uptime((get_time() - $status['status_last_change']), 'short-2') . ' ago', format_unixtime($status['status_last_change'])) . '</td>
|
|
<td style="text-align: right;"><strong>' . generate_tooltip_link('', $status['status_event'], $status['event_descr'], $status['event_class']) . '</strong></td>';
|
|
$table_cols++;
|
|
$table_cols++;
|
|
}
|
|
$row .= '<td style="width: 80px; text-align: right;"><strong>' . generate_tooltip_link('', $status['status_name'], $status['event_descr'], $status['event_class']) . '</strong></td>
|
|
</tr>' . PHP_EOL;
|
|
|
|
if ($vars['view'] === "graphs")
|
|
{
|
|
$vars['graph'] = "status";
|
|
}
|
|
|
|
if ($vars['graph'] || $vars['id'] == $status['status_id'])
|
|
{
|
|
// If id set in vars, display only specific graphs
|
|
$row .= '<tr class="' . $status['row_class'] . '">
|
|
<td class="state-marker"></td>
|
|
<td colspan="' . $table_cols . '">';
|
|
|
|
unset($graph_array['height'], $graph_array['width'], $graph_array['legend']);
|
|
$graph_array['to'] = get_time();
|
|
$graph_array['id'] = $status['status_id'];
|
|
$graph_array['type'] = "status_graph";
|
|
|
|
$row .= generate_graph_row($graph_array, TRUE);
|
|
|
|
$row .= '</td></tr>';
|
|
} # endif graphs
|
|
|
|
return $row;
|
|
|
|
}
|
|
|
|
function print_status_form($vars, $single_device = FALSE)
|
|
{
|
|
global $config;
|
|
|
|
$form = array('type' => 'rows',
|
|
'space' => '10px',
|
|
'submit_by_key' => TRUE,
|
|
'url' => generate_url($vars));
|
|
|
|
$form_items = array();
|
|
|
|
if ($single_device)
|
|
{
|
|
// Single device, just hidden field
|
|
$form['row'][0]['device_id'] = array(
|
|
'type' => 'hidden',
|
|
'name' => 'Device',
|
|
'value' => $vars['device_id'],
|
|
'grid' => 2,
|
|
'width' => '100%');
|
|
} else {
|
|
$form_items['devices'] = generate_form_values('device', dbFetchColumn('SELECT DISTINCT `device_id` FROM `status`'));
|
|
|
|
$form['row'][0]['device_id'] = array(
|
|
'type' => 'multiselect',
|
|
'name' => 'Device',
|
|
'value' => $vars['device_id'],
|
|
'grid' => 2,
|
|
'width' => '100%', //'180px',
|
|
'values' => $form_items['devices']);
|
|
}
|
|
|
|
$status_permitted = generate_query_permitted(array('device', 'status'));
|
|
foreach ([ 'entPhysicalClass' => 'Physical Class', 'status_event' => 'Status Event', 'status_name' => 'Status' ] as $param => $param_name) {
|
|
$sql = 'SELECT DISTINCT `'.$param.'` FROM `status` WHERE `status_deleted` = ?' . $status_permitted;
|
|
if ($entries = dbFetchColumn($sql, [ 0 ])) {
|
|
asort($entries);
|
|
}
|
|
foreach ($entries as $entry) {
|
|
if (safe_empty($entry)) { $entry = OBS_VAR_UNSET; }
|
|
if ($param === 'entPhysicalClass')
|
|
{
|
|
$name = nicecase($entry);
|
|
if (isset($config['icon'][strtolower($entry)]))
|
|
{
|
|
$name = ['name' => $name, 'icon' => $config['icon'][strtolower($entry)]];
|
|
} else {
|
|
$name = ['name' => $name, 'icon' => $config['icon']['status']];
|
|
}
|
|
} else {
|
|
$name = $entry;
|
|
}
|
|
$form_items[$param][$entry] = $name;
|
|
}
|
|
|
|
// Alternative param name, ie event
|
|
$short_param = str_replace('status_', '', $param);
|
|
if (!isset($vars[$param]) && isset($vars[$short_param]))
|
|
{
|
|
$vars[$param] = $vars[$short_param];
|
|
}
|
|
|
|
// Status specific forms
|
|
$form['row'][0][$param] = array(
|
|
'type' => 'multiselect',
|
|
'name' => $param_name,
|
|
'width' => '100%', //'180px',
|
|
'grid' => 2,
|
|
'value' => $vars[$param],
|
|
'values' => $form_items[$param]);
|
|
}
|
|
|
|
// Measured entities
|
|
$form['row'][0]['measured_state'] = array(
|
|
'type' => 'multiselect',
|
|
'name' => 'Measured State',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 2,
|
|
'value' => $vars['measured_state'],
|
|
'values' => ['none' => ['name' => 'Without Measure', 'icon' => $config['icon']['filter']],
|
|
'up' => ['name' => 'Measured UP', 'icon' => $config['icon']['up']],
|
|
'down' => ['name' => 'Measured DOWN', 'icon' => $config['icon']['down']],
|
|
'shutdown' => ['name' => 'Measured SHUTDOWN', 'icon' => $config['icon']['shutdown']]]);
|
|
|
|
$form['row'][1]['status_descr'] = array(
|
|
'type' => 'text',
|
|
'placeholder' => 'Status description',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 4,
|
|
'value' => $vars['status_descr']);
|
|
|
|
$form['row'][1]['status_type'] = array(
|
|
'type' => 'text',
|
|
'placeholder' => 'Status type',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 4,
|
|
'value' => $vars['status_descr']);
|
|
|
|
// Groups
|
|
foreach (get_type_groups('status') as $entry)
|
|
{
|
|
$form_items['group'][$entry['group_id']] = $entry['group_name'];
|
|
}
|
|
$form['row'][1]['group'] = array(
|
|
'community' => FALSE,
|
|
'type' => 'multiselect',
|
|
'name' => 'Select Groups',
|
|
'width' => '100%', //'180px',
|
|
'grid' => 2,
|
|
'value' => $vars['group'],
|
|
'values' => $form_items['group']);
|
|
|
|
$form['row'][1]['search'] = array(
|
|
'type' => 'submit',
|
|
'grid' => 2,
|
|
//'name' => 'Search',
|
|
//'icon' => 'icon-search',
|
|
'right' => TRUE,
|
|
);
|
|
|
|
// Show search form
|
|
echo '<div class="hidden-xl">';
|
|
print_form($form);
|
|
echo '</div>';
|
|
|
|
// Custom panel form
|
|
$panel_form = array('type' => 'rows',
|
|
'title' => 'Search Statuses',
|
|
'space' => '10px',
|
|
//'brand' => NULL,
|
|
//'class' => '',
|
|
'submit_by_key' => TRUE,
|
|
'url' => generate_url($vars));
|
|
|
|
// Clean grids
|
|
foreach ($form['row'] as $row => $rows) {
|
|
foreach (array_keys($rows) as $param) {
|
|
if (isset($form['row'][$row][$param]['grid'])) { unset($form['row'][$row][$param]['grid']); }
|
|
}
|
|
}
|
|
|
|
// Copy forms
|
|
$panel_form['row'][0]['device_id'] = $form['row'][0]['device_id'];
|
|
$panel_form['row'][0]['entPhysicalClass'] = $form['row'][0]['entPhysicalClass'];
|
|
|
|
$panel_form['row'][1]['status_event'] = $form['row'][0]['status_event'];
|
|
$panel_form['row'][1]['status_name'] = $form['row'][0]['status_name'];
|
|
|
|
$panel_form['row'][2]['measured_state'] = $form['row'][0]['measured_state'];
|
|
$panel_form['row'][2]['group'] = $form['row'][1]['group'];
|
|
|
|
$panel_form['row'][3]['status_type'] = $form['row'][1]['status_type'];
|
|
|
|
$panel_form['row'][4]['status_descr'] = $form['row'][1]['status_descr'];
|
|
|
|
//$panel_form['row'][5]['sort'] = $form['row'][0]['sort'];
|
|
$panel_form['row'][5]['search'] = $form['row'][1]['search'];
|
|
|
|
// Register custom panel
|
|
register_html_panel(generate_form($panel_form));
|
|
}
|
|
|
|
// EOF
|