From 3c5016427006b68bf205b1fbdc55c2358cc87762 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Fri, 11 Feb 2022 14:50:57 +0100 Subject: [PATCH 1/8] WIP heatmap --- .../include/class/Heatmap.class.php | 452 ++++++++++++++++++ pandora_console/include/styles/heatmap.css | 37 ++ pandora_console/operation/heatmap.php | 108 +++++ pandora_console/operation/menu.php | 5 +- 4 files changed, 601 insertions(+), 1 deletion(-) create mode 100644 pandora_console/include/class/Heatmap.class.php create mode 100644 pandora_console/include/styles/heatmap.css create mode 100644 pandora_console/operation/heatmap.php diff --git a/pandora_console/include/class/Heatmap.class.php b/pandora_console/include/class/Heatmap.class.php new file mode 100644 index 0000000000..1706d6e700 --- /dev/null +++ b/pandora_console/include/class/Heatmap.class.php @@ -0,0 +1,452 @@ +type = $type; + $this->filter = $filter; + (empty($randomId) === true) ? $this->randomId = uniqid() : $this->randomId = $randomId; + $this->refresh = $refresh; + } + + + /** + * Show . + * + * @return void + */ + public function run() + { + ui_require_css_file('heatmap'); + + $settings = [ + 'type' => 'POST', + 'dataType' => 'html', + 'url' => ui_get_full_url( + 'ajax.php', + false, + false, + false + ), + 'data' => [ + 'page' => 'operation/heatmap', + 'method' => 'showHeatmap', + 'randomId' => $this->randomId, + 'type' => $this->type, + 'filter' => $this->filter, + 'refresh' => $this->refresh, + ], + ]; + + echo '
'; + ?> + + '; + } + + + /** + * Setter for filter + * + * @param array $filter Filter. + * + * @return void + */ + public function setFilter(array $filter) + { + $this->filter = $filter; + } + + + /** + * Setter for type + * + * @param integer $type Type. + * + * @return void + */ + public function setType(int $type) + { + $this->type = $type; + } + + + /** + * Setter for refresh + * + * @param integer $refresh Refresh. + * + * @return void + */ + public function setRefresh(int $refresh) + { + $this->refresh = $refresh; + } + + + /** + * Get all agents + * + * @return array + */ + protected function getAllAgents() + { + // All agents. + $result = agents_get_agents( + [ + 'disabled' => 0, + // 'search_custom' => $search_sql_custom, + // 'search' => $search_sql, + ], + [ + 'id_agente', + 'alias', + 'id_grupo', + 'normal_count', + 'warning_count', + 'critical_count', + 'unknown_count', + 'notinit_count', + 'total_count', + 'fired_count', + ], + 'AR', + [ + 'field' => 'id_grupo,id_agente', + 'order' => 'ASC', + ] + ); + + $agents = []; + // Agent status. + foreach ($result as $agent) { + if ($agent['total_count'] === 0 || $agent['total_count'] === $agent['notinit_count']) { + $status = 'notinit'; + } else if ($agent['critical_count'] > 0) { + $status = 'critical'; + } else if ($agent['warning_count'] > 0) { + $status = 'warning'; + } else if ($agent['unknown_count'] > 0) { + $status = 'unknown'; + } else { + $status = 'normal'; + } + + $agents[$agent['id_agente']] = $agent; + $agents[$agent['id_agente']]['status'] = $status; + } + + $status = [ + 'normal', + 'critical', + 'warning', + 'unknown', + 'normal', + ]; + + // -------------------Agent generator-------------------- + $a = 1; + $agents = []; + $total = 1000; + while ($a <= $total) { + $agents[$a]['id_agente'] = $a; + $agents[$a]['status'] = $this->statusColour(rand(4, 0)); + $agents[$a]['id_grupo'] = ceil($a / 10); + $a++; + } + + // ------------------------------------------- + return $agents; + } + + + /** + * GetDataJson + * + * @return json + */ + public function getDataJson() + { + $return = $this->getAllAgents(); + echo json_encode($return); + return; + } + + + /** + * Get colour by status + * + * @param integer $status Status. + * + * @return string + */ + protected function statusColour(int $status) + { + switch ($status) { + case AGENT_STATUS_CRITICAL: + $return = 'critical'; + break; + + case AGENT_STATUS_WARNING: + $return = 'warning'; + break; + + case AGENT_STATUS_UNKNOWN: + $return = 'unknown'; + break; + + case AGENT_STATUS_NOT_INIT: + $return = 'notinit'; + break; + + case AGENT_STATUS_NORMAL: + default: + $return = 'normal'; + break; + } + + return $return; + } + + + /** + * Get max. number of y-axis + * + * @param integer $total Total. + * + * @return integer + */ + protected function getYAxis(int $total) + { + $yAxis = ceil(sqrt(($total / 2))); + return (integer) $yAxis; + + } + + + /** + * Checks if target method is available to be called using AJAX. + * + * @param string $method Target method. + * + * @return boolean True allowed, false not. + */ + public function ajaxMethod(string $method):bool + { + return in_array($method, $this->AJAXMethods); + } + + + /** + * ShowHeatmap + * + * @return void + */ + public function showHeatmap() + { + switch ($this->type) { + case 0: + default: + $result = $this->getAllAgents(); + break; + } + + $Yaxis = $this->getYAxis(count($result)); + $Xaxis = ($Yaxis * 2); + $viewBox = sprintf( + '0 0 %d %d', + $Xaxis, + $Yaxis + ); + + echo ''; + + $contX = 0; + $contY = 0; + // $auxdata = 0; + // $auxY = 0; + foreach ($result as $key => $value) { + echo ''; + + // Top. + // if ($auxdata !== $value['id_grupo'] || $contY === 0) { + // if ($auxdata !== $value['id_grupo']) { + // $auxdata = $value['id_grupo']; + // $auxY = 1; + // } + // $point = sprintf( + // '%d,%d %d,%d', + // $contX, + // $contY, + // ($contX + 1), + // $contY + // ); + // echo ''; + // } + // Left. + // if ($contX === 0 || $auxY === 1) { + // $point = sprintf( + // '%d,%d %d,%d', + // $contX, + // $contY, + // $contX, + // ($contY + 1) + // ); + // echo ''; + // } + // Bottom. + // if (($contY + 1) === $Yaxis) { + // $point = sprintf( + // '%d,%d %d,%d', + // $contX, + // ($contY + 1), + // ($contX + 1), + // ($contY + 1) + // ); + // echo ''; + // } + // Right. + // if (($contX + 1) === $Xaxis) { + // hd('entra'); + // $point = sprintf( + // '%d,%d %d,%d', + // ($contX + 1), + // $contY, + // ($contX + 1), + // ($contY + 1) + // ); + // echo ''; + // } + $contY++; + if ($contY === $Yaxis) { + $contX++; + $contY = 0; + $auxY = 0; + } + } + + echo ''; + } + + +} diff --git a/pandora_console/include/styles/heatmap.css b/pandora_console/include/styles/heatmap.css new file mode 100644 index 0000000000..c90304885e --- /dev/null +++ b/pandora_console/include/styles/heatmap.css @@ -0,0 +1,37 @@ +.mainDiv { + width: 100%; + display: flex; + justify-content: center; +} + +.normal { + fill: #82b92e; +} + +.critical { + fill: #e63c52; +} + +.warning { + fill: #f3b200; +} + +.unknown { + fill: #b2b2b2; +} + +.notinit { + fill: #4a83f3; +} + +.hover:hover { + filter: brightness(1.5); + stroke-width: 0.009; + stroke: black; +} + +.group { + fill: none; + stroke-width: 0.03; + stroke: black; +} diff --git a/pandora_console/operation/heatmap.php b/pandora_console/operation/heatmap.php new file mode 100644 index 0000000000..591865ac40 --- /dev/null +++ b/pandora_console/operation/heatmap.php @@ -0,0 +1,108 @@ + '', + 'label' => __('Monitoring'), + ], + [ + 'link' => '', + 'label' => __('Views'), + ], + ] + ); +} + +$type = get_parameter('type', 0); +$filter = get_parameter('filter', []); +$randomId = get_parameter('randomId', null); +$refresh = get_parameter('refresh', 300); + +// Control call flow. +try { + // Heatmap construct. + $heatmap = new Heatmap($type, $filter, $randomId, $refresh); +} catch (Exception $e) { + if (is_ajax() === true) { + echo json_encode(['error' => '[Heatmap]'.$e->getMessage() ]); + exit; + } else { + echo '[Heatmap]'.$e->getMessage(); + } + + // Stop this execution, but continue 'globally'. + return; +} + +// AJAX controller. +if ($is_ajax === true) { + $method = get_parameter('method'); + + if (method_exists($heatmap, $method) === true) { + if ($heatmap->ajaxMethod($method) === true) { + $heatmap->{$method}(); + } else { + echo 'Unavailable method'; + } + } else { + echo 'Method not found'; + } + + // Stop any execution. + exit; +} else { + // Run. + $heatmap->run(); +} diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index b417e20b89..299ed19c03 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -63,9 +63,12 @@ if (check_acl($config['id_user'], 0, 'AR')) { enterprise_hook('tag_view_submenu'); - $sub2['operation/agentes/alerts_status']['text'] = __('Alert detail'); + $sub2['operation/agentes/alerts_status']['text'] = __('Alert details'); $sub2['operation/agentes/alerts_status']['refr'] = 0; + $sub2['operation/heatmap']['text'] = __('Heatmap view'); + $sub2['operation/heatmap']['refr'] = 0; + $sub['view']['sub2'] = $sub2; enterprise_hook('inventory_menu'); From 74996e3cc021465bc602eb647175298f4cb983aa Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Fri, 25 Feb 2022 09:41:32 +0100 Subject: [PATCH 2/8] WIP heatmap 2 --- pandora_console/include/ajax/heatmap.ajax.php | 277 ++++++++++++ .../include/class/Heatmap.class.php | 407 +++++++++++++----- pandora_console/include/styles/heatmap.css | 70 +++ pandora_console/operation/heatmap.php | 211 ++++++++- pandora_console/operation/menu.php | 2 +- 5 files changed, 846 insertions(+), 121 deletions(-) create mode 100644 pandora_console/include/ajax/heatmap.ajax.php diff --git a/pandora_console/include/ajax/heatmap.ajax.php b/pandora_console/include/ajax/heatmap.ajax.php new file mode 100644 index 0000000000..ddcc98decb --- /dev/null +++ b/pandora_console/include/ajax/heatmap.ajax.php @@ -0,0 +1,277 @@ +'; + echo '
'; + echo '

'.__('Refresh').'

'; + echo html_print_select( + [ + '30' => __('30 seconds'), + (string) SECONDS_1MINUTE => __('1 minute'), + '180' => __('3 minute'), + (string) SECONDS_5MINUTES => __('5 minutes'), + ], + 'refresh', + $refresh, + '', + '', + 0, + true, + false, + false, + '', + false, + 'margin-top: 3px;' + ); + echo '
'; + + echo '
'; + echo '

'.__('Search').'

'; + echo html_print_input_text('search', $search, '', 30, 255, true); + echo '
'; + + echo '
'; + echo '

'.__('Type').'

'; + echo html_print_select( + [ + 0 => __('Group agents'), + 1 => __('Group modules by tag'), + 2 => __('Group modules by module group'), + ], + 'type', + $type, + '', + '', + 0, + true, + false, + false, + '', + false, + 'margin-top: 3px;width:70%' + ); + echo '
'; + echo ''; + } + + + if ($getFilterType === true) { + $filter = get_parameter('filter', 0); + echo '
'; + switch ($type) { + case 0: + default: + echo '

'.__('Group').'

'; + echo html_print_input( + [ + 'type' => 'select_groups', + 'returnAllGroup' => true, + 'name' => 'filter[]', + 'selected' => $filter, + 'return' => true, + 'required' => true, + 'privilege' => 'AR', + ] + ); + break; + + case 1: + echo '

'.__('Tag').'

'; + if (tags_has_user_acl_tags($config['id_user']) === false) { + echo html_print_select_from_sql( + 'SELECT id_tag, name + FROM ttag + WHERE id_tag NOT IN ( + SELECT a.id_tag + FROM ttag a, ttag_module b + WHERE a.id_tag = b.id_tag) + ORDER BY name', + 'filter[]', + $filter, + '', + '', + '', + true, + true, + false, + false, + 'width: 200px', + '5' + ); + } else { + $user_tags = tags_get_user_tags($config['id_user'], 'AR'); + if (!empty($user_tags)) { + $id_user_tags = array_keys($user_tags); + + echo html_print_select_from_sql( + 'SELECT id_tag, name + FROM ttag + WHERE id_tag IN ('.implode(',', $id_user_tags).') AND + id_tag NOT IN ( + SELECT a.id_tag + FROM ttag a, ttag_module b + WHERE a.id_tag = b.id_tag) + ORDER BY name', + 'filter[]', + $filter, + '', + '', + '', + true, + true, + false, + false, + 'width: 200px', + '5' + ); + } else { + echo html_print_select_from_sql( + 'SELECT id_tag, name + FROM ttag + WHERE id_tag NOT IN ( + SELECT a.id_tag + FROM ttag a, ttag_module b + WHERE a.id_tag = b.id_tag) + ORDER BY name', + 'filter[]', + $filter, + '', + '', + '', + true, + true, + false, + false, + 'width: 200px', + '5' + ); + } + } + break; + + case 2: + $module_groups = modules_get_modulegroups(); + echo '

'.__('Module group').'

'; + echo html_print_select( + $module_groups, + 'filter[]', + $filter, + '', + _('Not assigned'), + '', + true, + false, + false, + '', + false, + 'width: 70%' + ); + break; + } + + echo '
'; + } + + if ($getInfo === true) { + $id = get_parameter('id', 0); + switch ($type) { + case 2: + break; + + case 1: + break; + + case 0: + default: + $data = agents_get_agent($id); + + // Alias. + echo '
'; + echo '

'.__('Agent').'

'; + echo ''.$data['alias'].''; + echo '
'; + + // Ip. + echo '
'; + echo '

'.__('IP').'

'; + echo '

'.$data['direccion'].'

'; + echo '
'; + + // OS. + echo '
'; + echo '

'.__('OS').'

'; + echo '

'.ui_print_os_icon($data['id_os'], true, true).'

'; + echo '
'; + + // Description. + echo '
'; + echo '

'.__('Description').'

'; + echo '

'.$data['comentarios'].'

'; + echo '
'; + + // Group. + echo '
'; + echo '

'.__('Group').'

'; + echo '

'.groups_get_name($data['id_grupo']).'

'; + echo '
'; + + // Events. + echo '
'; + echo graph_graphic_agentevents( + $id, + 100, + 40, + SECONDS_1DAY, + '', + true, + false, + false, + 1 + ); + echo '
'; + break; + } + } + + return; +} diff --git a/pandora_console/include/class/Heatmap.class.php b/pandora_console/include/class/Heatmap.class.php index 1706d6e700..990a518171 100644 --- a/pandora_console/include/class/Heatmap.class.php +++ b/pandora_console/include/class/Heatmap.class.php @@ -67,6 +67,27 @@ class Heatmap */ protected $refresh = null; + /** + * Heatmap width. + * + * @var integer + */ + protected $width = null; + + /** + * Heatmap height. + * + * @var integer + */ + protected $height = null; + + /** + * Heatmap search. + * + * @var string + */ + protected $search = null; + /** * Constructor function @@ -75,22 +96,31 @@ class Heatmap * @param array $filter Heatmap filter. * @param string $randomId Heatmap random id. * @param integer $refresh Heatmap refresh. + * @param integer $width Width. + * @param integer $height Height. + * @param string $search Heatmap search. */ public function __construct( int $type=0, array $filter=[], string $randomId=null, - int $refresh=300 + int $refresh=300, + int $width=0, + int $height=0, + string $search=null ) { $this->type = $type; $this->filter = $filter; (empty($randomId) === true) ? $this->randomId = uniqid() : $this->randomId = $randomId; $this->refresh = $refresh; + $this->width = $width; + $this->height = $height; + $this->search = $search; } /** - * Show . + * Run. * * @return void */ @@ -114,6 +144,7 @@ class Heatmap 'type' => $this->type, 'filter' => $this->filter, 'refresh' => $this->refresh, + 'search' => $this->search, ], ]; @@ -121,13 +152,16 @@ class Heatmap ?> '; @@ -202,6 +277,17 @@ class Heatmap } + /** + * Getter for randomId + * + * @return string + */ + public function getRandomId() + { + return $this->randomId; + } + + /** * Get all agents * @@ -209,15 +295,21 @@ class Heatmap */ protected function getAllAgents() { + $filter['disabled'] = 0; + + if (empty($this->search) === false) { + $filter['search'] = ' AND alias LIKE "%'.$this->search.'%"'; + } + + if (empty($this->filter) === false) { + $filter['id_grupo'] = current($this->filter); + } + // All agents. $result = agents_get_agents( + $filter, [ - 'disabled' => 0, - // 'search_custom' => $search_sql_custom, - // 'search' => $search_sql, - ], - [ - 'id_agente', + 'id_agente as id', 'alias', 'id_grupo', 'normal_count', @@ -237,7 +329,7 @@ class Heatmap $agents = []; // Agent status. - foreach ($result as $agent) { + foreach ($result as $key => $agent) { if ($agent['total_count'] === 0 || $agent['total_count'] === $agent['notinit_count']) { $status = 'notinit'; } else if ($agent['critical_count'] > 0) { @@ -250,26 +342,18 @@ class Heatmap $status = 'normal'; } - $agents[$agent['id_agente']] = $agent; - $agents[$agent['id_agente']]['status'] = $status; + $agents[$key] = $agent; + $agents[$key]['status'] = $status; } - $status = [ - 'normal', - 'critical', - 'warning', - 'unknown', - 'normal', - ]; - // -------------------Agent generator-------------------- $a = 1; $agents = []; - $total = 1000; + $total = 1010; while ($a <= $total) { - $agents[$a]['id_agente'] = $a; + $agents[$a]['id'] = $a; $agents[$a]['status'] = $this->statusColour(rand(4, 0)); - $agents[$a]['id_grupo'] = ceil($a / 10); + $agents[$a]['id_grupo'] = ceil($a / 20); $a++; } @@ -287,12 +371,12 @@ class Heatmap { $return = $this->getAllAgents(); echo json_encode($return); - return; + return ''; } /** - * Get colour by status + * Get class by status * * @param integer $status Status. * @@ -330,14 +414,15 @@ class Heatmap /** * Get max. number of y-axis * - * @param integer $total Total. + * @param integer $total Total. + * @param float $relation Aspect relation. * * @return integer */ - protected function getYAxis(int $total) + protected function getYAxis(int $total, float $relation) { - $yAxis = ceil(sqrt(($total / 2))); - return (integer) $yAxis; + $yAxis = sqrt(($total / $relation)); + return $yAxis; } @@ -369,83 +454,179 @@ class Heatmap break; } - $Yaxis = $this->getYAxis(count($result)); - $Xaxis = ($Yaxis * 2); + $scale = ($this->width / $this->height); + + $Yaxis = $this->getYAxis(count($result), $scale); + $Xaxis = (int) ceil($Yaxis * $scale); + $Yaxis = ceil($Yaxis); + $viewBox = sprintf( '0 0 %d %d', $Xaxis, $Yaxis ); - echo ''; + echo ''; + $groups = []; $contX = 0; $contY = 0; - // $auxdata = 0; - // $auxY = 0; - foreach ($result as $key => $value) { - echo ''; - // Top. - // if ($auxdata !== $value['id_grupo'] || $contY === 0) { - // if ($auxdata !== $value['id_grupo']) { - // $auxdata = $value['id_grupo']; - // $auxY = 1; - // } - // $point = sprintf( - // '%d,%d %d,%d', - // $contX, - // $contY, - // ($contX + 1), - // $contY - // ); - // echo ''; - // } - // Left. - // if ($contX === 0 || $auxY === 1) { - // $point = sprintf( - // '%d,%d %d,%d', - // $contX, - // $contY, - // $contX, - // ($contY + 1) - // ); - // echo ''; - // } - // Bottom. - // if (($contY + 1) === $Yaxis) { - // $point = sprintf( - // '%d,%d %d,%d', - // $contX, - // ($contY + 1), - // ($contX + 1), - // ($contY + 1) - // ); - // echo ''; - // } - // Right. - // if (($contX + 1) === $Xaxis) { - // hd('entra'); - // $point = sprintf( - // '%d,%d %d,%d', - // ($contX + 1), - // $contY, - // ($contX + 1), - // ($contY + 1) - // ); - // echo ''; - // } - $contY++; - if ($contY === $Yaxis) { - $contX++; - $contY = 0; - $auxY = 0; + $contX++; + if ($contX >= $Xaxis) { + $contY++; + $contX = 0; + } + + if (empty($groups[$value['id_grupo']]) === true) { + $groups[$value['id_grupo']] = 1; + } else { + $groups[$value['id_grupo']] += 1; + } + } + + ?> + + '; + echo ''; + echo ''; + foreach ($groups as $group) { + if (($x_back + $group) <= $Xaxis) { + $x_position = ($x_back + $group); + $y_position = $y_back; + + $points = sprintf( + '%d,%d %d,%d %d,%d %d,%d', + $x_position, + $y_back, + $x_back, + $y_back, + $x_back, + ($y_position + 1), + $x_position, + ($y_position + 1) + ); + + echo ''; + + $x_back = $x_position; + if ($x_position === $Xaxis) { + $points = sprintf( + '%d,%d %d,%d', + $x_position, + $y_back, + $x_position, + ($y_back + 1) + ); + + echo ''; + + $y_back ++; + $x_back = 0; + } + } else { + $round = (int) floor(($x_back + $group) / $Xaxis); + $y_position = ($round + $y_back); + + // Top of the first line. + $points = sprintf( + '%d,%d %d,%d %d,%d', + $x_back, + ($y_back + 1), + $x_back, + $y_back, + $Xaxis, + $y_back + ); + + echo ''; + + if ($round === 1) { + // One line. + $x_position = (($x_back + $group) - $Xaxis); + + // Bottom of last line. + $points = sprintf( + '%d,%d %d,%d', + 0, + ($y_position + 1), + $x_position, + ($y_position + 1) + ); + + echo ''; + } else { + // Two or more lines. + $x_position = (($x_back + $group) - ($Xaxis * $round)); + if ($x_position === 0) { + $x_position = $Xaxis; + } + + // Bottom of last line. + $points = sprintf( + '%d,%d %d,%d', + 0, + ($y_position + 1), + $x_position, + ($y_position + 1) + ); + + echo ''; + } + + if ($x_position === $Xaxis) { + $x_position = 0; + } + + $x_back = $x_position; + $y_back = $y_position; } } echo ''; + + // Dialog. + echo ''; } diff --git a/pandora_console/include/styles/heatmap.css b/pandora_console/include/styles/heatmap.css index c90304885e..f574505efd 100644 --- a/pandora_console/include/styles/heatmap.css +++ b/pandora_console/include/styles/heatmap.css @@ -2,6 +2,8 @@ width: 100%; display: flex; justify-content: center; + min-height: 750px; + height: 100%; } .normal { @@ -24,6 +26,10 @@ fill: #4a83f3; } +.hover { + cursor: pointer; +} + .hover:hover { filter: brightness(1.5); stroke-width: 0.009; @@ -35,3 +41,67 @@ stroke-width: 0.03; stroke: black; } + +body.pure { + height: 100%; +} + +div#main_pure { + height: 100%; +} + +div#heatmap-controls { + position: fixed; + top: 30px; + right: 20px; + width: 350px; + background-color: #ececec; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + padding: 5px; + border-radius: 3px; +} + +div#heatmap-controls div#menu_tab { + margin: 0px; +} + +div#heatmap-controls ul.white-box-content { + background-color: #ececec; + border: 0px; +} + +div#heatmap-controls div.heatmap-title, +div#heatmap-controls div.heatmap-refr { + margin-top: 15px; + margin-left: 3px; + margin-right: 3px; +} +div#heatmap-controls div.heatmap-refr > div { + display: inline; +} + +.refr-form { + margin-bottom: 0 !important; + padding: 0 !important; +} + +.label-dialog { + width: 30%; + font-weight: bold; +} + +.div-dialog { + display: flex; + flex-direction: row; + justify-content: left; + align-items: center; +} + +.polyline { + fill: none; + stroke: black; + stroke-width: 0.05; +} diff --git a/pandora_console/operation/heatmap.php b/pandora_console/operation/heatmap.php index 591865ac40..40c8edde30 100644 --- a/pandora_console/operation/heatmap.php +++ b/pandora_console/operation/heatmap.php @@ -42,8 +42,50 @@ if ($agent_a === false && $agent_w === false) { require_once $config['homedir'].'/include/class/Heatmap.class.php'; +$pure = (bool) get_parameter('pure', false); +$type = get_parameter('type', 0); +$randomId = get_parameter('randomId', null); +$refresh = get_parameter('refresh', 30); +$height = get_parameter('height', 0); +$width = get_parameter('width', 0); +$search = get_parameter('search', ''); +$filter = get_parameter('filter', []); + +if (is_array($filter) === false) { + $filter = explode(',', $filter); +} + + $is_ajax = is_ajax(); -if (!$is_ajax) { +if ($is_ajax === false && $pure === false) { + $viewtab['config'] = ''.html_print_image( + 'images/setup.png', + true, + [ + 'title' => __('Config'), + 'class' => 'invert_filter', + ] + ).''; + + $url = sprintf( + 'index.php?sec=view&sec2=operation/heatmap&pure=1&type=%s&refresh=%s&search=%s&filter=%s', + $type, + $refresh, + $search, + implode(',', $filter) + ); + + $viewtab['full_screen'] = ''.html_print_image( + 'images/full_screen.png', + true, + [ + 'title' => __('Full screen'), + 'class' => 'invert_filter', + ] + ).''; + + + // Header. ui_print_standard_header( __('Heatmap view'), @@ -51,7 +93,7 @@ if (!$is_ajax) { false, '', false, - [], + $viewtab, [ [ 'link' => '', @@ -65,15 +107,85 @@ if (!$is_ajax) { ); } -$type = get_parameter('type', 0); -$filter = get_parameter('filter', []); -$randomId = get_parameter('randomId', null); -$refresh = get_parameter('refresh', 300); +if ($is_ajax === false && $pure === true) { + // Floating menu - Start. + echo '
'; + + echo ''; + + echo '
'; +} // Control call flow. try { // Heatmap construct. - $heatmap = new Heatmap($type, $filter, $randomId, $refresh); + $heatmap = new Heatmap($type, $filter, $randomId, $refresh, $width, $height, $search); } catch (Exception $e) { if (is_ajax() === true) { echo json_encode(['error' => '[Heatmap]'.$e->getMessage() ]); @@ -105,4 +217,89 @@ if ($is_ajax === true) { } else { // Run. $heatmap->run(); + + // Dialog. + echo ''; } + +?> + + diff --git a/pandora_console/operation/menu.php b/pandora_console/operation/menu.php index 299ed19c03..9789942b4a 100644 --- a/pandora_console/operation/menu.php +++ b/pandora_console/operation/menu.php @@ -63,7 +63,7 @@ if (check_acl($config['id_user'], 0, 'AR')) { enterprise_hook('tag_view_submenu'); - $sub2['operation/agentes/alerts_status']['text'] = __('Alert details'); + $sub2['operation/agentes/alerts_status']['text'] = __('Alert detail'); $sub2['operation/agentes/alerts_status']['refr'] = 0; $sub2['operation/heatmap']['text'] = __('Heatmap view'); From d4439dcf51ce989c60b86f3a975b72e5be9ad9e1 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 7 Mar 2022 10:47:20 +0100 Subject: [PATCH 3/8] heatmap css --- pandora_console/include/styles/heatmap.css | 156 ++++++++++++++++++++- 1 file changed, 152 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/styles/heatmap.css b/pandora_console/include/styles/heatmap.css index f574505efd..2e9533c339 100644 --- a/pandora_console/include/styles/heatmap.css +++ b/pandora_console/include/styles/heatmap.css @@ -4,24 +4,161 @@ justify-content: center; min-height: 750px; height: 100%; + align-items: center; } -.normal { +.normal_10 { fill: #82b92e; } -.critical { +.normal_9 { + fill: #89be38; +} + +.normal_8 { + fill: #8dc13d; +} + +.normal_7 { + fill: #90c342; +} + +.normal_6 { + fill: #97c84c; +} + +.normal_5 { + fill: #9dcc55; +} + +.normal_4 { + fill: #a4d15f; +} + +.normal_3 { + fill: #aad569; +} + +.normal_2 { + fill: #b1da73; +} + +.normal_1 { + fill: #b7de7c; +} + +.normal { + fill: #c0e28d; +} + +.critical_10 { fill: #e63c52; } -.warning { +.critical_9 { + fill: #e8475c; +} + +.critical_8 { + fill: #e95266; +} + +.critical_7 { + fill: #ea586b; +} + +.critical_6 { + fill: #eb5d70; +} + +.critical_5 { + fill: #ec6879; +} + +.critical_4 { + fill: #ee7383; +} + +.critical_3 { + fill: #ef7e8c; +} + +.critical_2 { + fill: #f08996; +} + +.critical_1 { + fill: #f1939f; +} + +.critical { + fill: #f3a5af; +} + +.warning_10 { fill: #f3b200; } -.unknown { +.warning_9 { + fill: #f5b70e; +} + +.warning_8 { + fill: #f6ba15; +} + +.warning_7 { + fill: #f6bc1c; +} + +.warning_6 { + fill: #f8c12a; +} + +.warning_5 { + fill: #f9c638; +} + +.warning_4 { + fill: #fbcb46; +} + +.warning_3 { + fill: #fcd054; +} + +.warning_2 { + fill: #fed562; +} + +.warning_1 { + fill: #ffd970; +} + +.warning { + fill: #ffde85; +} + +.unknown_10, +.unknown_9, +.unknown_8, +.unknown_7 { fill: #b2b2b2; } +.unknown_6, +.unknown_5, +.unknown_4, +.unknown_3 { + fill: #c2c2c2; +} + +.unknown_2, +.unknown_1, +.unknown { + fill: #cccccc; +} + .notinit { fill: #4a83f3; } @@ -100,6 +237,17 @@ div#heatmap-controls div.heatmap-refr > div { align-items: center; } +.title-dialog { + width: 40%; + font-weight: bold; + padding-left: 20px; +} + +.info-dialog { + width: 60%; + font-weight: bold; +} + .polyline { fill: none; stroke: black; From 04f6cfc94f95b039ceadc9ed5ffa762b28616425 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 7 Mar 2022 12:50:36 +0100 Subject: [PATCH 4/8] added heatmap --- pandora_console/operation/heatmap.php | 49 ++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 4 deletions(-) diff --git a/pandora_console/operation/heatmap.php b/pandora_console/operation/heatmap.php index 40c8edde30..9f7d4cee4d 100644 --- a/pandora_console/operation/heatmap.php +++ b/pandora_console/operation/heatmap.php @@ -50,11 +50,16 @@ $height = get_parameter('height', 0); $width = get_parameter('width', 0); $search = get_parameter('search', ''); $filter = get_parameter('filter', []); - if (is_array($filter) === false) { $filter = explode(',', $filter); } +$group_sent = (bool) get_parameter('group_sent'); +if ($group_sent === true) { + $group = (int) get_parameter('group'); +} else { + $group = (int) get_parameter('group', true); +} $is_ajax = is_ajax(); if ($is_ajax === false && $pure === false) { @@ -84,11 +89,39 @@ if ($is_ajax === false && $pure === false) { ] ).''; + $header_name = __('Heatmap view'); + switch ($type) { + case 2: + if (current($filter) == 0) { + $header_name .= ' - '.__('Module group').': '.__('Not assigned'); + } else { + $header_name .= ' - '.__('Module group').': '.modules_get_modulegroup_name(current($filter)); + } + break; + case 1: + $tags_name = ''; + foreach ($filter as $key => $tag) { + $tags_name .= tags_get_name($tag).', '; + } + + $tags_name = trim($tags_name, ', '); + $header_name .= ' - '.__('Tag').': '.$tags_name; + break; + + case 0: + default: + if (current($filter) == 0) { + $header_name .= ' - '.__('Group').': '.__('All'); + } else { + $header_name .= ' - '.__('Group').': '.groups_get_name(current($filter)); + } + break; + } // Header. ui_print_standard_header( - __('Heatmap view'), + $header_name, '', false, '', @@ -170,7 +203,14 @@ if ($is_ajax === false && $pure === true) { ); echo ''; - echo html_print_image('images/normal_screen.png', true, ['title' => __('Back to normal mode'), 'class' => 'invert_filter']); + echo html_print_image( + 'images/normal_screen.png', + true, + [ + 'title' => __('Back to normal mode'), + 'class' => 'invert_filter', + ] + ); echo ''; echo ''; @@ -185,7 +225,7 @@ if ($is_ajax === false && $pure === true) { // Control call flow. try { // Heatmap construct. - $heatmap = new Heatmap($type, $filter, $randomId, $refresh, $width, $height, $search); + $heatmap = new Heatmap($type, $filter, $randomId, $refresh, $width, $height, $search, $group); } catch (Exception $e) { if (is_ajax() === true) { echo json_encode(['error' => '[Heatmap]'.$e->getMessage() ]); @@ -265,6 +305,7 @@ if ($is_ajax === true) { type: '', refresh: '', search: '', + group: '', }, dataType: 'html', success: function(data) { From 270bb433da43d5af411a83987687dc6a2c5326e4 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Mon, 7 Mar 2022 13:11:54 +0100 Subject: [PATCH 5/8] added heatmap ajax and class --- pandora_console/include/ajax/heatmap.ajax.php | 125 +++- .../include/class/Heatmap.class.php | 582 ++++++++++++++---- 2 files changed, 543 insertions(+), 164 deletions(-) diff --git a/pandora_console/include/ajax/heatmap.ajax.php b/pandora_console/include/ajax/heatmap.ajax.php index ddcc98decb..3a4a1b1022 100644 --- a/pandora_console/include/ajax/heatmap.ajax.php +++ b/pandora_console/include/ajax/heatmap.ajax.php @@ -40,6 +40,7 @@ if (is_ajax() === true) { if ($getFilters === true) { $refresh = get_parameter('refresh', 30); $search = get_parameter('search', ''); + $group = get_parameter('group', true); echo '
'; echo '
'; @@ -91,6 +92,11 @@ if (is_ajax() === true) { 'margin-top: 3px;width:70%' ); echo '
'; + + echo '
'; + echo '

'.__('Show groups').'

'; + echo html_print_checkbox('group', 1, $group, true); + echo '
'; echo '
'; } @@ -121,11 +127,8 @@ if (is_ajax() === true) { echo html_print_select_from_sql( 'SELECT id_tag, name FROM ttag - WHERE id_tag NOT IN ( - SELECT a.id_tag - FROM ttag a, ttag_module b - WHERE a.id_tag = b.id_tag) - ORDER BY name', + WHERE id_tag + ORDER BY name', 'filter[]', $filter, '', @@ -146,12 +149,8 @@ if (is_ajax() === true) { echo html_print_select_from_sql( 'SELECT id_tag, name FROM ttag - WHERE id_tag IN ('.implode(',', $id_user_tags).') AND - id_tag NOT IN ( - SELECT a.id_tag - FROM ttag a, ttag_module b - WHERE a.id_tag = b.id_tag) - ORDER BY name', + WHERE id_tag IN ('.implode(',', $id_user_tags).') + ORDER BY name', 'filter[]', $filter, '', @@ -168,11 +167,8 @@ if (is_ajax() === true) { echo html_print_select_from_sql( 'SELECT id_tag, name FROM ttag - WHERE id_tag NOT IN ( - SELECT a.id_tag - FROM ttag a, ttag_module b - WHERE a.id_tag = b.id_tag) - ORDER BY name', + WHERE id_tag + ORDER BY name', 'filter[]', $filter, '', @@ -191,6 +187,8 @@ if (is_ajax() === true) { case 2: $module_groups = modules_get_modulegroups(); + // $module_groups[0] = _('Not assigned'); + // hd(current($filter)); echo '

'.__('Module group').'

'; echo html_print_select( $module_groups, @@ -198,13 +196,18 @@ if (is_ajax() === true) { $filter, '', _('Not assigned'), - '', + 0, true, false, false, '', false, - 'width: 70%' + 'width: 70%', + false, + false, + false, + '', + true ); break; } @@ -216,9 +219,72 @@ if (is_ajax() === true) { $id = get_parameter('id', 0); switch ($type) { case 2: + $data = db_get_row('tagente_modulo', 'id_agente_modulo', $id); + // Nombre. + echo '
'; + echo '

'.__('Module name').'

'; + echo ''.$data['nombre'].''; + echo '
'; + + // Descripcion. + echo '
'; + echo '

'.__('Description').'

'; + echo '

'.$data['descripcion'].'

'; + echo '
'; + + // Agent. + echo '
'; + echo '

'.__('Agent').'

'; + echo ''.agents_get_alias($data['id_agente']).''; + echo '
'; + + // Group. + echo '
'; + echo '

'.__('Group').'

'; + echo '

'.modules_get_modulegroup_name($data['id_module_group']).'

'; + echo '
'; break; case 1: + $data = db_get_row('tagente_modulo', 'id_agente_modulo', $id); + // Nombre. + echo '
'; + echo '

'.__('Module name').'

'; + echo ''.$data['nombre'].''; + echo '
'; + + // Descripcion. + echo '
'; + echo '

'.__('Description').'

'; + echo '

'.$data['descripcion'].'

'; + echo '
'; + + // Agent. + echo '
'; + echo '

'.__('Agent').'

'; + echo ''.agents_get_alias($data['id_agente']).''; + echo '
'; + + // Group. + echo '
'; + echo '

'.__('Group').'

'; + echo '

'.modules_get_modulegroup_name($data['id_module_group']).'

'; + echo '
'; + + // Tag. + $tags = db_get_all_rows_sql('SELECT id_tag FROM ttag_module WHERE id_agente_modulo ='.$id); + $tags_name = ''; + echo '
'; + echo '

'.__('Tag').'

'; + foreach ($tags as $key => $tag) { + $tags_name .= tags_get_name($tag['id_tag']).', '; + } + + $tags_name = trim($tags_name, ', '); + echo '

'.$tags_name.'

'; + echo '
'; break; case 0: @@ -227,32 +293,33 @@ if (is_ajax() === true) { // Alias. echo '
'; - echo '

'.__('Agent').'

'; - echo ''.$data['alias'].''; + echo '

'.__('Agent').'

'; + echo ''.$data['alias'].''; echo '
'; // Ip. echo '
'; - echo '

'.__('IP').'

'; - echo '

'.$data['direccion'].'

'; + echo '

'.__('IP').'

'; + echo '

'.$data['direccion'].'

'; echo '
'; // OS. echo '
'; - echo '

'.__('OS').'

'; - echo '

'.ui_print_os_icon($data['id_os'], true, true).'

'; + echo '

'.__('OS').'

'; + echo '

'.ui_print_os_icon($data['id_os'], true, true).'

'; echo '
'; // Description. echo '
'; - echo '

'.__('Description').'

'; - echo '

'.$data['comentarios'].'

'; + echo '

'.__('Description').'

'; + echo '

'.$data['comentarios'].'

'; echo '
'; // Group. echo '
'; - echo '

'.__('Group').'

'; - echo '

'.groups_get_name($data['id_grupo']).'

'; + echo '

'.__('Group').'

'; + echo '

'.groups_get_name($data['id_grupo']).'

'; echo '
'; // Events. @@ -260,7 +327,7 @@ if (is_ajax() === true) { echo graph_graphic_agentevents( $id, 100, - 40, + 80, SECONDS_1DAY, '', true, diff --git a/pandora_console/include/class/Heatmap.class.php b/pandora_console/include/class/Heatmap.class.php index 990a518171..2f448df4a4 100644 --- a/pandora_console/include/class/Heatmap.class.php +++ b/pandora_console/include/class/Heatmap.class.php @@ -88,6 +88,13 @@ class Heatmap */ protected $search = null; + /** + * Heatmap group. + * + * @var integer + */ + protected $group = null; + /** * Constructor function @@ -99,6 +106,7 @@ class Heatmap * @param integer $width Width. * @param integer $height Height. * @param string $search Heatmap search. + * @param integer $group Heatmap group. */ public function __construct( int $type=0, @@ -107,7 +115,8 @@ class Heatmap int $refresh=300, int $width=0, int $height=0, - string $search=null + string $search=null, + int $group=1 ) { $this->type = $type; $this->filter = $filter; @@ -116,6 +125,7 @@ class Heatmap $this->width = $width; $this->height = $height; $this->search = $search; + $this->group = $group; } @@ -145,6 +155,7 @@ class Heatmap 'filter' => $this->filter, 'refresh' => $this->refresh, 'search' => $this->search, + 'group' => $this->group, ], ]; @@ -155,7 +166,7 @@ class Heatmap const randomId = 'randomId; ?>'; const refresh = 'refresh; ?>'; let setting = ; - setting['data']['height'] = $(`#div_${randomId}`).height(); + setting['data']['height'] = $(`#div_${randomId}`).height() + 10; setting['data']['width'] = $(`#div_${randomId}`).width(); // Initial charge. @@ -180,8 +191,11 @@ class Heatmap page: "operation/heatmap", method: 'getDataJson', randomId: randomId, - type: 'type; ?>', - refresh: 'refresh; ?>' + type: setting['data']['type'], + refresh: setting['data']['refresh'], + filter: setting['data']['filter'], + search: setting['data']['search'], + group: setting['data']['group'] }, dataType: 'json', success: function(data) { @@ -200,19 +214,8 @@ class Heatmap const timer = setInterval( function() { while (cont <= limit) { - if ($(`#${randomId}_${lista[cont]['id']}`).hasClass(`${lista[cont]['status']}`)) { - let test = $(`#${randomId}_${lista[cont]['id']}`).css("filter"); - if (test !== 'none') { - // console.log(test) - // console.log(test.match('/(\d+\.\d|\d)/')); - } else { - $(`#${randomId}_${lista[cont]['id']}`).css("filter", "brightness(1.1)"); - } - } else { - $(`#${randomId}_${lista[cont]['id']}`).removeClass("normal critical warning unknown"); - $(`#${randomId}_${lista[cont]['id']}`).addClass(`${lista[cont]['status']}`); - $(`#${randomId}_${lista[cont]['id']}`).css("filter", "brightness(1)"); - } + $(`#${randomId}_${lista[cont]['id']}`).removeClass(); + $(`#${randomId}_${lista[cont]['id']}`).addClass(`${lista[cont]['status']} hover`); cont++; } @@ -297,36 +300,28 @@ class Heatmap { $filter['disabled'] = 0; + $alias = ''; if (empty($this->search) === false) { - $filter['search'] = ' AND alias LIKE "%'.$this->search.'%"'; + $alias = ' AND alias LIKE "%'.$this->search.'%"'; } - if (empty($this->filter) === false) { + $id_grupo = ''; + if (empty($this->filter) === false && current($this->filter) != 0) { $filter['id_grupo'] = current($this->filter); + $id_grupo = ' AND id_grupo = '.current($this->filter); } // All agents. - $result = agents_get_agents( - $filter, - [ - 'id_agente as id', - 'alias', - 'id_grupo', - 'normal_count', - 'warning_count', - 'critical_count', - 'unknown_count', - 'notinit_count', - 'total_count', - 'fired_count', - ], - 'AR', - [ - 'field' => 'id_grupo,id_agente', - 'order' => 'ASC', - ] + $sql = sprintf( + 'SELECT DISTINCT id_agente as id,alias,id_grupo,normal_count,warning_count,critical_count, unknown_count,notinit_count,total_count,fired_count, + (SELECT last_status_change FROM tagente_estado WHERE id_agente = tagente.id_agente ORDER BY last_status_change DESC LIMIT 1) AS last_status_change + FROM tagente WHERE `disabled` = 0 %s %s ORDER BY id_grupo,id_agente ASC', + $alias, + $id_grupo ); + $result = db_get_all_rows_sql($sql); + $agents = []; // Agent status. foreach ($result as $key => $agent) { @@ -342,23 +337,259 @@ class Heatmap $status = 'normal'; } + if ($agent['last_status_change'] != 0) { + $seconds = (time() - $agent['last_status_change']); + + if ($seconds >= SECONDS_1DAY) { + $status .= '_10'; + } else if ($seconds >= 77760) { + $status .= '_9'; + } else if ($seconds >= 69120) { + $status .= '_8'; + } else if ($seconds >= 60480) { + $status .= '_7'; + } else if ($seconds >= 51840) { + $status .= '_6'; + } else if ($seconds >= 43200) { + $status .= '_5'; + } else if ($seconds >= 34560) { + $status .= '_4'; + } else if ($seconds >= 25920) { + $status .= '_3'; + } else if ($seconds >= 17280) { + $status .= '_2'; + } else if ($seconds >= 8640) { + $status .= '_1'; + } + } + $agents[$key] = $agent; $agents[$key]['status'] = $status; } - // -------------------Agent generator-------------------- - $a = 1; - $agents = []; - $total = 1010; - while ($a <= $total) { - $agents[$a]['id'] = $a; - $agents[$a]['status'] = $this->statusColour(rand(4, 0)); - $agents[$a]['id_grupo'] = ceil($a / 20); - $a++; + return $agents; + } + + + /** + * Get all modules + * + * @return array + */ + protected function getAllModulesByGroup() + { + $filter_group = ''; + if (empty($this->filter) === false && current($this->filter) != -1) { + $filter_group = 'AND am.id_module_group ='.current($this->filter); } - // ------------------------------------------- - return $agents; + $filter_name = ''; + if (empty($this->search) === false) { + $filter_name = 'AND nombre LIKE "%'.$this->search.'%"'; + } + + // All modules. + $sql = sprintf( + 'SELECT am.id_agente_modulo AS id, ae.known_status AS `status`, am.id_module_group AS id_grupo, ae.last_status_change FROM tagente_modulo am + INNER JOIN tagente_estado ae ON am.id_agente_modulo = ae.id_agente_modulo + WHERE am.disabled = 0 %s %s GROUP BY am.id_module_group, am.id_agente_modulo', + $filter_group, + $filter_name + ); + + $result = db_get_all_rows_sql($sql); + + // Module status. + foreach ($result as $key => $module) { + $status = ''; + switch ($module['status']) { + case AGENT_MODULE_STATUS_CRITICAL_BAD: + case AGENT_MODULE_STATUS_CRITICAL_ALERT: + case 1: + case 100: + $status = 'critical'; + break; + + case AGENT_MODULE_STATUS_NORMAL: + case AGENT_MODULE_STATUS_NORMAL_ALERT: + case 0: + case 300: + $status = 'normal'; + break; + + case AGENT_MODULE_STATUS_WARNING: + case AGENT_MODULE_STATUS_WARNING_ALERT: + case 2: + case 200: + $status = 'warning'; + break; + + default: + case AGENT_MODULE_STATUS_UNKNOWN: + case 3: + $status = 'unknown'; + break; + case AGENT_MODULE_STATUS_NOT_INIT: + case 5: + $status = 'notinit'; + break; + } + + if ($module['last_status_change'] != 0) { + $seconds = (time() - $module['last_status_change']); + + if ($seconds >= SECONDS_1DAY) { + $status .= '_10'; + } else if ($seconds >= 77760) { + $status .= '_9'; + } else if ($seconds >= 69120) { + $status .= '_8'; + } else if ($seconds >= 60480) { + $status .= '_7'; + } else if ($seconds >= 51840) { + $status .= '_6'; + } else if ($seconds >= 43200) { + $status .= '_5'; + } else if ($seconds >= 34560) { + $status .= '_4'; + } else if ($seconds >= 25920) { + $status .= '_3'; + } else if ($seconds >= 17280) { + $status .= '_2'; + } else if ($seconds >= 8640) { + $status .= '_1'; + } + } + + $result[$key]['status'] = $status; + } + + return $result; + } + + + /** + * Get all modules + * + * @return array + */ + protected function getAllModulesByTag() + { + $filter_tag = ''; + if (empty($this->filter) === false && $this->filter[0] !== '0') { + foreach ($this->filter as $key => $value) { + $filter_tag .= ' AND tm.id_tag ='.$value; + } + } + + $filter_name = ''; + if (empty($this->search) === false) { + $filter_name = 'AND nombre LIKE "%'.$this->search.'%"'; + } + + // All modules. + $sql = sprintf( + 'SELECT ae.id_agente_modulo AS id, ae.known_status AS `status`, tm.id_tag AS id_grupo, ae.last_status_change FROM tagente_estado ae + INNER JOIN ttag_module tm ON tm.id_agente_modulo = ae.id_agente_modulo + WHERE 1=1 %s %s GROUP BY tm.id_tag, ae.id_agente_modulo', + $filter_tag, + $filter_name + ); + + $result = db_get_all_rows_sql($sql); + + // Module status. + foreach ($result as $key => $module) { + $status = ''; + switch ($module['status']) { + case AGENT_MODULE_STATUS_CRITICAL_BAD: + case AGENT_MODULE_STATUS_CRITICAL_ALERT: + case 1: + case 100: + $status = 'critical'; + break; + + case AGENT_MODULE_STATUS_NORMAL: + case AGENT_MODULE_STATUS_NORMAL_ALERT: + case 0: + case 300: + $status = 'normal'; + break; + + case AGENT_MODULE_STATUS_WARNING: + case AGENT_MODULE_STATUS_WARNING_ALERT: + case 2: + case 200: + $status = 'warning'; + break; + + default: + case AGENT_MODULE_STATUS_UNKNOWN: + case 3: + $status = 'unknown'; + break; + case AGENT_MODULE_STATUS_NOT_INIT: + case 5: + $status = 'notinit'; + break; + } + + if ($module['last_status_change'] != 0) { + $seconds = (time() - $module['last_status_change']); + + if ($seconds >= SECONDS_1DAY) { + $status .= '_10'; + } else if ($seconds >= 77760) { + $status .= '_9'; + } else if ($seconds >= 69120) { + $status .= '_8'; + } else if ($seconds >= 60480) { + $status .= '_7'; + } else if ($seconds >= 51840) { + $status .= '_6'; + } else if ($seconds >= 43200) { + $status .= '_5'; + } else if ($seconds >= 34560) { + $status .= '_4'; + } else if ($seconds >= 25920) { + $status .= '_3'; + } else if ($seconds >= 17280) { + $status .= '_2'; + } else if ($seconds >= 8640) { + $status .= '_1'; + } + } + + $result[$key]['status'] = $status; + } + + return $result; + } + + + /** + * GetData + * + * @return array + */ + public function getData() + { + switch ($this->type) { + case 2: + $data = $this->getAllModulesByGroup(); + break; + + case 1: + $data = $this->getAllModulesByTag(); + break; + + case 0: + default: + $data = $this->getAllAgents(); + break; + } + + return $data; } @@ -369,7 +600,7 @@ class Heatmap */ public function getDataJson() { - $return = $this->getAllAgents(); + $return = $this->getData(); echo json_encode($return); return ''; } @@ -447,12 +678,7 @@ class Heatmap */ public function showHeatmap() { - switch ($this->type) { - case 0: - default: - $result = $this->getAllAgents(); - break; - } + $result = $this->getData(); $scale = ($this->width / $this->height); @@ -466,7 +692,7 @@ class Heatmap $Yaxis ); - echo ''; $groups = []; @@ -525,101 +751,187 @@ class Heatmap }); '; - echo ''; - echo ''; - foreach ($groups as $group) { - if (($x_back + $group) <= $Xaxis) { - $x_position = ($x_back + $group); - $y_position = $y_back; + if (count($groups) > 1 && $this->group === 1) { + $x_back = 0; + $y_back = 0; - $points = sprintf( - '%d,%d %d,%d %d,%d %d,%d', - $x_position, - $y_back, - $x_back, - $y_back, - $x_back, - ($y_position + 1), - $x_position, - ($y_position + 1) - ); + echo ''; + foreach ($groups as $key => $group) { + $name = ''; + switch ($this->type) { + case 2: + $name = modules_get_modulegroup_name($key); + break; - echo ''; + case 1: + $name = tags_get_name($key); + break; - $x_back = $x_position; - if ($x_position === $Xaxis) { - $points = sprintf( - '%d,%d %d,%d', - $x_position, - $y_back, - $x_position, - ($y_back + 1) - ); - - echo ''; - - $y_back ++; - $x_back = 0; + case 0: + default: + $name = groups_get_name($key); + break; } - } else { - $round = (int) floor(($x_back + $group) / $Xaxis); - $y_position = ($round + $y_back); - // Top of the first line. - $points = sprintf( - '%d,%d %d,%d %d,%d', - $x_back, - ($y_back + 1), - $x_back, - $y_back, - $Xaxis, - $y_back - ); + if (($x_back + $group) <= $Xaxis) { + $x_position = ($x_back + $group); + $y_position = $y_back; - echo ''; + if ($y_back === 0 && $x_back === 0) { + $points = sprintf( + '%d,%d %d,%d', + $x_back, + $y_back, + $x_back, + ($y_back + 1) + ); - if ($round === 1) { - // One line. - $x_position = (($x_back + $group) - $Xaxis); - - // Bottom of last line. - $points = sprintf( - '%d,%d %d,%d', - 0, - ($y_position + 1), - $x_position, - ($y_position + 1) - ); - - echo ''; - } else { - // Two or more lines. - $x_position = (($x_back + $group) - ($Xaxis * $round)); - if ($x_position === 0) { - $x_position = $Xaxis; + echo ''; } - // Bottom of last line. $points = sprintf( - '%d,%d %d,%d', - 0, + '%d,%d %d,%d %d,%d', + $x_back, ($y_position + 1), $x_position, - ($y_position + 1) + ($y_position + 1), + $x_position, + $y_back ); echo ''; - } - if ($x_position === $Xaxis) { - $x_position = 0; - } + // Name. + echo ''.$name.''; - $x_back = $x_position; - $y_back = $y_position; + $x_back = $x_position; + if ($x_position === $Xaxis) { + $points = sprintf( + '%d,%d %d,%d', + $x_position, + $y_back, + $x_position, + ($y_back + 1) + ); + + echo ''; + + $y_back++; + $x_back = 0; + } + } else { + $round = (int) floor(($x_back + $group) / $Xaxis); + $y_position = ($round + $y_back); + + if ($round === 1) { + // One line. + $x_position = (($x_back + $group) - $Xaxis); + + if ($x_position <= $x_back) { + // Bottom line. + $points = sprintf( + '%d,%d %d,%d', + $x_back, + $y_position, + $Xaxis, + ($y_position) + ); + + echo ''; + } + + // Bottom of last line. + $points = sprintf( + '%d,%d %d,%d', + 0, + ($y_position + 1), + $x_position, + ($y_position + 1) + ); + + echo ''; + + // Name. + echo ''.$name.''; + + // Bottom-right of last line. + $points = sprintf( + '%d,%d %d,%d', + $x_position, + ($y_position), + $x_position, + ($y_position + 1) + ); + + echo ''; + + if ($x_position > $x_back) { + // Bottom-top of last line. + $points = sprintf( + '%d,%d %d,%d', + $x_position, + ($y_position), + $Xaxis, + ($y_position) + ); + + echo ''; + } + } else { + // Two or more lines. + $x_position = (($x_back + $group) - ($Xaxis * $round)); + + if ($x_position === 0) { + $x_position = $Xaxis; + } + + // Bottom of last line. + $points = sprintf( + '%d,%d %d,%d', + 0, + ($y_position + 1), + $x_position, + ($y_position + 1) + ); + + echo ''; + + // Bottom-right of last line. + $points = sprintf( + '%d,%d %d,%d', + $x_position, + ($y_position), + $x_position, + ($y_position + 1) + ); + + echo ''; + + // Name. + echo ''.$name.''; + + // Bottom-top of last line. + $points = sprintf( + '%d,%d %d,%d', + $x_position, + ($y_position), + $Xaxis, + ($y_position) + ); + + echo ''; + } + + if ($x_position === $Xaxis) { + $x_position = 0; + } + + $x_back = $x_position; + $y_back = $y_position; + } } } From cab85cbfbd470bfd60c164aebfcd87efc052af98 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Wed, 30 Mar 2022 10:21:30 +0200 Subject: [PATCH 6/8] #8458 Fixed errors --- pandora_console/include/ajax/heatmap.ajax.php | 80 ++++++++++++------- .../include/class/Heatmap.class.php | 71 ++++++++++------ pandora_console/include/styles/heatmap.css | 16 ++++ pandora_console/operation/heatmap.php | 4 +- 4 files changed, 115 insertions(+), 56 deletions(-) diff --git a/pandora_console/include/ajax/heatmap.ajax.php b/pandora_console/include/ajax/heatmap.ajax.php index 3a4a1b1022..f2f6c81280 100644 --- a/pandora_console/include/ajax/heatmap.ajax.php +++ b/pandora_console/include/ajax/heatmap.ajax.php @@ -38,7 +38,7 @@ if (is_ajax() === true) { $type = get_parameter('type', 0); if ($getFilters === true) { - $refresh = get_parameter('refresh', 30); + $refresh = get_parameter('refresh', 180); $search = get_parameter('search', ''); $group = get_parameter('group', true); @@ -117,6 +117,7 @@ if (is_ajax() === true) { 'return' => true, 'required' => true, 'privilege' => 'AR', + 'multiple' => true, ] ); break; @@ -186,28 +187,20 @@ if (is_ajax() === true) { break; case 2: - $module_groups = modules_get_modulegroups(); - // $module_groups[0] = _('Not assigned'); - // hd(current($filter)); echo '

'.__('Module group').'

'; - echo html_print_select( - $module_groups, + echo html_print_select_from_sql( + 'SELECT id_mg, name FROM tmodule_group ORDER BY name', 'filter[]', $filter, '', - _('Not assigned'), - 0, + __('Not assigned'), + '0', + true, + true, true, false, - false, - '', - false, - 'width: 70%', - false, - false, - false, - '', - true + 'width: 200px', + '5' ); break; } @@ -216,20 +209,28 @@ if (is_ajax() === true) { } if ($getInfo === true) { + enterprise_include_once('include/functions_agents.php'); $id = get_parameter('id', 0); switch ($type) { case 2: $data = db_get_row('tagente_modulo', 'id_agente_modulo', $id); + // Nombre. + $link = sprintf( + 'index.php?sec=view&sec2=operation/agentes/status_monitor%s&ag_modulename=%s', + '&refr=0&ag_group=0&module_option=1&status=-1', + $data['nombre'] + ); echo '
'; echo '

'.__('Module name').'

'; - echo ''.$data['nombre'].''; + echo ''.$data['nombre'].''; echo '
'; // Descripcion. + $description = (empty($data['descripcion']) === true) ? '-' : $data['descripcion']; echo '
'; echo '

'.__('Description').'

'; - echo '

'.$data['descripcion'].'

'; + echo '

'.$description.'

'; echo '
'; // Agent. @@ -240,24 +241,35 @@ if (is_ajax() === true) { echo '
'; // Group. + $group = (empty($data['id_module_group']) === true) + ? '-' + : modules_get_modulegroup_name($data['id_module_group']); + echo '
'; - echo '

'.__('Group').'

'; - echo '

'.modules_get_modulegroup_name($data['id_module_group']).'

'; + echo '

'.__('Module group').'

'; + echo '

'.$group.'

'; echo '
'; break; case 1: $data = db_get_row('tagente_modulo', 'id_agente_modulo', $id); + // Nombre. + $link = sprintf( + 'index.php?sec=view&sec2=operation/agentes/status_monitor%s&ag_modulename=%s', + '&refr=0&ag_group=0&module_option=1&status=-1', + $data['nombre'] + ); echo '
'; echo '

'.__('Module name').'

'; - echo ''.$data['nombre'].''; + echo ''.$data['nombre'].''; echo '
'; // Descripcion. + $description = (empty($data['descripcion']) === true) ? '-' : $data['descripcion']; echo '
'; - echo '

'.__('Description').'

'; - echo '

'.$data['descripcion'].'

'; + echo '

'.__('Description').'

'; + echo '

'.$description.'

'; echo '
'; // Agent. @@ -268,9 +280,13 @@ if (is_ajax() === true) { echo ''; // Group. + $group = (empty($data['id_module_group']) === true) + ? '-' + : modules_get_modulegroup_name($data['id_module_group']); + echo '
'; - echo '

'.__('Group').'

'; - echo '

'.modules_get_modulegroup_name($data['id_module_group']).'

'; + echo '

'.__('Module group').'

'; + echo '

'.$group.'

'; echo '
'; // Tag. @@ -317,17 +333,25 @@ if (is_ajax() === true) { echo ''; // Group. + $secondary_groups = ''; + $secondary = agents_get_secondary_groups($data['id_agente']); + if (isset($secondary['for_select']) === true && empty($secondary['for_select']) === false) { + $secondary_groups = implode(', ', $secondary['for_select']); + $secondary_groups = ', '.$secondary_groups; + } + echo '
'; echo '

'.__('Group').'

'; - echo '

'.groups_get_name($data['id_grupo']).'

'; + echo '

'.groups_get_name($data['id_grupo']).$secondary_groups.'

'; echo '
'; + // Events. echo '
'; echo graph_graphic_agentevents( $id, 100, - 80, + 40, SECONDS_1DAY, '', true, diff --git a/pandora_console/include/class/Heatmap.class.php b/pandora_console/include/class/Heatmap.class.php index 2f448df4a4..3f70d29a27 100644 --- a/pandora_console/include/class/Heatmap.class.php +++ b/pandora_console/include/class/Heatmap.class.php @@ -112,7 +112,7 @@ class Heatmap int $type=0, array $filter=[], string $randomId=null, - int $refresh=300, + int $refresh=180, int $width=0, int $height=0, string $search=null, @@ -230,6 +230,8 @@ class Heatmap }, (refresh * 1000) ); + } else { + location.reload(); } } }); @@ -307,8 +309,7 @@ class Heatmap $id_grupo = ''; if (empty($this->filter) === false && current($this->filter) != 0) { - $filter['id_grupo'] = current($this->filter); - $id_grupo = ' AND id_grupo = '.current($this->filter); + $id_grupo = ' AND id_grupo IN ('.implode(',', $this->filter).')'; } // All agents. @@ -380,7 +381,7 @@ class Heatmap { $filter_group = ''; if (empty($this->filter) === false && current($this->filter) != -1) { - $filter_group = 'AND am.id_module_group ='.current($this->filter); + $filter_group = 'AND am.id_module_group IN ('.implode(',', $this->filter).')'; } $filter_name = ''; @@ -477,9 +478,8 @@ class Heatmap { $filter_tag = ''; if (empty($this->filter) === false && $this->filter[0] !== '0') { - foreach ($this->filter as $key => $value) { - $filter_tag .= ' AND tm.id_tag ='.$value; - } + $tags = implode(',', $this->filter); + $filter_tag .= ' AND tm.id_tag IN ('.$tags.')'; } $filter_name = ''; @@ -680,11 +680,22 @@ class Heatmap { $result = $this->getData(); - $scale = ($this->width / $this->height); + if (empty($result) === true) { + echo '
'.__('No data found').'
'; + return; + } - $Yaxis = $this->getYAxis(count($result), $scale); - $Xaxis = (int) ceil($Yaxis * $scale); - $Yaxis = ceil($Yaxis); + $count_result = count($result); + + $scale = ($this->width / $this->height); + $Yaxis = $this->getYAxis($count_result, $scale); + if ($count_result <= 3) { + $Xaxis = $count_result; + $Yaxis = 1; + } else { + $Xaxis = (int) ceil($Yaxis * $scale); + $Yaxis = ceil($Yaxis); + } $viewBox = sprintf( '0 0 %d %d', @@ -728,7 +739,7 @@ class Heatmap modal: true, closeOnEscape: true, height: 400, - width: 430, + width: 530, title: '', open: function() { $.ajax({ @@ -755,7 +766,15 @@ class Heatmap $x_back = 0; $y_back = 0; - echo ''; + if ($count_result <= 100) { + $fontSize = 'small-size'; + $stroke = 'small-stroke'; + } else { + $fontSize = 'big-size'; + $stroke = 'big-stroke'; + } + + echo ''; foreach ($groups as $key => $group) { $name = ''; switch ($this->type) { @@ -786,7 +805,7 @@ class Heatmap ($y_back + 1) ); - echo ''; + echo ''; } $points = sprintf( @@ -799,11 +818,11 @@ class Heatmap $y_back ); - echo ''; + echo ''; // Name. echo ''.$name.''; + class="'.$fontSize.'">'.$name.''; $x_back = $x_position; if ($x_position === $Xaxis) { @@ -815,7 +834,7 @@ class Heatmap ($y_back + 1) ); - echo ''; + echo ''; $y_back++; $x_back = 0; @@ -838,7 +857,7 @@ class Heatmap ($y_position) ); - echo ''; + echo ''; } // Bottom of last line. @@ -850,11 +869,11 @@ class Heatmap ($y_position + 1) ); - echo ''; + echo ''; // Name. echo ''.$name.''; + class="'.$fontSize.'">'.$name.''; // Bottom-right of last line. $points = sprintf( @@ -865,7 +884,7 @@ class Heatmap ($y_position + 1) ); - echo ''; + echo ''; if ($x_position > $x_back) { // Bottom-top of last line. @@ -877,7 +896,7 @@ class Heatmap ($y_position) ); - echo ''; + echo ''; } } else { // Two or more lines. @@ -896,7 +915,7 @@ class Heatmap ($y_position + 1) ); - echo ''; + echo ''; // Bottom-right of last line. $points = sprintf( @@ -907,11 +926,11 @@ class Heatmap ($y_position + 1) ); - echo ''; + echo ''; // Name. echo ''.$name.''; + class="'.$fontSize.'">'.$name.''; // Bottom-top of last line. $points = sprintf( @@ -922,7 +941,7 @@ class Heatmap ($y_position) ); - echo ''; + echo ''; } if ($x_position === $Xaxis) { diff --git a/pandora_console/include/styles/heatmap.css b/pandora_console/include/styles/heatmap.css index 2e9533c339..bac09b561e 100644 --- a/pandora_console/include/styles/heatmap.css +++ b/pandora_console/include/styles/heatmap.css @@ -253,3 +253,19 @@ div#heatmap-controls div.heatmap-refr > div { stroke: black; stroke-width: 0.05; } + +.small-stroke { + stroke-width: 0.03; +} + +.big-stroke { + stroke-width: 0.05; +} + +.small-size { + font-size: 0.2px; +} + +.big-size { + font-size: 0.4px; +} diff --git a/pandora_console/operation/heatmap.php b/pandora_console/operation/heatmap.php index 9f7d4cee4d..59f97048a9 100644 --- a/pandora_console/operation/heatmap.php +++ b/pandora_console/operation/heatmap.php @@ -45,7 +45,7 @@ require_once $config['homedir'].'/include/class/Heatmap.class.php'; $pure = (bool) get_parameter('pure', false); $type = get_parameter('type', 0); $randomId = get_parameter('randomId', null); -$refresh = get_parameter('refresh', 30); +$refresh = get_parameter('refresh', 180); $height = get_parameter('height', 0); $width = get_parameter('width', 0); $search = get_parameter('search', ''); @@ -274,7 +274,7 @@ if ($is_ajax === true) { draggable: false, modal: true, closeOnEscape: true, - height: 370, + height: 410, width: 330, title: '', position: { From e796dc52bb9b17fbe98d19305c96ede083dfe4e5 Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 31 Mar 2022 09:46:30 +0200 Subject: [PATCH 7/8] #8458 Change in refresh value --- pandora_console/include/ajax/heatmap.ajax.php | 4 ++-- pandora_console/include/class/Heatmap.class.php | 2 +- pandora_console/operation/heatmap.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pandora_console/include/ajax/heatmap.ajax.php b/pandora_console/include/ajax/heatmap.ajax.php index f2f6c81280..6d06c0e2ce 100644 --- a/pandora_console/include/ajax/heatmap.ajax.php +++ b/pandora_console/include/ajax/heatmap.ajax.php @@ -38,7 +38,7 @@ if (is_ajax() === true) { $type = get_parameter('type', 0); if ($getFilters === true) { - $refresh = get_parameter('refresh', 180); + $refresh = get_parameter('refresh', SECONDS_5MINUTES); $search = get_parameter('search', ''); $group = get_parameter('group', true); @@ -49,7 +49,7 @@ if (is_ajax() === true) { [ '30' => __('30 seconds'), (string) SECONDS_1MINUTE => __('1 minute'), - '180' => __('3 minute'), + '180' => __('3 minutes'), (string) SECONDS_5MINUTES => __('5 minutes'), ], 'refresh', diff --git a/pandora_console/include/class/Heatmap.class.php b/pandora_console/include/class/Heatmap.class.php index 3f70d29a27..916b4b9873 100644 --- a/pandora_console/include/class/Heatmap.class.php +++ b/pandora_console/include/class/Heatmap.class.php @@ -112,7 +112,7 @@ class Heatmap int $type=0, array $filter=[], string $randomId=null, - int $refresh=180, + int $refresh=300, int $width=0, int $height=0, string $search=null, diff --git a/pandora_console/operation/heatmap.php b/pandora_console/operation/heatmap.php index 59f97048a9..a0664587e3 100644 --- a/pandora_console/operation/heatmap.php +++ b/pandora_console/operation/heatmap.php @@ -45,7 +45,7 @@ require_once $config['homedir'].'/include/class/Heatmap.class.php'; $pure = (bool) get_parameter('pure', false); $type = get_parameter('type', 0); $randomId = get_parameter('randomId', null); -$refresh = get_parameter('refresh', 180); +$refresh = get_parameter('refresh', SECONDS_5MINUTES); $height = get_parameter('height', 0); $width = get_parameter('width', 0); $search = get_parameter('search', ''); From fc9760676e37a7449651c59c73a9a94c52c841bf Mon Sep 17 00:00:00 2001 From: Daniel Maya Date: Thu, 31 Mar 2022 09:47:36 +0200 Subject: [PATCH 8/8] #8458 Change in refresh value 2 --- pandora_console/operation/heatmap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandora_console/operation/heatmap.php b/pandora_console/operation/heatmap.php index a0664587e3..3ed2b8e7ce 100644 --- a/pandora_console/operation/heatmap.php +++ b/pandora_console/operation/heatmap.php @@ -170,7 +170,7 @@ if ($is_ajax === false && $pure === true) { [ '30' => __('30 seconds'), (string) SECONDS_1MINUTE => __('1 minute'), - '180' => __('3 minute'), + '180' => __('3 minutes'), (string) SECONDS_5MINUTES => __('5 minutes'), ], 'refresh-control',