From 7c201d28554ba02b96e4e181689aee8c4e7c1785 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Thu, 21 Sep 2023 17:58:18 +0200 Subject: [PATCH 01/22] #10194 new structure for general tactical view --- pandora_console/general/logon_ok.php | 6 + pandora_console/images/status_check@svg.svg | 26 ++ pandora_console/images/status_error@svg.svg | 26 ++ pandora_console/include/graphs/fgraph.php | 20 +- .../include/lib/TacticalView/Element.php | 56 +++++ .../lib/TacticalView/GeneralTacticalView.php | 115 +++++++++ .../elements/MonitoringElements.php | 41 +++ .../lib/TacticalView/elements/NewsBoard.php | 123 +++++++++ .../lib/TacticalView/elements/Overview.php | 233 ++++++++++++++++++ .../include/styles/general_tactical_view.css | 77 ++++++ pandora_console/include/styles/news.css | 8 +- pandora_console/views/tacticalView/view.php | 102 ++++++++ 12 files changed, 826 insertions(+), 7 deletions(-) create mode 100644 pandora_console/images/status_check@svg.svg create mode 100644 pandora_console/images/status_error@svg.svg create mode 100644 pandora_console/include/lib/TacticalView/Element.php create mode 100644 pandora_console/include/lib/TacticalView/GeneralTacticalView.php create mode 100644 pandora_console/include/lib/TacticalView/elements/MonitoringElements.php create mode 100644 pandora_console/include/lib/TacticalView/elements/NewsBoard.php create mode 100644 pandora_console/include/lib/TacticalView/elements/Overview.php create mode 100644 pandora_console/include/styles/general_tactical_view.css create mode 100644 pandora_console/views/tacticalView/view.php diff --git a/pandora_console/general/logon_ok.php b/pandora_console/general/logon_ok.php index 6567347999..059443eff6 100644 --- a/pandora_console/general/logon_ok.php +++ b/pandora_console/general/logon_ok.php @@ -26,6 +26,12 @@ * ============================================================================ */ +use PandoraFMS\TacticalView\GeneralTacticalView; + +$tacticalView = new GeneralTacticalView(); +$tacticalView->render(); +return; +// Temporal return for develop. // Config functions. require_once 'include/config.php'; diff --git a/pandora_console/images/status_check@svg.svg b/pandora_console/images/status_check@svg.svg new file mode 100644 index 0000000000..78e62ea848 --- /dev/null +++ b/pandora_console/images/status_check@svg.svg @@ -0,0 +1,26 @@ + + + AE320C3A-79E4-4E24-956A-B81125ACFA52@svg + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pandora_console/images/status_error@svg.svg b/pandora_console/images/status_error@svg.svg new file mode 100644 index 0000000000..e6502bff7e --- /dev/null +++ b/pandora_console/images/status_error@svg.svg @@ -0,0 +1,26 @@ + + + CD9D3D2F-E199-427F-BC6C-532C8382EE45@svg + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pandora_console/include/graphs/fgraph.php b/pandora_console/include/graphs/fgraph.php index 494ec9c010..f0980836b6 100644 --- a/pandora_console/include/graphs/fgraph.php +++ b/pandora_console/include/graphs/fgraph.php @@ -1019,7 +1019,9 @@ function get_build_setup_charts($type, $options, $data) ) { $scales = $chart->options()->getScales(); - if ($options['scales']['x'] !== false) { + if (isset($options['scales']['x']) === true + && $options['scales']['x'] !== false + ) { // Defaults scalesFont X. $scalesXFonts = $scales->getX()->ticks()->getFonts(); $scalesXFonts->setFamily((empty($config['fontpath']) === true) ? 'lato' : $config['fontpath']); @@ -1028,7 +1030,9 @@ function get_build_setup_charts($type, $options, $data) $scalesXFonts->setSize(((int) $config['font_size'] + 2)); } - if ($options['scales']['y'] !== false) { + if (isset($options['scales']['y']) === true + && $options['scales']['y'] !== false + ) { // Defaults scalesFont Y. $scalesYFonts = $scales->getY()->ticks()->getFonts(); $scalesYFonts->setFamily((empty($config['fontpath']) === true) ? 'lato' : $config['fontpath']); @@ -1037,7 +1041,9 @@ function get_build_setup_charts($type, $options, $data) $scalesYFonts->setSize(((int) $config['font_size'] + 2)); } - if ($options['scales']['r'] !== false) { + if (isset($options['scales']['r']) === true + && $options['scales']['r'] !== false + ) { // Defaults scalesFont R. $scalesRFonts = $scales->getR()->pointLabels()->getFonts(); $scalesRFonts->setStyle('normal'); @@ -1053,6 +1059,10 @@ function get_build_setup_charts($type, $options, $data) $scales->getX()->setBounds($options['scales']['x']['bounds']); } + if (isset($options['scales']['x']['display']) === true) { + $scales->getX()->setDisplay($options['scales']['x']['display']); + } + if (isset($options['scales']['x']['grid']) === true && empty($options['scales']['x']['grid']) === false && is_array($options['scales']['x']['grid']) === true @@ -1098,6 +1108,10 @@ function get_build_setup_charts($type, $options, $data) $scales->getY()->setBounds($options['scales']['y']['bounds']); } + if (isset($options['scales']['y']['display']) === true) { + $scales->getY()->setDisplay($options['scales']['y']['display']); + } + if (isset($options['scales']['y']['grid']) === true && empty($options['scales']['y']['grid']) === false && is_array($options['scales']['y']['grid']) === true diff --git a/pandora_console/include/lib/TacticalView/Element.php b/pandora_console/include/lib/TacticalView/Element.php new file mode 100644 index 0000000000..a97502e0e1 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/Element.php @@ -0,0 +1,56 @@ +interval = 0; + $this->title = __('Default element'); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php new file mode 100644 index 0000000000..82b042cf7c --- /dev/null +++ b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php @@ -0,0 +1,115 @@ +elements = $this->instanceElements(); + } + + + /** + * Instantiate all the elements that will build the dashboard + * + * @return array + */ + public function instanceElements():array + { + global $config; + $dir = $config['homedir'].'/include/lib/TacticalView/elements/'; + + $handle = opendir($dir); + if ($handle === false) { + return []; + } + + $ignores = [ + '.', + '..', + ]; + + $elements = []; + while (false !== ($file = readdir($handle))) { + try { + if (in_array($file, $ignores) === true) { + continue; + } + + $filepath = realpath($dir.'/'.$file); + if (is_readable($filepath) === false + || is_dir($filepath) === true + || preg_match('/.*\.php$/', $filepath) === false + ) { + continue; + } + + $className = preg_replace('/.php/', '', $file); + include_once $filepath; + if (class_exists($className) === true) { + $instance = new $className(); + $elements[$className] = $instance; + } + } catch (Exception $e) { + } + } + + return $elements; + } + + + /** + * Render funcion for print the html. + * + * @return void + */ + public function render():void + { + View::render( + 'tacticalView/view', + $this->elements + ); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php new file mode 100644 index 0000000000..4731d54b27 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php @@ -0,0 +1,41 @@ +title = __('Monitoring elements'); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/NewsBoard.php b/pandora_console/include/lib/TacticalView/elements/NewsBoard.php new file mode 100644 index 0000000000..4f7820b19c --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/NewsBoard.php @@ -0,0 +1,123 @@ +title = __('News Board'); + } + + + /** + * Returns the html of the latest news. + * + * @return string + */ + public function getNews():string + { + global $config; + $options = []; + $options['id_user'] = $config['id_user']; + $options['modal'] = false; + $options['limit'] = 7; + $news = get_news($options); + + if (!empty($news)) { + $output = '
'; + foreach ($news as $article) { + $default = false; + if ($article['text'] == '<p style="text-align: center; font-size: 13px;">Hello, congratulations, if you've arrived here you already have an operational monitoring console. Remember that our forums and online documentation are available 24x7 to get you out of any trouble. You can replace this message with a personalized one at Admin tools -> Site news.</p> ') { + $article['subject'] = __('Welcome to Pandora FMS Console'); + $default = true; + } + + $text_bbdd = io_safe_output($article['text']); + $text = html_entity_decode($text_bbdd); + + $output .= '
'; + $output .= '
'; + $output .= ''.$article['subject'].''; + $output .= ''.__('By').' '.$article['author'].' '.ui_print_timestamp($article['timestamp'], true).''; + $output .= '
'; + $output .= '
'; + + if ($default) { + $output .= '
'; + $output .= '
'; + $output .= 'img colabora con nosotros - Support'; + $output .= '
'; + + $output .= ' +

'.__('Welcome to our monitoring tool so grand,').' +
'.__('Where data insights are at your command.').' +
'.__('Sales, marketing, operations too,').' +
'.__("Customer support, we've got you.").' +

+ +

'.__('Our interface is user-friendly,').' +
'.__("Customize your dashboard, it's easy.").' +
'.__('Set up alerts and gain insights so keen,').' +
'.__("Optimize your data, like you've never seen.").' +

+ +

'.__('Unleash its power now, and join the pro league,').' +
'.__('Unlock the potential of your data to intrigue.').' +
'.__('Monitoring made simple, efficient and fun,').' +
'.__('Discover a whole new way to get things done.').' +

+ +

'.__('And take control of your IT once and for all.').'

