WIP heatmap

This commit is contained in:
Daniel Maya 2022-02-11 14:50:57 +01:00
parent cbee39189f
commit 3c50164270
4 changed files with 601 additions and 1 deletions

View File

@ -0,0 +1,452 @@
<?php
/**
* Heatmap class.
*
* @category Heatmap
* @package Pandora FMS
* @subpackage Community
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2022 Artica Soluciones Tecnologicas
* Please see http://pandorafms.org for full contribution list
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation for version 2.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* ============================================================================
*/
class Heatmap
{
/**
* Heatmap type.
*
* @var integer
*/
protected $type = null;
/**
* Heatmap filter.
*
* @var array
*/
protected $filter = null;
/**
* Allowed methods to be called using AJAX request.
*
* @var array
*/
protected $AJAXMethods = [
'showHeatmap',
'updateHeatmap',
'getDataJson',
];
/**
* Heatmap random id.
*
* @var string
*/
protected $randomId = null;
/**
* Heatmap refresh.
*
* @var integer
*/
protected $refresh = null;
/**
* Constructor function
*
* @param integer $type Heatmap type.
* @param array $filter Heatmap filter.
* @param string $randomId Heatmap random id.
* @param integer $refresh Heatmap refresh.
*/
public function __construct(
int $type=0,
array $filter=[],
string $randomId=null,
int $refresh=300
) {
$this->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 '<div id="div_'.$this->randomId.'" class="mainDiv">';
?>
<script type="text/javascript">
$(document).ready(function() {
const randomId = '<?php echo 'div_'.$this->randomId; ?>';
const refresh = '<?php echo $this->refresh; ?>';
// Initial charge.
ajaxRequest(
randomId,
<?php echo json_encode($settings); ?>
);
// Refresh.
setInterval(
function() {
refreshMap();
},
(refresh * 10)
);
});
function refreshMap() {
$.ajax({
type: 'GET',
url: '<?php echo ui_get_full_url('ajax.php', false, false, false); ?>',
data: {
page: "operation/heatmap",
method: 'getDataJson',
randomId: '<?php echo $this->randomId; ?>',
type: '<?php echo $this->type; ?>',
refresh: '<?php echo $this->refresh; ?>'
},
dataType: 'json',
success: function(data) {
console.log(data);
}
});
};
</script>
<?php
echo '</div>';
}
/**
* 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 '<svg id="svg_'.$this->randomId.'" width=95% viewBox="'.$viewBox.'">';
$contX = 0;
$contY = 0;
// $auxdata = 0;
// $auxY = 0;
foreach ($result as $key => $value) {
echo '<rect id="'.$value['id_agente'].'"
class="'.$value['status'].' hover"
width="1" height="1" x ="'.$contX.' "y="'.$contY.'" />';
// 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 '<polygon class="group" points="'.$point.'" />';
// }
// Left.
// if ($contX === 0 || $auxY === 1) {
// $point = sprintf(
// '%d,%d %d,%d',
// $contX,
// $contY,
// $contX,
// ($contY + 1)
// );
// echo '<polygon class="group" points="'.$point.'" />';
// }
// Bottom.
// if (($contY + 1) === $Yaxis) {
// $point = sprintf(
// '%d,%d %d,%d',
// $contX,
// ($contY + 1),
// ($contX + 1),
// ($contY + 1)
// );
// echo '<polygon class="group" points="'.$point.'" />';
// }
// Right.
// if (($contX + 1) === $Xaxis) {
// hd('entra');
// $point = sprintf(
// '%d,%d %d,%d',
// ($contX + 1),
// $contY,
// ($contX + 1),
// ($contY + 1)
// );
// echo '<polygon class="group" points="'.$point.'" />';
// }
$contY++;
if ($contY === $Yaxis) {
$contX++;
$contY = 0;
$auxY = 0;
}
}
echo '</svg>';
}
}

View File

@ -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;
}

View File

@ -0,0 +1,108 @@
<?php
/**
* Tree view.
*
* @category Operation
* @package Pandora FMS
* @subpackage Community
* @version 1.0.0
* @license See below
*
* ______ ___ _______ _______ ________
* | __ \.-----.--.--.--| |.-----.----.-----. | ___| | | __|
* | __/| _ | | _ || _ | _| _ | | ___| |__ |
* |___| |___._|__|__|_____||_____|__| |___._| |___| |__|_|__|_______|
*
* ============================================================================
* Copyright (c) 2005-2022 Artica Soluciones Tecnologicas
* Please see http://pandorafms.org for full contribution list
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation for version 2.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* ============================================================================
*/
global $config;
// Login check.
check_login();
$agent_a = (bool) check_acl($config['id_user'], 0, 'AR');
$agent_w = (bool) check_acl($config['id_user'], 0, 'AW');
if ($agent_a === false && $agent_w === false) {
db_pandora_audit('ACL Violation', 'Trying to access agent main list view');
include 'general/noaccess.php';
return;
}
require_once $config['homedir'].'/include/class/Heatmap.class.php';
$is_ajax = is_ajax();
if (!$is_ajax) {
// Header.
ui_print_standard_header(
__('Heatmap view'),
'',
false,
'',
false,
[],
[
[
'link' => '',
'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();
}

View File

@ -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');