+ + '.__('You can replace this message with a personalized one at Admin tools -> Site news.').' + '; + + $output .= '
'; + } else { + $text = str_replace('title = __('General overview'); + } + + + /** + * Return the html log size status. + * + * @return string + */ + public function getLogSizeStatus():string + { + // TODO connect to automonitorization. + $status = true; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + ], + true + ); + + } + + + /** + * Return the html Wix server status. + * + * @return string + */ + public function getWuxServerStatus():string + { + // TODO connect to automonitorization. + $status = false; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + ], + true + ); + + } + + + /** + * Returns the html of the used licenses. + * + * @return string + */ + public function getLicenseUsage():string + { + // TODO connect to automonitorization. + $options = [ + 'labels' => [ + 'Open Source', + 'Enterprise', + 'MaaS', + ], + 'colors' => [ + '#1C4E6B', + '#5C63A2', + '#EC7176', + ], + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + ]; + $pie = ring_graph([2, 4, 6], $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 320px', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of a graph with the processed xmls + * + * @return string + */ + public function getXmlProcessed():string + { + $sql = 'SELECT + utimestamp, + DATE_FORMAT(FROM_UNIXTIME(utimestamp), "%Y-%m-%d %H:00:00") AS hour, + COUNT(*) AS xml_proccessed + FROM tagent_access + WHERE FROM_UNIXTIME(utimestamp) >= NOW() - INTERVAL 24 HOUR + GROUP BY hour + ORDER BY hour;'; + + $rows = db_process_sql($sql); + + $dates = []; + $xml_proccessed = []; + $total = 0; + foreach ($rows as $key => $raw_data) { + $dates[] = date('H:i:s', $raw_data['utimestamp']); + $xml_proccessed[] = $raw_data['xml_proccessed']; + $total += $raw_data['xml_proccessed']; + } + + $options = [ + 'labels' => $dates, + 'legend' => [ 'display' => false ], + 'tooltips' => [ 'display' => false ], + 'scales' => [ + 'y' => [ + 'grid' => ['display' => false], + 'ticks' => ['display' => false], + ], + 'x' => [ + 'grid' => ['display' => false], + 'display' => false, + ], + ], + ]; + + $data = [['data' => $xml_proccessed]]; + + $graph_area = html_print_div( + [ + 'content' => line_graph($data, $options), + 'class' => 'margin-top-5 w100p h100p', + 'style' => 'max-height: 330px;', + ], + true + ); + + $total = html_print_div( + [ + 'content' => $total, + 'class' => 'text-xl', + ], + true + ); + + $output = $total.$graph_area; + + return $output; + } + + +} diff --git a/pandora_console/include/styles/general_tactical_view.css b/pandora_console/include/styles/general_tactical_view.css new file mode 100644 index 0000000000..27c8482cd3 --- /dev/null +++ b/pandora_console/include/styles/general_tactical_view.css @@ -0,0 +1,77 @@ +.row { + display: flex; + width: 100%; +} +.col-6 { + width: 49%; + display: flex; + flex-wrap: wrap; + flex-direction: column; +} +.col-7 { + width: 58%; +} +.col-5 { + width: 41%; +} +.container { + background-color: white; + border: 1px solid #e5e9ed; + border-radius: 10px; + margin: 5px; +} +.br-l { + border-left: 1px solid #e5e9ed; +} +.br-t { + border-top: 1px solid #e5e9ed; +} +.br-r { + border-right: 1px solid #e5e9ed; +} +.br-b { + border-bottom: 1px solid #e5e9ed; +} +.title { + font-size: 18px; + color: #161628; + text-align: center; + font-weight: bold; + padding: 15px 0px; +} +.subtitle { + font-size: 13px; + color: #161628; + padding-bottom: 10px; +} +.subtitle.link { + display: flex; + flex-direction: row; + justify-content: space-between; +} +.subtitle.link a { + color: #14524f; + font-size: 13px; +} +.absolute-link::after { + content: "→"; +} +.status-text { + color: #6e7079; + font-size: 13px; + margin-left: 6px; +} +.text-xl { + font-size: 40px; + color: #6c7587; + font-weight: bold; + padding-left: 8px; + margin-bottom: 8px; + line-height: initial; +} +#news-board { + min-width: 530px; + width: 100%; + max-height: 805px; + overflow-y: auto; +} diff --git a/pandora_console/include/styles/news.css b/pandora_console/include/styles/news.css index c9e66bd462..d25bcc322f 100644 --- a/pandora_console/include/styles/news.css +++ b/pandora_console/include/styles/news.css @@ -1,7 +1,7 @@ .new-board { background-color: #ffffff; - border: 1px solid #e5e9ed; - border-radius: 4px; + border-top: 1px solid #e5e9ed; + border-bottom: 1px solid #e5e9ed; margin-bottom: 15px; } @@ -36,12 +36,12 @@ display: flex; flex-direction: row; flex-wrap: nowrap; - align-items: center; + align-items: flex-start; } .default-new > div > img { width: 100%; - max-width: 430px; + max-width: 268px; height: auto; } diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php new file mode 100644 index 0000000000..63c59c2790 --- /dev/null +++ b/pandora_console/views/tacticalView/view.php @@ -0,0 +1,102 @@ +
+
+
+
+
+ title; ?> +
+
+
+
+
+
+
+ + + + getLogSizeStatus(); ?> +
+
+
+
+ + + + getWuxServerStatus(); ?> +
+
+
+
+
+ + + + getLicenseUsage(); ?> +
+
+
+
+ + getXmlProcessed(); ?> +
+
+
+
+
+
+
+
+
+ title; ?> +
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+ +
+
+ +
+
+
+
+
+
+ title; ?> +
+ getNews(); ?> +
+
+
+ +
+ +
+ +
+ +
\ No newline at end of file From 0fdbefa7eecbac24e61d5ffb42391520cd30a334 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Mon, 25 Sep 2023 13:52:28 +0200 Subject: [PATCH 02/22] #10194 first section drawed --- pandora_console/include/functions_graph.php | 7 +- .../include/lib/TacticalView/Element.php | 19 ++ .../lib/TacticalView/GeneralTacticalView.php | 32 ++ .../lib/TacticalView/elements/Database.php | 309 ++++++++++++++++++ .../lib/TacticalView/elements/Groups.php | 215 ++++++++++++ .../lib/TacticalView/elements/LogStorage.php | 141 ++++++++ .../elements/MonitoringElements.php | 149 +++++++++ .../lib/TacticalView/elements/Overview.php | 18 +- .../lib/TacticalView/elements/SnmpTraps.php | 79 +++++ .../include/styles/general_tactical_view.css | 50 ++- pandora_console/views/tacticalView/view.php | 175 ++++++++-- 11 files changed, 1161 insertions(+), 33 deletions(-) create mode 100644 pandora_console/include/lib/TacticalView/elements/Database.php create mode 100644 pandora_console/include/lib/TacticalView/elements/Groups.php create mode 100644 pandora_console/include/lib/TacticalView/elements/LogStorage.php create mode 100644 pandora_console/include/lib/TacticalView/elements/SnmpTraps.php diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index bb0fe8fd58..dae91c862c 100644 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -4842,12 +4842,17 @@ function graph_nodata_image($options) return base64_encode($dataImg); } + $widthImage = '200px'; + if (isset($options['nodata_image']['width']) === true) { + $widthImage = $options['nodata_image']['width']; + } + return html_print_image( 'images/image_problem_area.png', true, [ 'title' => __('No data'), - 'style' => 'width: 200px;', + 'style' => 'width: '.$widthImage.';', ] ); } diff --git a/pandora_console/include/lib/TacticalView/Element.php b/pandora_console/include/lib/TacticalView/Element.php index a97502e0e1..cf0d6b517e 100644 --- a/pandora_console/include/lib/TacticalView/Element.php +++ b/pandora_console/include/lib/TacticalView/Element.php @@ -53,4 +53,23 @@ class Element } + /** + * Cut the text to display it on the labels. + * + * @param string $text Text for cut. + * @param integer $length Length max for text cutted. + * + * @return string + */ + protected function controlSizeText(string $text, int $length=14):string + { + if (mb_strlen($text) > $length) { + $newText = mb_substr($text, 0, $length).'...'; + return $newText; + } else { + return $text; + } + } + + } diff --git a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php index 82b042cf7c..275b82efbd 100644 --- a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php +++ b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php @@ -70,6 +70,7 @@ class GeneralTacticalView ]; $elements = []; + $elements['welcome'] = $this->getWelcomeMessage(); while (false !== ($file = readdir($handle))) { try { if (in_array($file, $ignores) === true) { @@ -112,4 +113,35 @@ class GeneralTacticalView } + /** + * Return the welcome message. + * + * @return string + */ + private function getWelcomeMessage():string + { + global $config; + $profile = users_get_user_profile($config['id_user']); + if (is_array($profile) === true && count($profile) > 0) { + $name = $profile[0]['name']; + } else { + $name = ''; + } + + if (empty($name) === true) { + $message = __('Welcome back! 👋'); + } else { + $message = __('Welcome back %s! 👋', $name); + } + + return html_print_div( + [ + 'content' => $message, + 'class' => 'message-welcome', + ], + true + ); + } + + } diff --git a/pandora_console/include/lib/TacticalView/elements/Database.php b/pandora_console/include/lib/TacticalView/elements/Database.php new file mode 100644 index 0000000000..b7250fb390 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/Database.php @@ -0,0 +1,309 @@ +title = __('Database'); + } + + + /** + * Returns the html status of database. + * + * @return string + */ + public function getStatus():string + { + // TODO connect to automonitorization. + $status = true; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html records data of database. + * + * @return string + */ + public function getDataRecords():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total events. + * + * @return string + */ + public function getEvents():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total records. + * + * @return string + */ + public function getStringRecords():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total reads database in a graph. + * + * @return string + */ + public function getReadsGraph():string + { + // TODO connect to automonitorization. + $dates = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + ]; + $string_reads = [ + 1, + 0.5, + 2, + 1.5, + 3, + 2.5, + 4, + 3.5, + 5, + 4.5, + 6, + ]; + $total = '9.999.999'; + $options = [ + 'labels' => $dates, + 'legend' => [ 'display' => false ], + 'tooltips' => [ 'display' => false ], + 'scales' => [ + 'y' => [ + 'grid' => ['display' => false], + 'ticks' => ['display' => false], + 'display' => false, + ], + 'x' => [ + 'grid' => ['display' => false], + 'display' => false, + ], + ], + ]; + + $data = [ + [ + 'backgroundColor' => '#EC7176', + 'borderColor' => '#EC7176', + 'pointBackgroundColor' => '#EC7176', + 'pointHoverBorderColor' => '#EC7176', + 'data' => $string_reads, + ], + ]; + + $graph_area = html_print_div( + [ + 'content' => line_graph($data, $options), + 'class' => 'w100p h100p', + 'style' => 'max-height: 100px;', + ], + true + ); + + $total = html_print_div( + [ + 'content' => $total, + 'class' => 'text-xl', + ], + true + ); + + $output = $total.$graph_area; + + return $output; + } + + + /** + * Returns the html of total writes database in a graph. + * + * @return string + */ + public function getWritesGraph():string + { + // TODO connect to automonitorization. + $dates = [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + ]; + $string_writes = [ + 1, + 0.5, + 2, + 1.5, + 3, + 2.5, + 4, + 3.5, + 5, + 4.5, + 6, + ]; + $total = '9.999.999'; + $options = [ + 'labels' => $dates, + 'legend' => [ 'display' => false ], + 'tooltips' => [ 'display' => false ], + 'scales' => [ + 'y' => [ + 'grid' => ['display' => false], + 'ticks' => ['display' => false], + 'display' => false, + ], + 'x' => [ + 'grid' => ['display' => false], + 'display' => false, + ], + ], + ]; + + $data = [ + [ + 'backgroundColor' => '#009D9E', + 'borderColor' => '#009D9E', + 'pointBackgroundColor' => '#009D9E', + 'pointHoverBorderColor' => '#009D9E', + 'data' => $string_writes, + ], + ]; + + $graph_area = html_print_div( + [ + 'content' => line_graph($data, $options), + 'class' => 'w100p h100p', + 'style' => 'max-height: 100px;', + ], + true + ); + + $total = html_print_div( + [ + 'content' => $total, + 'class' => 'text-xl', + ], + true + ); + + $output = $total.$graph_area; + + return $output; + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/Groups.php b/pandora_console/include/lib/TacticalView/elements/Groups.php new file mode 100644 index 0000000000..55bf2a2354 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/Groups.php @@ -0,0 +1,215 @@ +title = __('Groups'); + $this->total = $this->calculateTotalGroups(); + } + + + /** + * Return the total groups. + * + * @return integer + */ + public function calculateTotalGroups():int + { + $total = db_get_num_rows('SELECT * FROM tgrupo;'); + return $total; + } + + + /** + * Return the status groups in heat map. + * + * @return string + */ + public function getStatusHeatMap():string + { + ui_require_css_file('heatmap'); + $width = 350; + $height = 335; + $sql = 'SELECT * FROM tagente a + LEFT JOIN tagent_secondary_group g ON g.id_agent = a.id_agente'; + + $all_agents = db_get_all_rows_sql($sql); + if (empty($all_agents)) { + return null; + } + + $total_agents = count($all_agents); + + // Best square. + $high = (float) max($width, $height); + $low = 0.0; + + while (abs($high - $low) > 0.000001) { + $mid = (($high + $low) / 2.0); + $midval = (floor($width / $mid) * floor($height / $mid)); + if ($midval >= $total_agents) { + $low = $mid; + } else { + $high = $mid; + } + } + + $square_length = min(($width / floor($width / $low)), ($height / floor($height / $low))); + // Print starmap. + $heatmap = sprintf( + '', + $width, + $height + ); + + $heatmap .= ''; + $row = 0; + $column = 0; + $x = 0; + $y = 0; + $cont = 1; + + foreach ($all_agents as $key => $value) { + // Colour by status. + $status = agents_get_status_from_counts($value); + + switch ($status) { + case 5: + // Not init status. + $status = 'notinit'; + break; + + case 1: + // Critical status. + $status = 'critical'; + break; + + case 2: + // Warning status. + $status = 'warning'; + break; + + case 0: + // Normal status. + $status = 'normal'; + break; + + case 3: + case -1: + default: + // Unknown status. + $status = 'unknown'; + break; + } + + $heatmap .= sprintf( + '', + 'rect_'.$cont, + $x, + $y, + $row, + $column, + $square_length, + $square_length, + $status, + random_int(1, 10) + ); + + $y += $square_length; + $row++; + if ((int) ($y + $square_length) > (int) $height) { + $y = 0; + $x += $square_length; + $row = 0; + $column++; + } + + if ((int) ($x + $square_length) > (int) $width) { + $x = 0; + $y += $square_length; + $column = 0; + $row++; + } + + $cont++; + } + + $heatmap .= ''; + $heatmap .= ''; + $heatmap .= ''; + + return html_print_div( + [ + 'content' => $heatmap, + 'style' => 'margin: 0 auto; width: fit-content;', + ], + true + ); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/LogStorage.php b/pandora_console/include/lib/TacticalView/elements/LogStorage.php new file mode 100644 index 0000000000..fcde21a295 --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/LogStorage.php @@ -0,0 +1,141 @@ +title = __('Log storage'); + } + + + /** + * Returns the html status of log storage. + * + * @return string + */ + public function getStatus():string + { + // TODO connect to automonitorization. + $status = true; + + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + + $output = $image_status.$text; + + return html_print_div( + [ + 'content' => $output, + 'class' => 'flex_center margin-top-5', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total sources in log storage. + * + * @return string + */ + public function getTotalSources():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 0px 10px;', + ], + true + ); + } + + + /** + * Returns the html of lines in log storage. + * + * @return string + */ + public function getStoredData():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 0px 10px;', + ], + true + ); + } + + + /** + * Returns the html of age of stored data. + * + * @return string + */ + public function getAgeOfStoredData():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 0px 10px;', + ], + true + ); + } + + +} diff --git a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php index 4731d54b27..7a91348cf8 100644 --- a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php +++ b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php @@ -38,4 +38,153 @@ class MonitoringElements extends Element } + /** + * Returns the html of the tags grouped by modules. + * + * @return string + */ + public function getTagsGraph():string + { + $sql = 'SELECT name, count(*) AS total + FROM ttag_module t + LEFT JOIN ttag ta ON ta.id_tag = t.id_tag + GROUP BY t.id_tag'; + $rows = db_process_sql($sql); + + $labels = []; + $data = []; + foreach ($rows as $key => $row) { + $labels[] = $this->controlSizeText($row['name']); + $data[] = $row['total']; + } + + $options = [ + 'labels' => $labels, + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + 'nodata_image' => ['width' => '100%'], + ]; + $pie = ring_graph($data, $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of the groups grouped by modules. + * + * @return string + */ + public function getModuleGroupGraph():string + { + $sql = 'SELECT name, count(*) AS total + FROM tagente_modulo m + LEFT JOIN tmodule_group g ON g.id_mg = m.id_module_group + WHERE name <> "" + GROUP BY m.id_module_group'; + $rows = db_process_sql($sql); + + $labels = []; + $data = []; + foreach ($rows as $key => $row) { + $labels[] = $this->controlSizeText($row['name']); + $data[] = $row['total']; + } + + $options = [ + 'labels' => $labels, + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + 'nodata_image' => ['width' => '100%'], + ]; + $pie = ring_graph($data, $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of the agent grouped by modules. + * + * @return string + */ + public function getAgentGroupsGraph():string + { + $sql = 'SELECT gr.nombre, count(*) AS total + FROM tagente a + LEFT JOIN tagent_secondary_group g ON g.id_agent = a.id_agente + LEFT JOIN tgrupo gr ON gr.id_grupo = a.id_grupo + GROUP BY a.id_grupo'; + $rows = db_process_sql($sql); + + $labels = []; + $data = []; + foreach ($rows as $key => $row) { + $labels[] = $this->controlSizeText($row['nombre']); + $data[] = $row['total']; + } + + $options = [ + 'labels' => $labels, + 'legend' => [ + 'position' => 'bottom', + 'align' => 'right', + ], + 'cutout' => 80, + 'nodata_image' => ['width' => '100%'], + ]; + $pie = ring_graph($data, $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + + /** + * Returns the html of monitoring by status. + * + * @return string + */ + public function getMonitoringStatusGraph():string + { + // TODO add labels. + $pie = graph_agent_status(false, '', '', true, true, false, true); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 60%; max-height: 220px;', + ], + true + ); + + return $output; + } + + } diff --git a/pandora_console/include/lib/TacticalView/elements/Overview.php b/pandora_console/include/lib/TacticalView/elements/Overview.php index ba82e00a60..8ab35336a9 100644 --- a/pandora_console/include/lib/TacticalView/elements/Overview.php +++ b/pandora_console/include/lib/TacticalView/elements/Overview.php @@ -129,7 +129,7 @@ class Overview extends Element * * @return string */ - public function getLicenseUsage():string + public function getLicenseUsageGraph():string { // TODO connect to automonitorization. $options = [ @@ -167,7 +167,7 @@ class Overview extends Element * * @return string */ - public function getXmlProcessed():string + public function getXmlProcessedGraph():string { $sql = 'SELECT utimestamp, @@ -184,9 +184,9 @@ class Overview extends Element $xml_proccessed = []; $total = 0; foreach ($rows as $key => $raw_data) { - $dates[] = date('H:i:s', $raw_data['utimestamp']); - $xml_proccessed[] = $raw_data['xml_proccessed']; + $dates[] = date('H:00:00', $raw_data['utimestamp']); $total += $raw_data['xml_proccessed']; + $xml_proccessed[] = $raw_data['xml_proccessed']; } $options = [ @@ -205,7 +205,15 @@ class Overview extends Element ], ]; - $data = [['data' => $xml_proccessed]]; + $data = [ + [ + 'backgroundColor' => '#009D9E', + 'borderColor' => '#009D9E', + 'pointBackgroundColor' => '#009D9E', + 'pointHoverBorderColor' => '#009D9E', + 'data' => $xml_proccessed, + ], + ]; $graph_area = html_print_div( [ diff --git a/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php b/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php new file mode 100644 index 0000000000..4068531c2d --- /dev/null +++ b/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php @@ -0,0 +1,79 @@ +title = __('SNMP Traps'); + } + + + /** + * Returns the html of queues traps. + * + * @return string + */ + public function getQueues():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + + /** + * Returns the html of total sources traps. + * + * @return string + */ + public function getTotalSources():string + { + // TODO connect to automonitorization. + return html_print_div( + [ + 'content' => '9.999.999', + 'class' => 'text-l', + 'style' => 'margin: 0px 10px 10px 10px;', + ], + true + ); + } + + +} diff --git a/pandora_console/include/styles/general_tactical_view.css b/pandora_console/include/styles/general_tactical_view.css index 27c8482cd3..427667455e 100644 --- a/pandora_console/include/styles/general_tactical_view.css +++ b/pandora_console/include/styles/general_tactical_view.css @@ -1,3 +1,22 @@ +#welcome-message { + margin-bottom: 30px; +} + +.message-welcome { + color: #161628; + font-size: 32px; + line-height: 38px; + text-align: left; + font-weight: 700; +} + +.subtitle-welcome-message { + color: #8a96a6; + font-size: 15px; + line-height: 20px; + text-align: left; + margin-left: 5px; +} .row { display: flex; width: 100%; @@ -19,6 +38,7 @@ border: 1px solid #e5e9ed; border-radius: 10px; margin: 5px; + max-width: 100%; } .br-l { border-left: 1px solid #e5e9ed; @@ -33,11 +53,11 @@ border-bottom: 1px solid #e5e9ed; } .title { - font-size: 18px; + font-size: 18px !important; color: #161628; - text-align: center; - font-weight: bold; - padding: 15px 0px; + text-align: center !important; + font-weight: bold !important; + padding: 15px 0px !important; } .subtitle { font-size: 13px; @@ -52,6 +72,7 @@ .subtitle.link a { color: #14524f; font-size: 13px; + font-weight: 800; } .absolute-link::after { content: "→"; @@ -69,9 +90,30 @@ margin-bottom: 8px; line-height: initial; } +.text-l { + font-size: 27px; + color: #6c7587; + font-weight: bold; + margin-bottom: 8px; + line-height: initial; +} #news-board { min-width: 530px; width: 100%; max-height: 805px; overflow-y: auto; } + +#database .subtitle, +#logStorage .subtitle, +#SNMPTraps .subtitle { + padding: 10px 10px 5px 10px; +} + +.indicative-text { + color: #6e7079; + font-size: 12px; + line-height: 13px; + text-align: left; + padding: 0px 10px 10px 10px; +} diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php index 63c59c2790..92a4d54f79 100644 --- a/pandora_console/views/tacticalView/view.php +++ b/pandora_console/views/tacticalView/view.php @@ -1,3 +1,8 @@ +
+ + +
+
@@ -31,7 +36,7 @@ - getLicenseUsage(); ?> + getLicenseUsageGraph(); ?>
@@ -39,7 +44,7 @@ - getXmlProcessed(); ?> + getXmlProcessedGraph(); ?>
@@ -51,27 +56,33 @@
title; ?>
-
-
-
-
+
@@ -60,13 +60,13 @@
getTagsGraph(); ?>
getModuleGroupGraph(); ?>
@@ -80,7 +80,7 @@
getAgentGroupsGraph(); ?>
@@ -141,7 +141,7 @@
-
+
title; ?> @@ -223,9 +223,151 @@
+
+
+
+ title; ?> +
+
+
+
+ +
+ getCurrentlyTriggered(); ?> +
+
+
+ +
+ getActiveCorrelation(); ?> +
+
+ + getDataTableUsers(); ?> +
+
+
+
+
+ title; ?> +
+
+
+ + getEventsGraph(); ?> +
+
+ + getEventsCriticalityGraph(); ?> +
+
+ + getEventsStatusValidateGraph(); ?> +
+
+ + getEventsStatusValidateGraph(); ?> +
+
+
+
+ + getDataTableEvents(); ?> +
+
+
+
- +
+
+
+ title; ?> +
+
+
+
+
+
+ +
+ getTotalAgents(); ?> +
+
+
+ +
+ getAlerts(); ?> +
+
+ + getDataTableGroups(); ?> +
+
+ + getOperatingSystemGraph(); ?> + + getOperatingSystemGraph(); ?> +
+
+
+
+
+
+
+ title; ?> +
+
+
+ getTotalGroups(); ?> +
+
+ getTotalModules(); ?> +
+
+ getTotalPolicies(); ?> +
+
+ getTotalRemotePlugins(); ?> +
+
+
+
+ getTotalModuleTemplate(); ?> +
+
+ getNotInitModules(); ?> +
+
+ getTotalUnknowAgents(); ?> +
+
+
+
+
+ title; ?> +
+ list(); ?> +
+
\ No newline at end of file From e7e27855a62322a8e786bc472c0e2473556d9b1e Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Fri, 29 Sep 2023 08:55:24 +0200 Subject: [PATCH 05/22] #10194 fixed name empty in agents y monitoring --- .../include/lib/TacticalView/elements/Agents.php | 8 ++++++++ .../lib/TacticalView/elements/MonitoringElements.php | 12 ++++++++++++ 2 files changed, 20 insertions(+) diff --git a/pandora_console/include/lib/TacticalView/elements/Agents.php b/pandora_console/include/lib/TacticalView/elements/Agents.php index 6e9d46e21d..eef1264334 100644 --- a/pandora_console/include/lib/TacticalView/elements/Agents.php +++ b/pandora_console/include/lib/TacticalView/elements/Agents.php @@ -241,6 +241,10 @@ class Agents extends Element $labels = []; $data = []; foreach ($rows as $key => $row) { + if (empty($row['name']) === true) { + continue; + } + $labels[] = $this->controlSizeText($row['name']); $data[] = $row['total']; } @@ -279,6 +283,10 @@ class Agents extends Element $labels = []; $data = []; foreach ([] as $key => $row) { + if (empty($row['alias']) === true) { + continue; + } + $labels[] = $this->controlSizeText($row['alias']); $data[] = $row['status']; } diff --git a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php index 0b071a6109..d277437c63 100644 --- a/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php +++ b/pandora_console/include/lib/TacticalView/elements/MonitoringElements.php @@ -57,6 +57,10 @@ class MonitoringElements extends Element $labels = []; $data = []; foreach ($rows as $key => $row) { + if (empty($row['name']) === true) { + continue; + } + $labels[] = $this->controlSizeText($row['name']); $data[] = $row['total']; } @@ -103,6 +107,10 @@ class MonitoringElements extends Element $labels = []; $data = []; foreach ($rows as $key => $row) { + if (empty($row['name']) === true) { + continue; + } + $labels[] = $this->controlSizeText($row['name']); $data[] = $row['total']; } @@ -154,6 +162,10 @@ class MonitoringElements extends Element $labels = []; $data = []; foreach ($rows as $key => $row) { + if (empty($row['nombre']) === true) { + continue; + } + $labels[] = $this->controlSizeText($row['nombre']); $data[] = $row['total']; } From 438cb11f953a55b34b24d594e8fd6ad4508dc45f Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Mon, 2 Oct 2023 16:44:53 +0200 Subject: [PATCH 06/22] #10194 added automonitoritation modules and interval refresh async --- .../ajax/general_tactical_view.ajax.php | 2 +- .../javascript/general_tactical_view.js | 72 +++++++++ .../include/lib/TacticalView/Element.php | 82 +++++++++- .../lib/TacticalView/GeneralTacticalView.php | 27 +++- .../lib/TacticalView/elements/Agents.php | 106 ++++++++++--- .../lib/TacticalView/elements/Alerts.php | 47 ++++-- .../TacticalView/elements/Configurations.php | 20 ++- .../lib/TacticalView/elements/Database.php | 142 ++++++++++-------- .../lib/TacticalView/elements/Events.php | 12 +- .../lib/TacticalView/elements/Groups.php | 81 +++++----- .../lib/TacticalView/elements/LogStorage.php | 51 +++++-- .../elements/MonitoringElements.php | 1 - .../lib/TacticalView/elements/Overview.php | 27 +++- .../lib/TacticalView/elements/SnmpTraps.php | 27 +++- .../include/styles/general_tactical_view.css | 1 - pandora_console/include/styles/pandora.css | 4 + pandora_console/views/tacticalView/view.php | 20 +-- 17 files changed, 536 insertions(+), 186 deletions(-) create mode 100644 pandora_console/include/javascript/general_tactical_view.js diff --git a/pandora_console/include/ajax/general_tactical_view.ajax.php b/pandora_console/include/ajax/general_tactical_view.ajax.php index 3b4865421e..99c9b09a57 100644 --- a/pandora_console/include/ajax/general_tactical_view.ajax.php +++ b/pandora_console/include/ajax/general_tactical_view.ajax.php @@ -66,7 +66,7 @@ if (is_ajax()) { if (class_exists($class) === true) { $instance = new $class(); if ($instance->ajaxMethod($method) === true) { - $instance->{$method}(); + echo $instance->{$method}(); } else { $instance->error('Unavailable method.'); } diff --git a/pandora_console/include/javascript/general_tactical_view.js b/pandora_console/include/javascript/general_tactical_view.js new file mode 100644 index 0000000000..ee9aae65f2 --- /dev/null +++ b/pandora_console/include/javascript/general_tactical_view.js @@ -0,0 +1,72 @@ +/* global $ */ +$(document).ready(function() { + $.ajax({ + url: "ajax.php", + data: { + page: "include/ajax/general_tactical_view.ajax", + method: "getEventsGraph", + class: "Events" + }, + type: "POST", + success: function(data) { + $("#events-last-24").html(data); + } + }); + + $.ajax({ + url: "ajax.php", + data: { + page: "include/ajax/general_tactical_view.ajax", + method: "getEventsCriticalityGraph", + class: "Events" + }, + type: "POST", + success: function(data) { + $("#events-criticality").html(data); + } + }); + + $.ajax({ + url: "ajax.php", + data: { + page: "include/ajax/general_tactical_view.ajax", + method: "getEventsStatusValidateGraph", + class: "Events" + }, + type: "POST", + success: function(data) { + $("#events-status-validate").html(data); + } + }); + + $.ajax({ + url: "ajax.php", + data: { + page: "include/ajax/general_tactical_view.ajax", + method: "getEventsStatusValidateGraph", + class: "Events" + }, + type: "POST", + success: function(data) { + $("#events-status-pending-validate").html(data); + } + }); +}); + +function autoRefresh(interval, id, method, php_class) { + setInterval(() => { + $.ajax({ + url: "ajax.php", + data: { + page: "include/ajax/general_tactical_view.ajax", + method: method, + class: php_class + }, + type: "POST", + success: function(data) { + var content = $(data).html(); + $("#" + id).html(content); + } + }); + }, interval); +} diff --git a/pandora_console/include/lib/TacticalView/Element.php b/pandora_console/include/lib/TacticalView/Element.php index ed0c7c78d6..b7c756fb39 100644 --- a/pandora_console/include/lib/TacticalView/Element.php +++ b/pandora_console/include/lib/TacticalView/Element.php @@ -54,7 +54,21 @@ class Element * * @var integer */ - protected $interval; + public $interval; + + /** + * Agent of automonitoritation + * + * @var array + */ + protected $monitoringAgent; + + /** + * Refresh config for async method. + * + * @var array + */ + public $refreshConfig = []; /** @@ -68,6 +82,11 @@ class Element $this->interval = 0; $this->title = __('Default element'); $this->ajaxController = $ajax_controller; + $agent = agents_get_agents(['nombre' => 'pandora.internals']); + if (is_array($agent) === true && count($agent) > 0) { + $this->monitoringAgent = $agent[0]; + } + } @@ -116,4 +135,65 @@ class Element } + /** + * Return a valur from Module of monitoring. + * + * @param string $moduleName Name of module value. + * @param integer $dateInit Date init for filter. + * @param integer $dateEnd Date end for filter. + * + * @return array Array of module data. + */ + protected function valueMonitoring(string $moduleName, int $dateInit=0, int $dateEnd=0):array + { + if (empty($this->monitoringAgent) === false) { + $module = modules_get_agentmodule_id(io_safe_input($moduleName), $this->monitoringAgent['id_agente']); + if (is_array($module) === true && key_exists('id_agente_modulo', $module) === true) { + if ($dateInit === 0 && $dateEnd === 0) { + $value = modules_get_last_value($module['id_agente_modulo']); + $rawData = [['datos' => $value]]; + } else { + $rawData = modules_get_raw_data($module['id_agente_modulo'], $dateInit, $dateEnd); + } + + return $rawData; + } else { + return [['datos' => 0]]; + } + + return [['datos' => 0]]; + } else { + return [['datos' => 0]]; + } + } + + + /** + * Simple image loading for async functions. + * + * @return string + */ + public static function loading():string + { + return html_print_div( + [ + 'content' => '', + 'class' => 'spinner-fixed inherit', + ], + true + ); + } + + + /** + * Return the name of class + * + * @return string + */ + public static function nameClass():string + { + return static::class; + } + + } diff --git a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php index 42f351f56d..3bc2e45246 100644 --- a/pandora_console/include/lib/TacticalView/GeneralTacticalView.php +++ b/pandora_console/include/lib/TacticalView/GeneralTacticalView.php @@ -45,6 +45,7 @@ class GeneralTacticalView public function __construct() { ui_require_css_file('general_tactical_view'); + ui_require_javascript_file('general_tactical_view'); $this->elements = $this->instanceElements(); } @@ -106,13 +107,37 @@ class GeneralTacticalView */ public function render():void { + $data = []; + $data['javascript'] = $this->javascript(); + $data = array_merge($data, $this->elements); View::render( 'tacticalView/view', - $this->elements + $data ); } + /** + * Function for print js embedded in html. + * + * @return string + */ + public function javascript():string + { + $js = ''; + return $js; + } + + /** * Return the welcome message. * diff --git a/pandora_console/include/lib/TacticalView/elements/Agents.php b/pandora_console/include/lib/TacticalView/elements/Agents.php index eef1264334..d3061599f6 100644 --- a/pandora_console/include/lib/TacticalView/elements/Agents.php +++ b/pandora_console/include/lib/TacticalView/elements/Agents.php @@ -47,10 +47,11 @@ class Agents extends Element */ public function getTotalAgents():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('total_agents'); + $total = round($value[0]['datos']); return html_print_div( [ - 'content' => '9.999.999', + 'content' => $total, 'class' => 'text-l', 'style' => 'margin: 0px 10px 10px 10px;', ], @@ -66,10 +67,11 @@ class Agents extends Element */ public function getAlerts():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('triggered_alerts_24h'); + $total = round($value[0]['datos']); return html_print_div( [ - 'content' => '9.999.999', + 'content' => $total, 'class' => 'text-l', 'style' => 'margin: 0px 10px 10px 10px;', ], @@ -105,7 +107,10 @@ class Agents extends Element 'columns' => $columns, 'column_names' => $columnNames, 'ajax_url' => $this->ajaxController, - 'no-filtered' => [-1], + 'no_sortable_columns' => [ + 0, + 1, + ], 'ajax_data' => [ 'method' => 'getGroups', 'class' => static::class, @@ -125,9 +130,9 @@ class Agents extends Element /** * Return top 20 groups with more agents for ajax datatable. * - * @return void + * @return string */ - public function getGroups():void + public function getGroups():string { global $config; @@ -195,26 +200,25 @@ class Agents extends Element $total = db_get_num_rows($sql_count); - echo json_encode( + // Capture output. + $response = ob_get_clean(); + + return json_encode( [ 'data' => $rows, 'recordsTotal' => $total, 'recordsFiltered' => $total, ] ); - - // Capture output. - $response = ob_get_clean(); } catch (Exception $e) { - echo json_encode(['error' => $e->getMessage()]); - exit; + return json_encode(['error' => $e->getMessage()]); } json_decode($response); if (json_last_error() === JSON_ERROR_NONE) { - echo $response; + return $response; } else { - echo json_encode( + return json_encode( [ 'success' => false, 'error' => $response, @@ -279,16 +283,71 @@ class Agents extends Element */ public function getStatusGraph():string { - // TODO Find the method for calculate status in agents. - $labels = []; - $data = []; - foreach ([] as $key => $row) { - if (empty($row['alias']) === true) { - continue; + $agents = agents_get_agents( + false, + [ + 'id_agente', + 'id_grupo', + 'nombre', + 'alias', + 'id_os', + 'ultimo_contacto', + 'intervalo', + 'comentarios description', + 'quiet', + 'normal_count', + 'warning_count', + 'critical_count', + 'unknown_count', + 'notinit_count', + 'total_count', + 'fired_count', + 'ultimo_contacto_remoto', + 'remote', + 'agent_version', + ] + ); + $labels = [ + __('No Monitors'), + __('CRITICAL'), + __('WARNING'), + __('UKNOWN'), + __('NORMAL'), + ]; + $totals = [ + 'no_monitors' => 0, + 'critical' => 0, + 'warning' => 0, + 'unknown' => 0, + 'ok' => 0, + ]; + + $colors = [ + COL_NOTINIT, + COL_CRITICAL, + COL_WARNING, + COL_UNKNOWN, + COL_NORMAL, + ]; + + foreach ($agents as $key => $agent) { + if ($agent['total_count'] == 0 || $agent['total_count'] == $agent['notinit_count']) { + $totals['no_monitors']++; } - $labels[] = $this->controlSizeText($row['alias']); - $data[] = $row['status']; + if ($agent['critical_count'] > 0) { + $totals['critical']++; + } else if ($agent['warning_count'] > 0) { + $totals['warning']++; + } else if ($agent['unknown_count'] > 0) { + $totals['unknown']++; + } else { + $totals['ok']++; + } + } + + foreach ($totals as $key => $total) { + $data[] = $total; } $options = [ @@ -300,6 +359,7 @@ class Agents extends Element ], 'cutout' => 80, 'nodata_image' => ['width' => '80%'], + 'colors' => $colors, ]; $pie = ring_graph($data, $options); $output = html_print_div( diff --git a/pandora_console/include/lib/TacticalView/elements/Alerts.php b/pandora_console/include/lib/TacticalView/elements/Alerts.php index 0c970346a6..fc4c3a5297 100644 --- a/pandora_console/include/lib/TacticalView/elements/Alerts.php +++ b/pandora_console/include/lib/TacticalView/elements/Alerts.php @@ -37,6 +37,22 @@ class Alerts extends Element parent::__construct(); $this->title = __('Alerts'); $this->ajaxMethods = ['getUsers']; + $this->ajaxMethods = [ + 'getUsers', + 'getCurrentlyTriggered', + 'getActiveCorrelation', + ]; + $this->interval = 300000; + $this->refreshConfig = [ + 'triggered' => [ + 'id' => 'currently-triggered', + 'method' => 'getCurrentlyTriggered', + ], + 'active-correlation' => [ + 'id' => 'active-correlation', + 'method' => 'getActiveCorrelation', + ], + ]; } @@ -47,11 +63,13 @@ class Alerts extends Element */ public function getCurrentlyTriggered():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('triggered_alerts'); + $total = round($value[0]['datos']); return html_print_div( [ - 'content' => '9.999.999', + 'content' => $total, 'class' => 'text-l', + 'id' => 'currently-triggered', 'style' => 'margin: 0px 10px 10px 10px;', ], true @@ -66,11 +84,13 @@ class Alerts extends Element */ public function getActiveCorrelation():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('triggered_correlative_alerts'); + $total = round($value[0]['datos']); return html_print_div( [ - 'content' => '9.999.999', + 'content' => $total, 'class' => 'text-l', + 'id' => 'active-correlation', 'style' => 'margin: 0px 10px 10px 10px;', ], true @@ -126,9 +146,9 @@ class Alerts extends Element /** * Return all users for ajax. * - * @return void + * @return string */ - public function getUsers():void + public function getUsers():string { global $config; @@ -188,26 +208,25 @@ class Alerts extends Element $total = db_process_sql($sql_count); - echo json_encode( + // Capture output. + $response = ob_get_clean(); + + return json_encode( [ 'data' => $rows, 'recordsTotal' => $total[0]['total'], 'recordsFiltered' => $total[0]['total'], ] ); - - // Capture output. - $response = ob_get_clean(); } catch (Exception $e) { - echo json_encode(['error' => $e->getMessage()]); - exit; + return json_encode(['error' => $e->getMessage()]); } json_decode($response); if (json_last_error() === JSON_ERROR_NONE) { - echo $response; + return $response; } else { - echo json_encode( + return json_encode( [ 'success' => false, 'error' => $response, diff --git a/pandora_console/include/lib/TacticalView/elements/Configurations.php b/pandora_console/include/lib/TacticalView/elements/Configurations.php index a6e171f8b5..51b9dcd6b5 100644 --- a/pandora_console/include/lib/TacticalView/elements/Configurations.php +++ b/pandora_console/include/lib/TacticalView/elements/Configurations.php @@ -46,12 +46,13 @@ class Configurations extends Element */ public function getTotalGroups():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('total_groups'); + $total = round($value[0]['datos']); $image = html_print_image('images/Tactical_Groups.svg', true); $text = ''.__('Groups').''; $number = html_print_div( [ - 'content' => '999.999', + 'content' => $total, 'class' => 'text-l text_center', 'style' => '', ], @@ -69,12 +70,13 @@ class Configurations extends Element */ public function getTotalModules():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('total_modules'); + $total = round($value[0]['datos']); $image = html_print_image('images/Tactical_Modules.svg', true); $text = ''.__('Modules').''; $number = html_print_div( [ - 'content' => '999.999', + 'content' => $total, 'class' => 'text-l text_center', 'style' => '', ], @@ -182,12 +184,13 @@ class Configurations extends Element */ public function getNotInitModules():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('total_notinit'); + $total = round($value[0]['datos']); $image = html_print_image('images/Tactical_Not_init_module.svg', true); $text = ''.__('Not-init modules').''; $number = html_print_div( [ - 'content' => '999.999', + 'content' => $total, 'class' => 'text-l text_center', 'style' => '', ], @@ -205,12 +208,13 @@ class Configurations extends Element */ public function getTotalUnknowAgents():string { - // TODO connect to automonitorization. + $value = $this->valueMonitoring('total_notinit'); + $total = round($value[0]['total_unknown']); $image = html_print_image('images/Tactical_Unknown_agent.svg', true); $text = ''.__('Unknown agents').''; $number = html_print_div( [ - 'content' => '999.999', + 'content' => $total, 'class' => 'text-l text_center', 'style' => '', ], diff --git a/pandora_console/include/lib/TacticalView/elements/Database.php b/pandora_console/include/lib/TacticalView/elements/Database.php index c1c0138e28..ffd38c8156 100644 --- a/pandora_console/include/lib/TacticalView/elements/Database.php +++ b/pandora_console/include/lib/TacticalView/elements/Database.php @@ -36,6 +36,42 @@ class Database extends Element { parent::__construct(); $this->title = __('Database'); + $this->ajaxMethods = [ + 'getStatus', + 'getDataRecords', + 'getEvents', + 'getStringRecords', + 'getReadsGraph', + 'getWritesGraph', + ]; + $this->interval = 300000; + $this->refreshConfig = [ + 'status' => [ + 'id' => 'status-database', + 'method' => 'getStatus', + ], + 'records' => [ + 'id' => 'data-records', + 'method' => 'getDataRecords', + ], + 'events' => [ + 'id' => 'total-events', + 'method' => 'getEvents', + ], + 'totalRecords' => [ + 'id' => 'total-records', + 'method' => 'getStringRecords', + + ], + 'reads' => [ + 'id' => 'database-reads', + 'method' => 'getReadsGraph', + ], + 'writes' => [ + 'id' => 'database-writes', + 'method' => 'getWritesGraph', + ], + ]; } @@ -75,6 +111,7 @@ class Database extends Element [ 'content' => $output, 'class' => 'flex_center margin-top-5', + 'id' => 'status-database', 'style' => 'margin: 0px 10px 10px 10px;', ], true @@ -89,11 +126,13 @@ class Database extends Element */ public function getDataRecords():string { - // TODO connect to automonitorization. + $data = $this->valueMonitoring('mysql_size_of_data'); + $value = round($data[0]['datos'], 2).' MB'; return html_print_div( [ - 'content' => '9.999.999', + 'content' => $value, 'class' => 'text-l', + 'id' => 'data-records', 'style' => 'margin: 0px 10px 10px 10px;', ], true @@ -113,6 +152,7 @@ class Database extends Element [ 'content' => '9.999.999', 'class' => 'text-l', + 'id' => 'total-events', 'style' => 'margin: 0px 10px 10px 10px;', ], true @@ -127,11 +167,13 @@ class Database extends Element */ public function getStringRecords():string { - // TODO connect to automonitorization. + $data = $this->valueMonitoring('total_string_data'); + $value = round($data[0]['datos']); return html_print_div( [ - 'content' => '9.999.999', + 'content' => $value, 'class' => 'text-l', + 'id' => 'total-records', 'style' => 'margin: 0px 10px 10px 10px;', ], true @@ -146,33 +188,17 @@ class Database extends Element */ public function getReadsGraph():string { - // TODO connect to automonitorization. - $dates = [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - ]; - $string_reads = [ - 1, - 0.5, - 2, - 1.5, - 3, - 2.5, - 4, - 3.5, - 5, - 4.5, - 6, - ]; - $total = '9.999.999'; + $dateInit = (time() - 86400); + $reads = $this->valueMonitoring('mysql_questions_reads', $dateInit, time()); + $dates = []; + $string_reads = []; + $total = 0; + foreach ($reads as $key => $read) { + $dates[] = date('d-m-Y H:i:s', $read['utimestamp']); + $string_reads[] = $read['datos']; + $total += $read['datos']; + } + $options = [ 'labels' => $dates, 'legend' => [ 'display' => false ], @@ -217,7 +243,13 @@ class Database extends Element true ); - $output = $total.$graph_area; + $output = html_print_div( + [ + 'content' => $total.$graph_area, + 'id' => 'database-reads', + ], + true + ); return $output; } @@ -230,33 +262,17 @@ class Database extends Element */ public function getWritesGraph():string { - // TODO connect to automonitorization. - $dates = [ - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - ]; - $string_writes = [ - 1, - 0.5, - 2, - 1.5, - 3, - 2.5, - 4, - 3.5, - 5, - 4.5, - 6, - ]; - $total = '9.999.999'; + $dateInit = (time() - 86400); + $writes = $this->valueMonitoring('mysql_questions_writes', $dateInit, time()); + $dates = []; + $string_writes = []; + $total = 0; + foreach ($writes as $key => $write) { + $dates[] = date('d-m-Y H:i:s', $write['utimestamp']); + $string_writes[] = $write['datos']; + $total += $write['datos']; + } + $options = [ 'labels' => $dates, 'legend' => [ 'display' => false ], @@ -301,7 +317,13 @@ class Database extends Element true ); - $output = $total.$graph_area; + $output = html_print_div( + [ + 'content' => $total.$graph_area, + 'id' => 'database-writes', + ], + true + ); return $output; } diff --git a/pandora_console/include/lib/TacticalView/elements/Events.php b/pandora_console/include/lib/TacticalView/elements/Events.php index 6889b11b6d..dd25efa3e2 100644 --- a/pandora_console/include/lib/TacticalView/elements/Events.php +++ b/pandora_console/include/lib/TacticalView/elements/Events.php @@ -36,6 +36,11 @@ class Events extends Element { parent::__construct(); $this->title = __('Events'); + $this->ajaxMethods = [ + 'getEventsGraph', + 'getEventsCriticalityGraph', + 'getEventsStatusValidateGraph', + ]; } @@ -84,7 +89,6 @@ class Events extends Element } $danger = $max_value; - $warning = ($max_value / 2); $ok = ($max_value / 3); foreach ($graph_values as $key => $value) { @@ -92,7 +96,7 @@ class Events extends Element $colors[] = '#EC7176'; } - if ($value['y'] >= $warning && $value['y'] < $danger) { + if ($value['y'] >= $ok && $value['y'] < $danger) { $colors[] = '#FCAB10'; } @@ -120,7 +124,7 @@ class Events extends Element $bar = vbar_graph($graph_values, $options); - return html_print_div( + $output = html_print_div( [ 'content' => $bar, 'class' => 'margin-top-5 w100p relative', @@ -128,6 +132,8 @@ class Events extends Element ], true ); + + return $output; } diff --git a/pandora_console/include/lib/TacticalView/elements/Groups.php b/pandora_console/include/lib/TacticalView/elements/Groups.php index b3aa1f9b6e..ee7ccf0ab6 100644 --- a/pandora_console/include/lib/TacticalView/elements/Groups.php +++ b/pandora_console/include/lib/TacticalView/elements/Groups.php @@ -41,7 +41,11 @@ class Groups extends Element */ public function __construct() { + global $config; parent::__construct(); + include_once $config['homedir'].'/include/functions_users.php'; + include_once 'include/functions_groupview.php'; + ui_require_css_file('heatmap'); $this->title = __('Groups'); $this->total = $this->calculateTotalGroups(); } @@ -54,7 +58,7 @@ class Groups extends Element */ public function calculateTotalGroups():int { - $total = db_get_num_rows('SELECT * FROM tgrupo;'); + $total = db_get_value_sql('SELECT count(*) FROM tgrupo'); return $total; } @@ -66,19 +70,22 @@ class Groups extends Element */ public function getStatusHeatMap():string { - ui_require_css_file('heatmap'); + global $config; + + // ACL Check. + $agent_a = check_acl($config['id_user'], 0, 'AR'); + $agent_w = check_acl($config['id_user'], 0, 'AW'); $width = 350; $height = 275; - $sql = 'SELECT * FROM tagente a - LEFT JOIN tagent_secondary_group g ON g.id_agent = a.id_agente'; - $all_agents = db_get_all_rows_sql($sql); - if (empty($all_agents)) { - return null; - } - - $total_agents = count($all_agents); + $groups_list = groupview_get_groups_list( + $config['id_user'], + ($agent_a == true) ? 'AR' : (($agent_w == true) ? 'AW' : 'AR'), + true + ); + $total_groups = $groups_list['counter']; + $groups = $groups_list['groups']; // Best square. $high = (float) max($width, $height); $low = 0.0; @@ -86,7 +93,7 @@ class Groups extends Element while (abs($high - $low) > 0.000001) { $mid = (($high + $low) / 2.0); $midval = (floor($width / $mid) * floor($height / $mid)); - if ($midval >= $total_agents) { + if ($midval >= $total_groups) { $low = $mid; } else { $high = $mid; @@ -107,38 +114,21 @@ class Groups extends Element $x = 0; $y = 0; $cont = 1; + foreach ($groups as $key => $value) { + if ($value['_name_'] === 'All') { + continue; + } - foreach ($all_agents as $key => $value) { - // Colour by status. - $status = agents_get_status_from_counts($value); - - switch ($status) { - case 5: - // Not init status. - $status = 'notinit'; - break; - - case 1: - // Critical status. - $status = 'critical'; - break; - - case 2: - // Warning status. - $status = 'warning'; - break; - - case 0: - // Normal status. - $status = 'normal'; - break; - - case 3: - case -1: - default: - // Unknown status. - $status = 'unknown'; - break; + if ($value['_monitors_critical_'] > 0) { + $status = 'critical'; + } else if ($value['_monitors_warning_'] > 0) { + $status = 'warning'; + } else if (($value['_monitors_unknown_'] > 0) || ($value['_agents_unknown_'] > 0)) { + $status = 'unknown'; + } else if ($value['_monitors_ok_'] > 0) { + $status = 'normal'; + } else { + $status = 'unknown'; } $heatmap .= sprintf( @@ -175,14 +165,13 @@ class Groups extends Element $heatmap .= ''; + $heatmap .= ''; + $heatmap .= ''; + + return html_print_div( + [ + 'content' => $heatmap, + 'style' => 'margin: 0 auto; width: fit-content; min-height: 285px;', + ], + true + ); + } + + + /** + * Return the status agents in heat map. + * + * @return string + */ + public function getStatusHeatMapAgents():string + { + global $config; + $width = get_parameter('width', 350); + $height = get_parameter('height', 275); + + $id_groups = array_keys(users_get_groups($config['id_user'], 'AR', false)); + + if (in_array(0, $id_groups) === false) { + foreach ($id_groups as $key => $id_group) { + if ((bool) check_acl_restricted_all($config['id_user'], $id_group, 'AR') === false) { + unset($id_groups[$key]); + } + } + } + + $id_groups = implode(',', $id_groups); + + $sql = 'SELECT * FROM tagente a + LEFT JOIN tagent_secondary_group g ON g.id_agent = a.id_agente + WHERE g.id_group IN ('.$id_groups.') OR a.id_grupo IN ('.$id_groups.')'; + $all_agents = db_get_all_rows_sql($sql); + if (empty($all_agents)) { + return null; + } + + $total_agents = count($all_agents); + + // Best square. + $high = (float) max($width, $height); + $low = 0.0; + + while (abs($high - $low) > 0.000001) { + $mid = (($high + $low) / 2.0); + $midval = (floor($width / $mid) * floor($height / $mid)); + if ($midval >= $total_agents) { + $low = $mid; + } else { + $high = $mid; + } + } + + $square_length = min(($width / floor($width / $low)), ($height / floor($height / $low))); + // Print starmap. + $heatmap = sprintf( + '', + $width, + $height + ); + + $heatmap .= ''; + $row = 0; + $column = 0; + $x = 0; + $y = 0; + $cont = 1; + + foreach ($all_agents as $key => $value) { + // Colour by status. + $status = agents_get_status_from_counts($value); + + switch ($status) { + case 5: + // Not init status. + $status = 'notinit'; + break; + + case 1: + // Critical status. + $status = 'critical'; + break; + + case 2: + // Warning status. + $status = 'warning'; + break; + + case 0: + // Normal status. + $status = 'normal'; + break; + + case 3: + case -1: + default: + // Unknown status. + $status = 'unknown'; + break; + } + + $heatmap .= sprintf( + '', + 'rect_'.$cont, + $x, + $y, + $row, + $column, + $square_length, + $square_length, + $status, + random_int(1, 10) + ); + + $y += $square_length; + $row++; + if ((int) ($y + $square_length) > (int) $height) { + $y = 0; + $x += $square_length; + $row = 0; + $column++; + } + + if ((int) ($x + $square_length) > (int) $width) { + $x = 0; + $y += $square_length; + $column = 0; + $row++; + } + + $cont++; + } + + $heatmap .= ''; + $heatmap .= ''; + $heatmap .= ''; + + return html_print_div( + [ + 'content' => $heatmap, + 'style' => 'margin: 0 auto; width: fit-content; min-height: 285px;', + ], + true + ); + } + + + /** + * Return the status groups in heat map. + * + * @return string + */ + public function getStatusHeatMapGroup():string { global $config; $width = get_parameter('width', 350); diff --git a/pandora_console/include/lib/TacticalView/elements/LogStorage.php b/pandora_console/include/lib/TacticalView/elements/LogStorage.php index 6f535271da..27e8b61fbb 100644 --- a/pandora_console/include/lib/TacticalView/elements/LogStorage.php +++ b/pandora_console/include/lib/TacticalView/elements/LogStorage.php @@ -71,15 +71,11 @@ class LogStorage extends Element */ public function isEnabled():bool { - if (empty($this->monitoringAgent) === true) { - return false; - } - - $existModule = modules_get_agentmodule_id(io_safe_input('Log server connection'), $this->monitoringAgent['id_agente']); - if ($existModule === false) { - return false; - } else { + global $config; + if ((bool) $config['log_collector'] === true) { return true; + } else { + return false; } } @@ -91,9 +87,30 @@ class LogStorage extends Element */ public function getStatus():string { - $value = $this->valueMonitoring('Log server connection'); - $status = ((int) $value[0]['datos'] === 1) ? true : false; - if ($status === true) { + $classDisabled = ''; + if ($this->isEnabled() === true) { + $value = $this->valueMonitoring('Log server connection'); + $status = ((int) $value[0]['datos'] === 1) ? true : false; + if ($status === true) { + $image_status = html_print_image('images/status_check@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Everything’s OK!'), + 'class' => 'status-text', + ], + true + ); + } else { + $image_status = html_print_image('images/status_error@svg.svg', true); + $text = html_print_div( + [ + 'content' => __('Something’s wrong'), + 'class' => 'status-text', + ], + true + ); + } + } else { $image_status = html_print_image('images/status_check@svg.svg', true); $text = html_print_div( [ @@ -102,15 +119,7 @@ class LogStorage extends Element ], true ); - } else { - $image_status = html_print_image('images/status_error@svg.svg', true); - $text = html_print_div( - [ - 'content' => __('Something’s wrong'), - 'class' => 'status-text', - ], - true - ); + $classDisabled = 'alpha50'; } $output = $image_status.$text; @@ -118,7 +127,7 @@ class LogStorage extends Element return html_print_div( [ 'content' => $output, - 'class' => 'flex_center margin-top-5', + 'class' => 'flex_center margin-top-5 '.$classDisabled, 'style' => 'margin: 0px 10px 10px 10px;', 'id' => 'status-log-storage', ], @@ -134,8 +143,13 @@ class LogStorage extends Element */ public function getTotalSources():string { - $data = $this->valueMonitoring('Total sources'); - $value = round($data[0]['datos']); + if ($this->isEnabled() === true) { + $data = $this->valueMonitoring('Total sources'); + $value = round($data[0]['datos']); + } else { + $value = __('N/A'); + } + return html_print_div( [ 'content' => $value, @@ -155,8 +169,13 @@ class LogStorage extends Element */ public function getStoredData():string { - $data = $this->valueMonitoring('Total lines of data'); - $value = round($data[0]['datos']); + if ($this->isEnabled() === true) { + $data = $this->valueMonitoring('Total lines of data'); + $value = round($data[0]['datos']); + } else { + $value = __('N/A'); + } + return html_print_div( [ 'content' => $value, diff --git a/pandora_console/include/lib/TacticalView/elements/Overview.php b/pandora_console/include/lib/TacticalView/elements/Overview.php index 79b5eceb26..706e6db321 100644 --- a/pandora_console/include/lib/TacticalView/elements/Overview.php +++ b/pandora_console/include/lib/TacticalView/elements/Overview.php @@ -34,46 +34,31 @@ class Overview extends Element */ public function __construct() { + global $config; parent::__construct(); + if (is_ajax() === true) { + include_once $config['homedir'].'/include/functions_servers.php'; + } + $this->title = __('General overview'); $this->ajaxMethods = [ 'getLogSizeStatus', - 'getWuxServerStatus', + 'getServerStatus', ]; $this->interval = 300000; $this->refreshConfig = [ - 'logSizeStatus' => [ + 'logSizeStatus' => [ 'id' => 'status-log-size', 'method' => 'getLogSizeStatus', ], - 'wuxServerStatus' => [ - 'id' => 'status-wux', - 'method' => 'getWuxServerStatus', + 'ServerStatus' => [ + 'id' => 'status-servers', + 'method' => 'getServerStatus', ], ]; } - /** - * Check if module WUX connection exist. - * - * @return boolean - */ - public function wuxIsEnabled():bool - { - if (empty($this->monitoringAgent) === true) { - return false; - } - - $existModule = modules_get_agentmodule_id(io_safe_input('WUX connection'), $this->monitoringAgent['id_agente']); - if ($existModule === false) { - return false; - } else { - return true; - } - } - - /** * Return the html log size status. * @@ -106,11 +91,10 @@ class Overview extends Element $output = $image_status.$text; - $align = ($this->wuxIsEnabled() === true) ? 'flex_center' : 'flex_justify'; return html_print_div( [ 'content' => $output, - 'class' => 'margin-top-5 '.$align, + 'class' => 'margin-top-5 flex_center', 'id' => 'status-log-size', ], true @@ -120,14 +104,13 @@ class Overview extends Element /** - * Return the html Wix server status. + * Return the html Servers status. * * @return string */ - public function getWuxServerStatus():string + public function getServerStatus():string { - $wux = $this->valueMonitoring('WUX connection'); - $status = ($wux[0]['datos'] > 0) ? true : false; + $status = check_all_servers_up(); if ($status === true) { $image_status = html_print_image('images/status_check@svg.svg', true); @@ -155,7 +138,7 @@ class Overview extends Element [ 'content' => $output, 'class' => 'flex_center margin-top-5', - 'id' => 'status-wux', + 'id' => 'status-servers', ], true ); diff --git a/pandora_console/include/lib/TacticalView/elements/ScheduledDowntime.php b/pandora_console/include/lib/TacticalView/elements/ScheduledDowntime.php index d3bbf54c56..5bbede28b7 100644 --- a/pandora_console/include/lib/TacticalView/elements/ScheduledDowntime.php +++ b/pandora_console/include/lib/TacticalView/elements/ScheduledDowntime.php @@ -248,4 +248,22 @@ class ScheduledDowntime extends Element } + /** + * Check permission acl for this section. + * + * @return boolean + */ + public function checkAcl():bool + { + global $config; + $read_permisson = (bool) check_acl($config['id_user'], 0, 'AR'); + $manage_permisson = (bool) check_acl($config['id_user'], 0, 'AW'); + if ($read_permisson === true && $manage_permisson === true) { + return true; + } else { + return false; + } + } + + } diff --git a/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php b/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php index 7783a5277b..f606893429 100644 --- a/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php +++ b/pandora_console/include/lib/TacticalView/elements/SnmpTraps.php @@ -81,8 +81,13 @@ class SnmpTraps extends Element */ public function getQueues():string { - $value = $this->valueMonitoring('snmp_trap_queue'); - $total = round($value[0]['data']); + if ($this->isEnabled() === true) { + $value = $this->valueMonitoring('snmp_trap_queue'); + $total = round($value[0]['data']); + } else { + $total = __('N/A'); + } + return html_print_div( [ 'content' => $total, @@ -102,8 +107,13 @@ class SnmpTraps extends Element */ public function getTotalSources():string { - $value = $this->valueMonitoring('total_trap'); - $total = round($value[0]['data']); + if ($this->isEnabled() === true) { + $value = $this->valueMonitoring('total_trap'); + $total = round($value[0]['data']); + } else { + $total = __('N/A'); + } + return html_print_div( [ 'content' => $total, diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php index 17b73d360b..8472f2f236 100644 --- a/pandora_console/views/tacticalView/view.php +++ b/pandora_console/views/tacticalView/view.php @@ -14,24 +14,22 @@
-
-
+
+
getLogSizeStatus(); ?>
- wuxIsEnabled() === true) : ?> -
-
- - - - getWuxServerStatus(); ?> -
+
+
+ + + + getServerStatus(); ?>
- +
@@ -53,7 +51,7 @@
-
+
title; ?> @@ -91,7 +89,6 @@
- checkAcl() === true) : ?>
@@ -140,9 +137,7 @@
-
-
@@ -153,83 +148,75 @@ getNews(); ?>
- total < 200) : ?> -
-
-
- title; ?> +
+
+
+ title; ?> +
+ +
+ loading(); ?> +
+
+
+
+
+
+ title; ?> +
+
+
+
+ +
+ getStatus(); ?>
- - - isEnabled() === true && $SnmpTraps->isEnabled() === true) : ?> -
- isEnabled() === true) : ?> -
-
- title; ?> -
-
-
-
- -
- getStatus(); ?> -
-
-
- -
- getTotalSources(); ?> -
-
-
-
-
- -
- getStoredData(); ?> - -
-
-
- -
- getAgeOfStoredData(); ?> - -
+
+
+ title; ?> +
+
+
+
+
+ getQueues(); ?>
- - isEnabled() === true) : ?> -
-
- title; ?> -
-
-
-
- -
- getQueues(); ?> -
-
-
- -
- getTotalSources(); ?> -
+
+
+
+ getTotalSources(); ?>
- +
- +
@@ -249,9 +236,9 @@
- +
- getActiveCorrelation(); ?> + getActiveAlerts(); ?>
checkAclUserList() === true) : ?> @@ -265,47 +252,47 @@
checkAcl() === true) : ?> -
-
-
- title; ?> -
-
-
- -
loading(); ?>
-
-
- -
loading(); ?>
-
-
- -
loading(); ?>
-
-
- -
loading(); ?>
-
-
+
+
+
+ title; ?>
-
-
-
@@ -368,7 +355,7 @@ getTotalRemotePlugins(); ?>
-
+
getTotalModuleTemplate(); ?>
@@ -380,12 +367,14 @@
-
-
- title; ?> + checkAcl() === true) : ?> +
+
+ title; ?> +
+ list(); ?>
- list(); ?> -
+
Date: Mon, 9 Oct 2023 19:04:01 +0200 Subject: [PATCH 13/22] #10194 new graph for license and changes in design --- .../javascript/general_tactical_view.js | 5 +- .../lib/TacticalView/elements/Database.php | 5 +- .../lib/TacticalView/elements/Events.php | 2 + .../lib/TacticalView/elements/Groups.php | 4 +- .../lib/TacticalView/elements/Overview.php | 105 +++++++++++++----- .../include/styles/general_tactical_view.css | 58 ++++++++++ pandora_console/views/tacticalView/view.php | 24 ++-- 7 files changed, 158 insertions(+), 45 deletions(-) diff --git a/pandora_console/include/javascript/general_tactical_view.js b/pandora_console/include/javascript/general_tactical_view.js index c3d48b133b..817315db50 100644 --- a/pandora_console/include/javascript/general_tactical_view.js +++ b/pandora_console/include/javascript/general_tactical_view.js @@ -64,7 +64,10 @@ $(document).ready(function() { }, type: "POST", success: function(data) { - $("#heatmap-group").html(data); + var title = $(data)[1]; + var heatmap = $(data)[0]; + $("#heatmap-group").html(heatmap); + $("#heatmap-title").html($(title).html()); } }); }); diff --git a/pandora_console/include/lib/TacticalView/elements/Database.php b/pandora_console/include/lib/TacticalView/elements/Database.php index 7d46d29cb1..ef5925162b 100644 --- a/pandora_console/include/lib/TacticalView/elements/Database.php +++ b/pandora_console/include/lib/TacticalView/elements/Database.php @@ -147,10 +147,11 @@ class Database extends Element */ public function getEvents():string { - // TODO connect to automonitorization. + $data = $this->valueMonitoring('last_events_24h'); + $value = round($data[0]['datos']); return html_print_div( [ - 'content' => '9.999.999', + 'content' => $value, 'class' => 'text-l', 'id' => 'total-events', 'style' => 'margin: 0px 10px 10px 10px;', diff --git a/pandora_console/include/lib/TacticalView/elements/Events.php b/pandora_console/include/lib/TacticalView/elements/Events.php index 2e20aaa4c0..b304e59300 100644 --- a/pandora_console/include/lib/TacticalView/elements/Events.php +++ b/pandora_console/include/lib/TacticalView/elements/Events.php @@ -103,6 +103,8 @@ class Events extends Element ]; } + $graph_values = array_slice($graph_values, -24); + $danger = $max_value; $ok = ($max_value / 3); diff --git a/pandora_console/include/lib/TacticalView/elements/Groups.php b/pandora_console/include/lib/TacticalView/elements/Groups.php index 016700ef92..82b0f358b1 100644 --- a/pandora_console/include/lib/TacticalView/elements/Groups.php +++ b/pandora_console/include/lib/TacticalView/elements/Groups.php @@ -81,11 +81,11 @@ class Groups extends Element $agents = agents_get_agents(); if (is_array($agents) === true && count($agents) >= 10) { $this->title = __('My monitored agents'); - return $this->getStatusHeatMapAgents(); + return $this->getStatusHeatMapAgents().''.$this->title.''; } $this->title = __('My monitored modules'); - return $this->getStatusHeatMapModules(); + return $this->getStatusHeatMapModules().''.$this->title.''; } diff --git a/pandora_console/include/lib/TacticalView/elements/Overview.php b/pandora_console/include/lib/TacticalView/elements/Overview.php index 706e6db321..01e4a67a49 100644 --- a/pandora_console/include/lib/TacticalView/elements/Overview.php +++ b/pandora_console/include/lib/TacticalView/elements/Overview.php @@ -153,27 +153,25 @@ class Overview extends Element */ public function getLicenseUsageGraph():string { - // TODO connect to automonitorization. - $options = [ - 'labels' => [ - 'Agents used', - 'Free agents', + // TODO: show real data. + $data = [ + 'free_agents' => [ + 'label' => __('Free agents'), + 'perc' => 40, + 'color' => '#5C63A2', ], - 'colors' => [ - '#1C4E6B', - '#5C63A2', + 'agents_used' => [ + 'label' => __('Agents used'), + 'perc' => 60, + 'color' => '#1C4E6B', ], - 'legend' => [ - 'position' => 'bottom', - 'align' => 'right', - ], - 'cutout' => 80, ]; - $pie = ring_graph([60, 40], $options); + + $bar = $this->printHorizontalBar($data); $output = html_print_div( [ - 'content' => $pie, - 'style' => 'margin: 0 auto; max-width: 320px', + 'content' => $bar, + 'style' => 'margin: 0 auto;', ], true ); @@ -183,11 +181,60 @@ class Overview extends Element /** - * Returns the html of a graph with the processed xmls + * Print horizontal bar divided by percentage. + * + * @param array $data Required [perc, color, label]. * * @return string */ - public function getXmlProcessedGraph():string + private function printHorizontalBar(array $data):string + { + $output = '
'; + $output .= '
'; + foreach ($data as $key => $value) { + $output .= html_print_div( + [ + 'content' => '
'.$value['label'], + 'class' => 'label', + ], + true + ); + } + + $output .= '
'; + $output .= '
'; + foreach ($data as $key => $value) { + $output .= html_print_div( + [ + 'content' => $value['perc'].' %', + 'style' => 'width: '.$value['perc'].'%; background-color: '.$value['color'].';', + ], + true + ); + } + + $output .= '
'; + $output .= ' +
+
0 %
+
20 %
+
40 %
+
60 %
+
80 %
+
100 %
+
'; + $output .= '
'; + + return $output; + } + + + /** + * Returns the html of a graph with the cpu load. + * + * @return string + */ + public function getCPULoadGraph():string { $sql = 'SELECT utimestamp, @@ -199,14 +246,13 @@ class Overview extends Element ORDER BY hour;'; $rows = db_process_sql($sql); - + $data_last24h = $this->valueMonitoring('CPU Load', (time() - 86400), time()); $dates = []; - $xml_proccessed = []; + $cpu_load = []; $total = 0; - foreach ($rows as $key => $raw_data) { - $dates[] = date('H:00:00', $raw_data['utimestamp']); - $total += $raw_data['xml_proccessed']; - $xml_proccessed[] = $raw_data['xml_proccessed']; + foreach ($data_last24h as $key => $raw_data) { + $dates[] = date('H:m:s', $raw_data['utimestamp']); + $cpu_load[] = $raw_data['datos']; } $options = [ @@ -215,8 +261,9 @@ class Overview extends Element 'tooltips' => [ 'display' => false ], 'scales' => [ 'y' => [ - 'grid' => ['display' => false], - 'ticks' => ['display' => false], + 'grid' => ['display' => false], + 'ticks' => ['display' => false], + 'display' => false, ], 'x' => [ 'grid' => ['display' => false], @@ -231,7 +278,7 @@ class Overview extends Element 'borderColor' => '#009D9E', 'pointBackgroundColor' => '#009D9E', 'pointHoverBorderColor' => '#009D9E', - 'data' => $xml_proccessed, + 'data' => $cpu_load, ], ]; @@ -239,7 +286,7 @@ class Overview extends Element [ 'content' => line_graph($data, $options), 'class' => 'margin-top-5 w100p h100p', - 'style' => 'max-height: 330px;', + 'style' => 'max-height: 50px;', ], true ); @@ -252,7 +299,7 @@ class Overview extends Element true ); - $output = $total.$graph_area; + $output = $graph_area; return $output; } diff --git a/pandora_console/include/styles/general_tactical_view.css b/pandora_console/include/styles/general_tactical_view.css index ff76053f69..3763ef1bd9 100644 --- a/pandora_console/include/styles/general_tactical_view.css +++ b/pandora_console/include/styles/general_tactical_view.css @@ -131,6 +131,64 @@ padding: 10px 10px 5px 10px; } +#Agents > .row { + min-height: 550px; +} +#horizontalBar { + padding: 0px 20px; + position: relative; +} +#horizontalBar .bar { + display: flex; + color: white; + height: 43px; +} + +#horizontalBar .bar div { + display: flex; + align-items: center; + justify-content: center; + z-index: 1; +} + +.marks { + display: flex; + justify-content: space-between; + margin-top: 20px; +} +.marks .line { + height: 76px; + background: #00000033; + width: 1px; + position: absolute; + top: 24px; + margin-left: 11px; +} +.mark:nth-child(1) .line { + margin-left: 0px; +} + +.mark:nth-last-child(1) .line { + margin-left: 31px; +} + +.labels { + display: flex; + margin-bottom: 19px; +} +.label { + display: flex; + justify-content: center; + align-items: center; + margin-right: 10px; +} +.label div { + width: 10px; + height: 10px; + border-radius: 2px; + margin-right: 3px; +} + .indicative-text { color: #6e7079; font-size: 12px; diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php index 8472f2f236..b1b37d3d46 100644 --- a/pandora_console/views/tacticalView/view.php +++ b/pandora_console/views/tacticalView/view.php @@ -12,9 +12,9 @@
-
+
-
+
@@ -22,7 +22,7 @@ getLogSizeStatus(); ?>
-
+
@@ -30,6 +30,14 @@ getServerStatus(); ?>
+
+
+ + + + getCPULoadGraph(); ?> +
+
@@ -40,12 +48,6 @@
-
- - getXmlProcessedGraph(); ?> -
@@ -150,7 +152,7 @@
-
+
title; ?>
-
+
title; ?>
From a02482ac5d26de3637e8b06314b5b6c7d499e2dd Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Tue, 10 Oct 2023 15:15:43 +0200 Subject: [PATCH 14/22] #10194 added links --- .../javascript/general_tactical_view.js | 2 +- .../TacticalView/elements/Configurations.php | 4 +- .../lib/TacticalView/elements/Events.php | 82 +++++++++++++ .../lib/TacticalView/elements/LogStorage.php | 4 +- .../lib/TacticalView/elements/Overview.php | 109 ++++++++++++------ .../include/styles/general_tactical_view.css | 49 ++++++-- pandora_console/operation/events/events.php | 16 ++- pandora_console/views/tacticalView/view.php | 80 ++++++------- 8 files changed, 251 insertions(+), 95 deletions(-) diff --git a/pandora_console/include/javascript/general_tactical_view.js b/pandora_console/include/javascript/general_tactical_view.js index 817315db50..25e5c5af7f 100644 --- a/pandora_console/include/javascript/general_tactical_view.js +++ b/pandora_console/include/javascript/general_tactical_view.js @@ -30,7 +30,7 @@ $(document).ready(function() { url: "ajax.php", data: { page: "include/ajax/general_tactical_view.ajax", - method: "getEventsStatusValidateGraph", + method: "getEventsStatusGraph", class: "Events" }, type: "POST", diff --git a/pandora_console/include/lib/TacticalView/elements/Configurations.php b/pandora_console/include/lib/TacticalView/elements/Configurations.php index 51b9dcd6b5..614d5bbadd 100644 --- a/pandora_console/include/lib/TacticalView/elements/Configurations.php +++ b/pandora_console/include/lib/TacticalView/elements/Configurations.php @@ -208,8 +208,8 @@ class Configurations extends Element */ public function getTotalUnknowAgents():string { - $value = $this->valueMonitoring('total_notinit'); - $total = round($value[0]['total_unknown']); + $value = $this->valueMonitoring('total_unknown'); + $total = round($value[0]['datos']); $image = html_print_image('images/Tactical_Unknown_agent.svg', true); $text = ''.__('Unknown agents').''; $number = html_print_div( diff --git a/pandora_console/include/lib/TacticalView/elements/Events.php b/pandora_console/include/lib/TacticalView/elements/Events.php index b304e59300..b83e56f8fd 100644 --- a/pandora_console/include/lib/TacticalView/elements/Events.php +++ b/pandora_console/include/lib/TacticalView/elements/Events.php @@ -40,6 +40,7 @@ class Events extends Element 'getEventsGraph', 'getEventsCriticalityGraph', 'getEventsStatusValidateGraph', + 'getEventsStatusGraph', ]; } @@ -333,6 +334,86 @@ class Events extends Element } + /** + * Return the html graph of events in last 8h grouped by status. + * + * @return string + */ + public function getEventsStatusGraph():string + { + global $config; + $id_groups = array_keys(users_get_groups($config['id_user'], 'AR', false)); + if (in_array(0, $id_groups) === false) { + foreach ($id_groups as $key => $id_group) { + if ((bool) check_acl_restricted_all($config['id_user'], $id_group, 'AR') === false) { + unset($id_groups[$key]); + } + } + } + + if (users_can_manage_group_all() === true) { + $id_groups[] = 0; + } + + $id_groups = implode(',', $id_groups); + $interval8h = (time() - 86400); + $sql = 'SELECT criticity, count(*) AS total + FROM tevento + WHERE utimestamp >= '.$interval8h.' AND id_grupo IN ('.$id_groups.') + group by criticity'; + + $rows = db_process_sql($sql); + + $labels = []; + $data = []; + $colors = []; + foreach ($rows as $key => $row) { + switch ($row['criticity']) { + case EVENT_CRIT_CRITICAL: + $label = __('CRITICAL'); + $colors[] = COL_CRITICAL; + break; + + case EVENT_CRIT_NORMAL: + $label = __('NORMAL'); + $colors[] = COL_NORMAL; + break; + + case EVENT_CRIT_WARNING: + $label = __('WARNING'); + $colors[] = COL_WARNING; + break; + + default: + $colors[] = COL_UNKNOWN; + $label = __('UNKNOWN'); + break; + } + + $labels[] = $this->controlSizeText($label); + $data[] = $row['total']; + } + + $options = [ + 'labels' => $labels, + 'legend' => ['display' => false], + 'cutout' => 80, + 'nodata_image' => ['width' => '100%'], + 'colors' => $colors, + ]; + $pie = ring_graph($data, $options); + $output = html_print_div( + [ + 'content' => $pie, + 'style' => 'margin: 0 auto; max-width: 80%; max-height: 220px;', + ], + true + ); + + return $output; + } + + /** * Return the datatable events in last 8 hours. * @@ -360,6 +441,7 @@ class Events extends Element 'ajax_data' => [ 'get_events' => 1, 'compact_date' => 1, + 'external_url' => 1, ], 'order' => [ 'field' => 'timestamp', diff --git a/pandora_console/include/lib/TacticalView/elements/LogStorage.php b/pandora_console/include/lib/TacticalView/elements/LogStorage.php index 27e8b61fbb..fbf950024f 100644 --- a/pandora_console/include/lib/TacticalView/elements/LogStorage.php +++ b/pandora_console/include/lib/TacticalView/elements/LogStorage.php @@ -197,11 +197,11 @@ class LogStorage extends Element { $data = $this->valueMonitoring('Longest data archived'); $date = $data[0]['datos']; - if ($date > 0) { + if ($date > 0 && $this->isEnabled() === true) { $interval = (time() - strtotime($date)); $days = round($interval / 86400); } else { - $days = '-'; + $days = 'N/A'; } return html_print_div( diff --git a/pandora_console/include/lib/TacticalView/elements/Overview.php b/pandora_console/include/lib/TacticalView/elements/Overview.php index 01e4a67a49..af1a7ab2ae 100644 --- a/pandora_console/include/lib/TacticalView/elements/Overview.php +++ b/pandora_console/include/lib/TacticalView/elements/Overview.php @@ -44,6 +44,7 @@ class Overview extends Element $this->ajaxMethods = [ 'getLogSizeStatus', 'getServerStatus', + 'getCPULoadGraph', ]; $this->interval = 300000; $this->refreshConfig = [ @@ -55,6 +56,10 @@ class Overview extends Element 'id' => 'status-servers', 'method' => 'getServerStatus', ], + 'cpuStatus' => [ + 'id' => 'status-cpu', + 'method' => 'getCPULoadGraph', + ], ]; } @@ -153,19 +158,65 @@ class Overview extends Element */ public function getLicenseUsageGraph():string { - // TODO: show real data. - $data = [ - 'free_agents' => [ - 'label' => __('Free agents'), - 'perc' => 40, - 'color' => '#5C63A2', - ], - 'agents_used' => [ - 'label' => __('Agents used'), - 'perc' => 60, - 'color' => '#1C4E6B', - ], - ]; + if (enterprise_installed() === true) { + $info = license_get_info(); + if ($info['limit'] > $info['count']) { + $used = round(($info['count'] / $info['limit']) * 100); + $free = (100 - $used); + } else { + $free = 100; + $used = 0; + } + + $data = [ + 'agents_used' => [ + 'label' => __('% Agents used'), + 'perc' => $used, + 'color' => '#1C4E6B', + ], + 'free_agents' => [ + 'label' => __('% Free agents'), + 'perc' => $free, + 'color' => '#5C63A2', + ], + ]; + } else { + $agents = agents_get_agents(); + $enabled_agents = agents_get_agents( + false, + false, + 'AR', + [ + 'field' => 'nombre', + 'order' => 'ASC', + ], + false, + 1 + ); + if (is_array($agents) === true) { + $total = count($agents); + } else { + $total = 0; + } + + if ($total > 0 && is_array($enabled_agents) === true) { + $total_disabled_agents = round((($total - count($enabled_agents)) * 100) / $total); + $total_enabled_agents = round((count($enabled_agents) * 100) / $total); + } + + $data = [ + 'agents_enabled' => [ + 'label' => __('% Agents enabled'), + 'perc' => $total_enabled_agents, + 'color' => '#1C4E6B', + ], + 'agents_disabled' => [ + 'label' => __('% Agents disabled'), + 'perc' => $total_disabled_agents, + 'color' => '#5C63A2', + ], + ]; + } $bar = $this->printHorizontalBar($data); $output = html_print_div( @@ -216,12 +267,12 @@ class Overview extends Element $output .= '
'; $output .= '
-
0 %
-
20 %
-
40 %
-
60 %
-
80 %
-
100 %
+
0 %
+
20 %
+
40 %
+
60 %
+
80 %
+
100 %
'; $output .= '
'; @@ -236,20 +287,9 @@ class Overview extends Element */ public function getCPULoadGraph():string { - $sql = 'SELECT - utimestamp, - DATE_FORMAT(FROM_UNIXTIME(utimestamp), "%Y-%m-%d %H:00:00") AS hour, - COUNT(*) AS xml_proccessed - FROM tagent_access - WHERE FROM_UNIXTIME(utimestamp) >= NOW() - INTERVAL 24 HOUR - GROUP BY hour - ORDER BY hour;'; - - $rows = db_process_sql($sql); $data_last24h = $this->valueMonitoring('CPU Load', (time() - 86400), time()); $dates = []; $cpu_load = []; - $total = 0; foreach ($data_last24h as $key => $raw_data) { $dates[] = date('H:m:s', $raw_data['utimestamp']); $cpu_load[] = $raw_data['datos']; @@ -287,14 +327,7 @@ class Overview extends Element 'content' => line_graph($data, $options), 'class' => 'margin-top-5 w100p h100p', 'style' => 'max-height: 50px;', - ], - true - ); - - $total = html_print_div( - [ - 'content' => $total, - 'class' => 'text-xl', + 'id' => 'status-cpu', ], true ); diff --git a/pandora_console/include/styles/general_tactical_view.css b/pandora_console/include/styles/general_tactical_view.css index 3763ef1bd9..b758fd7738 100644 --- a/pandora_console/include/styles/general_tactical_view.css +++ b/pandora_console/include/styles/general_tactical_view.css @@ -135,13 +135,14 @@ min-height: 550px; } #horizontalBar { - padding: 0px 20px; + margin: 0px 20px; position: relative; } #horizontalBar .bar { display: flex; color: white; height: 43px; + justify-content: space-between; } #horizontalBar .bar div { @@ -153,7 +154,6 @@ .marks { display: flex; - justify-content: space-between; margin-top: 20px; } .marks .line { @@ -162,14 +162,49 @@ width: 1px; position: absolute; top: 24px; - margin-left: 11px; } -.mark:nth-child(1) .line { - margin-left: 0px; +.mark { + min-height: 30px; +} +.mark .number { + position: absolute; +} +.mark0 { + left: 0%; +} +.mark20 { + left: 20%; +} +.mark40 { + left: 40%; +} +.mark60 { + left: 60%; +} +.mark80 { + left: 80%; +} +.mark100 { + left: 100%; +} +.number20 { + left: 19%; +} +.number40 { + left: 39%; +} +.number60 { + left: 59%; +} +.number80 { + left: 79%; +} +.number100 { + left: 95%; } -.mark:nth-last-child(1) .line { - margin-left: 31px; +.mark:nth-child(1) { + text-align: left; } .labels { diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php index 944b7f12b4..3a391338ed 100644 --- a/pandora_console/operation/events/events.php +++ b/pandora_console/operation/events/events.php @@ -338,6 +338,7 @@ if (is_metaconsole() === true // Ajax responses. if (is_ajax() === true) { $get_events = (int) get_parameter('get_events', 0); + $external_url = (bool) get_parameter('external_url', 0); $table_id = get_parameter('table_id', ''); $groupRecursion = (bool) get_parameter('groupRecursion', false); $compact_date = (int) get_parameter('compact_date', 0); @@ -472,7 +473,7 @@ if (is_ajax() === true) { $data = array_reduce( $events, - function ($carry, $item) use ($table_id, &$redirection_form_id, $filter, $compact_date) { + function ($carry, $item) use ($table_id, &$redirection_form_id, $filter, $compact_date, $external_url) { global $config; $tmp = (object) $item; @@ -743,8 +744,13 @@ if (is_ajax() === true) { $criticity .= $color.'" data-title="'.$text.'" data-use_title_for_force_title="1">'.$text.'
'; $tmp->criticity = $criticity; - // Add event severity to end of text. - $evn = ''; + if (isset($external_url) === true && $external_url === true) { + $url = ui_get_full_url('index.php?sec=eventos&sec2=operation/events/events'); + $evn = ''; + } else { + // Add event severity to end of text. + $evn = ''; + } // Grouped events. if ((int) $filter['group_rep'] === EVENT_GROUP_REP_EXTRAIDS) { @@ -3588,7 +3594,7 @@ function show_event_dialo(event, dialog_page) { // History mode flag var history = $("#hidden-history").val(); - + console.log(event); jQuery.post( ajax_file, { @@ -3606,7 +3612,7 @@ function show_event_dialo(event, dialog_page) { .empty() .append(data) .dialog({ - title: event.evento, + title: event.event_title, resizable: true, draggable: true, modal: true, diff --git a/pandora_console/views/tacticalView/view.php b/pandora_console/views/tacticalView/view.php index b1b37d3d46..e6e5be13a7 100644 --- a/pandora_console/views/tacticalView/view.php +++ b/pandora_console/views/tacticalView/view.php @@ -41,8 +41,8 @@
- - + + getLicenseUsageGraph(); ?>
@@ -52,7 +52,7 @@
-
+
@@ -62,13 +62,13 @@
getTagsGraph(); ?>
getModuleGroupGraph(); ?>
@@ -76,13 +76,13 @@
getMonitoringStatusGraph(); ?>
getAgentGroupsGraph(); ?>
@@ -126,14 +126,14 @@
-
- @@ -156,7 +156,7 @@ title; ?>
loading(); ?> @@ -246,7 +246,7 @@ checkAclUserList() === true) : ?>
getDataTableUsers(); ?>
@@ -262,25 +262,25 @@
loading(); ?>
-
-
- @@ -288,7 +288,7 @@
getDataTableEvents(); ?>
@@ -321,17 +321,17 @@
getDataTableGroups(); ?>
checkAcl() === true) : ?> From e3e7328a01cbfbd691fffddd1ba53f24d0b45d23 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Tue, 10 Oct 2023 15:51:48 +0200 Subject: [PATCH 15/22] #10194 change in graph --- pandora_console/include/graphs/fgraph.php | 6 ++++++ .../include/lib/TacticalView/elements/Alerts.php | 1 + .../include/lib/TacticalView/elements/Database.php | 2 ++ .../include/lib/TacticalView/elements/Overview.php | 1 + pandora_console/include/styles/general_tactical_view.css | 3 ++- 5 files changed, 12 insertions(+), 1 deletion(-) diff --git a/pandora_console/include/graphs/fgraph.php b/pandora_console/include/graphs/fgraph.php index 889a08ef45..5e5818357b 100644 --- a/pandora_console/include/graphs/fgraph.php +++ b/pandora_console/include/graphs/fgraph.php @@ -725,6 +725,12 @@ function get_build_setup_charts($type, $options, $data) $chart->options()->getElements()->center()->setColor($options['elements']['center']['color']); } } + + if (isset($options['elements']['point']) === true) { + if (isset($options['elements']['point']['radius']) === true) { + $chart->options()->getElements()->point()->setRadius($options['elements']['point']['radius']); + } + } } // Set Responsive for responsive charts. diff --git a/pandora_console/include/lib/TacticalView/elements/Alerts.php b/pandora_console/include/lib/TacticalView/elements/Alerts.php index a5788fff33..1de2d0fca0 100644 --- a/pandora_console/include/lib/TacticalView/elements/Alerts.php +++ b/pandora_console/include/lib/TacticalView/elements/Alerts.php @@ -205,6 +205,7 @@ class Alerts extends Element $rows = db_process_sql($sql); foreach ($rows as $key => $row) { + $rows[$key]['id_user'] = ''.$row['id_user'].''; if ((bool) $row['is_admin'] === true) { $rows[$key]['is_admin'] = ''.__('Admin').''; } else { diff --git a/pandora_console/include/lib/TacticalView/elements/Database.php b/pandora_console/include/lib/TacticalView/elements/Database.php index ef5925162b..2330396904 100644 --- a/pandora_console/include/lib/TacticalView/elements/Database.php +++ b/pandora_console/include/lib/TacticalView/elements/Database.php @@ -215,6 +215,7 @@ class Database extends Element 'display' => false, ], ], + 'elements' => [ 'point' => [ 'radius' => 0 ] ], ]; $data = [ @@ -289,6 +290,7 @@ class Database extends Element 'display' => false, ], ], + 'elements' => [ 'point' => [ 'radius' => 0 ] ], ]; $data = [ diff --git a/pandora_console/include/lib/TacticalView/elements/Overview.php b/pandora_console/include/lib/TacticalView/elements/Overview.php index af1a7ab2ae..b29ece1e65 100644 --- a/pandora_console/include/lib/TacticalView/elements/Overview.php +++ b/pandora_console/include/lib/TacticalView/elements/Overview.php @@ -310,6 +310,7 @@ class Overview extends Element 'display' => false, ], ], + 'elements' => [ 'point' => [ 'radius' => 0 ] ], ]; $data = [ diff --git a/pandora_console/include/styles/general_tactical_view.css b/pandora_console/include/styles/general_tactical_view.css index b758fd7738..476ca981bb 100644 --- a/pandora_console/include/styles/general_tactical_view.css +++ b/pandora_console/include/styles/general_tactical_view.css @@ -81,7 +81,8 @@ .subtitle { font-size: 13px; color: #161628; - padding-bottom: 10px; + padding-bottom: 5px; + padding-top: 5px; } .subtitle.link { display: flex; From 45629983527001a4e17deaaac2d1b0e84bb4922f Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Tue, 10 Oct 2023 16:27:50 +0200 Subject: [PATCH 16/22] #10194 control empty value in license graph --- pandora_console/include/lib/TacticalView/elements/Overview.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandora_console/include/lib/TacticalView/elements/Overview.php b/pandora_console/include/lib/TacticalView/elements/Overview.php index b29ece1e65..bc07b7f832 100644 --- a/pandora_console/include/lib/TacticalView/elements/Overview.php +++ b/pandora_console/include/lib/TacticalView/elements/Overview.php @@ -202,6 +202,9 @@ class Overview extends Element if ($total > 0 && is_array($enabled_agents) === true) { $total_disabled_agents = round((($total - count($enabled_agents)) * 100) / $total); $total_enabled_agents = round((count($enabled_agents) * 100) / $total); + } else { + $total_disabled_agents = 0; + $total_enabled_agents = 100; } $data = [ From d54a6faede0b8d818a5c3b18339dee4bed55b39d Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Mon, 16 Oct 2023 20:47:47 +0200 Subject: [PATCH 17/22] #10194 adjust bars 24 hrs in events and changed numbers --- pandora_console/general/logon_ok.php | 338 ------------------ pandora_console/images/system_event.svg | 15 + .../javascript/general_tactical_view.js | 27 +- .../lib/TacticalView/elements/Agents.php | 4 +- .../lib/TacticalView/elements/Alerts.php | 4 +- .../TacticalView/elements/Configurations.php | 38 +- .../lib/TacticalView/elements/Database.php | 18 +- .../lib/TacticalView/elements/Events.php | 78 ++-- .../lib/TacticalView/elements/LogStorage.php | 6 +- .../lib/TacticalView/elements/Overview.php | 4 +- .../elements/ScheduledDowntime.php | 5 +- .../operation/agentes/tactical.php | 285 +-------------- pandora_console/views/tacticalView/view.php | 10 +- 13 files changed, 135 insertions(+), 697 deletions(-) create mode 100644 pandora_console/images/system_event.svg diff --git a/pandora_console/general/logon_ok.php b/pandora_console/general/logon_ok.php index 059443eff6..920e4ace8e 100644 --- a/pandora_console/general/logon_ok.php +++ b/pandora_console/general/logon_ok.php @@ -30,341 +30,3 @@ use PandoraFMS\TacticalView\GeneralTacticalView; $tacticalView = new GeneralTacticalView(); $tacticalView->render(); -return; -// Temporal return for develop. - // Config functions. -require_once 'include/config.php'; - -// This solves problems in enterprise load. -global $config; - -check_login(); -// ACL Check. -if (check_acl($config['id_user'], 0, 'AR') === 0) { - db_pandora_audit( - AUDIT_LOG_ACL_VIOLATION, - 'Trying to access Default view' - ); - include 'general/noaccess.php'; - exit; -} - -require_once 'include/functions_reporting.php'; -require_once 'include/functions_tactical.php'; -require_once $config['homedir'].'/include/functions_graph.php'; - -if (tags_has_user_acl_tags()) { - ui_print_tags_warning(); -} - -$all_data = tactical_status_modules_agents( - $config['id_user'], - false, - 'AR' -); -$data = []; - -$data['monitor_not_init'] = (int) $all_data['_monitors_not_init_']; -$data['monitor_unknown'] = (int) $all_data['_monitors_unknown_']; -$data['monitor_ok'] = (int) $all_data['_monitors_ok_']; -$data['monitor_warning'] = (int) $all_data['_monitors_warning_']; -$data['monitor_critical'] = (int) $all_data['_monitors_critical_']; -$data['monitor_not_normal'] = (int) $all_data['_monitor_not_normal_']; -$data['monitor_alerts'] = (int) $all_data['_monitors_alerts_']; -$data['monitor_alerts_fired'] = (int) $all_data['_monitors_alerts_fired_']; -$data['monitor_total'] = (int) $all_data['_monitor_total_']; - - -$data['total_agents'] = (int) $all_data['_total_agents_']; - -$data['monitor_checks'] = (int) $all_data['_monitor_checks_']; -if (!empty($all_data)) { - if ($data['monitor_not_normal'] > 0 && $data['monitor_checks'] > 0) { - $data['monitor_health'] = format_numeric((100 - ($data['monitor_not_normal'] / ($data['monitor_checks'] / 100))), 1); - } else { - $data['monitor_health'] = 100; - } - - if ($data['monitor_not_init'] > 0 && $data['monitor_checks'] > 0) { - $data['module_sanity'] = format_numeric((100 - ($data['monitor_not_init'] / ($data['monitor_checks'] / 100))), 1); - } else { - $data['module_sanity'] = 100; - } - - if (isset($data['alerts'])) { - if ($data['monitor_alerts_fired'] > 0 && $data['alerts'] > 0) { - $data['alert_level'] = format_numeric((100 - ($data['monitor_alerts_fired'] / ($data['alerts'] / 100))), 1); - } else { - $data['alert_level'] = 100; - } - } else { - $data['alert_level'] = 100; - $data['alerts'] = 0; - } - - $data['monitor_bad'] = ($data['monitor_critical'] + $data['monitor_warning']); - - if ($data['monitor_bad'] > 0 && $data['monitor_checks'] > 0) { - $data['global_health'] = format_numeric((100 - ($data['monitor_bad'] / ($data['monitor_checks'] / 100))), 1); - } else { - $data['global_health'] = 100; - } - - $data['server_sanity'] = format_numeric((100 - $data['module_sanity']), 1); -} - -ui_require_css_file('logon'); - -echo '
'; - -// -// Overview Table. -// -$table = new stdClass(); -$table->class = 'no-class'; -$table->cellpadding = 4; -$table->cellspacing = 4; -$table->head = []; -$table->data = []; -$table->headstyle[0] = 'text-align:center;'; -$table->width = '100%'; -$table->head_colspan[0] = 4; - -// Indicators. -$tdata = []; -$stats = reporting_get_stats_indicators($data, 120, 10, false); -$status = ''; -foreach ($stats as $stat) { - $status .= ''; -} - -$status .= '
'.$stat['title'].''.$stat['graph'].'
'; -$table->rowclass = []; -$table->rowclass[0] = 'w100p'; -$table->rowclass[1] = 'w100p'; -$table->rowclass[2] = 'w100p'; -$table->rowclass[3] = 'w100p'; -$table->rowclass[4] = 'w100p'; -$table->rowclass[5] = 'w100p'; -$table->data[0][0] = $status; - -$table->data[] = $tdata; - -// Alerts. -$tdata = []; -$tdata[0] = reporting_get_stats_alerts($data); -$table->rowclass[] = ''; -$table->data[] = $tdata; - -// Modules by status. -$tdata = []; - -$data_agents = [ - __('Critical') => $data['monitor_critical'], - __('Warning') => $data['monitor_warning'], - __('Normal') => $data['monitor_ok'], - __('Unknown') => $data['monitor_unknown'], - __('Not init') => $data['monitor_not_init'], -]; - -$tdata[0] = reporting_get_stats_modules_status($data, 180, 100, false, $data_agents); -$table->rowclass[] = ''; -$table->data[] = $tdata; - -// Total agents and modules. -$tdata = []; -$tdata[0] = reporting_get_stats_agents_monitors($data); -$table->rowclass[] = ''; -$table->data[] = $tdata; - -// Users. -if (users_is_admin() || check_acl($config['id_user'], 0, 'UM')) { - $tdata = []; - $tdata[0] = reporting_get_stats_users($data); - $table->rowclass[] = ''; - $table->data[] = $tdata; -} - -ui_toggle( - html_print_table($table, true), - __('%s Overview', get_product_name()), - '', - 'overview', - false -); -unset($table); - -echo '