'.html_print_image(
'images/RC.png',
true,
[
@@ -297,7 +297,7 @@ switch ($section) {
$help_header = 'setup_flow_tab';
break;
- case 'ehorus':
+ case 'pandorarc':
$buttons['ehorus']['active'] = true;
$subpage = __('Pandora RC');
$help_header = 'setup_ehorus_tab';
@@ -442,7 +442,7 @@ switch ($section) {
include_once $config['homedir'].'/godmode/setup/setup_visuals.php';
break;
- case 'ehorus':
+ case 'pandorarc':
include_once $config['homedir'].'/godmode/setup/setup_ehorus.php';
break;
diff --git a/pandora_console/images/widgets/service_level.png b/pandora_console/images/widgets/service_level.png
new file mode 100644
index 0000000000..685744641f
Binary files /dev/null and b/pandora_console/images/widgets/service_level.png differ
diff --git a/pandora_console/include/functions.php b/pandora_console/include/functions.php
index 641a9f93f7..0bb6612376 100644
--- a/pandora_console/include/functions.php
+++ b/pandora_console/include/functions.php
@@ -306,32 +306,48 @@ function format_for_graph(
}
-function human_milliseconds_to_string($seconds)
+function human_milliseconds_to_string($seconds, $size_text='large')
{
$ret = '';
// get the days
$days = intval(intval($seconds) / (360000 * 24));
if ($days > 0) {
- $ret .= "$days days ";
+ if ($size_text === 'short') {
+ $ret .= str_replace(' ', '', "$days d").' ';
+ } else {
+ $ret .= "$days days ";
+ }
}
// get the hours
$hours = ((intval($seconds) / 360000) % 24);
if ($hours > 0) {
- $ret .= "$hours hours ";
+ if ($size_text === 'short') {
+ $ret .= str_replace(' ', '', "$hours h").' ';
+ } else {
+ $ret .= "$hours hours ";
+ }
}
// get the minutes
$minutes = ((intval($seconds) / 6000) % 60);
if ($minutes > 0) {
- $ret .= "$minutes minutes ";
+ if ($size_text === 'short') {
+ $ret .= str_replace(' ', '', "$minutes m").' ';
+ } else {
+ $ret .= "$minutes minutes ";
+ }
}
// get the seconds
$seconds = ((intval($seconds) / 100) % 60);
if ($seconds > 0) {
- $ret .= "$seconds seconds";
+ if ($size_text === 'short') {
+ $ret .= str_replace(' ', '', "$seconds s").' ';
+ } else {
+ $ret .= "$seconds seconds ";
+ }
}
return $ret;
diff --git a/pandora_console/include/functions_cron_task.php b/pandora_console/include/functions_cron_task.php
index 9de0520ccd..40a6e159cc 100644
--- a/pandora_console/include/functions_cron_task.php
+++ b/pandora_console/include/functions_cron_task.php
@@ -459,17 +459,17 @@ function cron_task_start_gotty(bool $restart_mode=true)
// Check prev process running and kill it (only if port changed in setup params).
if (empty($config['restart_gotty_next_cron_port']) === false) {
- config_update_value('restart_gotty_next_cron_port', '');
-
- $prevProcessRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'");
+ $prevProcessRunning = shell_exec("pgrep -af 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."' | grep -v 'pgrep'");
if (empty($prevProcessRunning) === false) {
shell_exec("pkill -f 'pandora_gotty.*-p ".$config['restart_gotty_next_cron_port']."'");
}
+
+ config_update_value('restart_gotty_next_cron_port', '');
}
// Check if gotty is running on the configured port.
- $processRunning = shell_exec("pgrep -f 'pandora_gotty.*-p ".$config['gotty_port']."'");
+ $processRunning = shell_exec("pgrep -af 'pandora_gotty.*-p ".$config['gotty_port']."' | grep -v 'pgrep'");
$start_proc = true;
diff --git a/pandora_console/include/functions_modules.php b/pandora_console/include/functions_modules.php
index 5add1570d8..ea776d6fe3 100755
--- a/pandora_console/include/functions_modules.php
+++ b/pandora_console/include/functions_modules.php
@@ -4770,7 +4770,231 @@ function export_agents_module_csv($filters)
/**
- * Check if modules are compatible with MADE server.
+ * Function to return Mean Time Between Failure, Mean Time To Solution (in seconds)
+ * and Availability of a module
+ *
+ * @param string $datetime_from Start time of the interval.
+ *
+ * @param string $datetime_to End time of the interval.
+ *
+ * @param string $id_agentmodule id_agentmodule of the module
+ *
+ * @return array Returns an array with the data
+ */
+function service_level_module_data($datetime_from, $datetime_to, $id_agentmodule)
+{
+ $data = [];
+ $data['mtbf'] = false;
+ $data['mtrs'] = false;
+ $data['availability'] = false;
+ $data['critical_events'] = false;
+ $data['warning_events'] = false;
+ $data['last_status_change'] = false;
+ $data['module_name'] = false;
+
+ $availability = 0;
+ $type = '';
+ if ((bool) is_metaconsole() === true) {
+ if (enterprise_include_once('include/functions_metaconsole.php') !== ENTERPRISE_NOT_HOOK) {
+ $server_id = [];
+ $server_id['id'] = explode('|', $id_agentmodule)[0];
+ $id_agentmodule = explode('|', $id_agentmodule)[1];
+ $server_name = db_get_row_filter('tmetaconsole_setup', $server_id, 'server_name');
+ $connection = metaconsole_get_connection($server_name);
+ if (metaconsole_load_external_db($connection) !== NOERR) {
+ // Restore db connection.
+ metaconsole_restore_db();
+ return $data;
+ }
+ }
+ }
+
+ $uncompressed_data = db_uncompress_module_data(
+ $id_agentmodule,
+ $datetime_from,
+ $datetime_to
+ );
+
+ $first_utimestamp = 0;
+ foreach ($uncompressed_data as $data_module) {
+ foreach ($data_module['data'] as $subdata) {
+ if (!empty($subdata['datos'])) {
+ $first_utimestamp = $subdata['utimestamp'];
+ if (isset($subdata['type'])) {
+ $type = $subdata['type'];
+ }
+
+ break;
+ }
+ }
+ }
+
+ $interval_time = ($datetime_to - $datetime_from);
+ $current_time = time();
+ $sql = 'SELECT utimestamp, event_type FROM tevento
+ WHERE id_agentmodule = '.$id_agentmodule.'
+ AND utimestamp >= '.$datetime_from.'
+ AND utimestamp <= '.$datetime_to.'
+ ORDER BY utimestamp DESC';
+
+ $events_time = db_get_all_rows_sql($sql);
+
+ // Count events.
+ $sql = 'SELECT COUNT(*) as critical_events FROM tevento
+ WHERE id_agentmodule= '.$id_agentmodule.'
+ AND utimestamp >= '.$datetime_from.'
+ AND utimestamp <= '.$datetime_to.'
+ AND (event_type = "going_up_critical" OR event_type = "going_down_critical")';
+
+ $critical_events = db_get_sql($sql);
+
+ $sql = 'SELECT COUNT(*) as warning_events FROM tevento
+ WHERE id_agentmodule= '.$id_agentmodule.'
+ AND utimestamp >= '.$datetime_from.'
+ AND utimestamp <= '.$datetime_to.'
+ AND (event_type = "going_up_warning" OR event_type = "going_down_warning")';
+
+ $warning_events = db_get_sql($sql);
+
+ if ($events_time !== false && count($events_time) > 0) {
+ $failed_event = [];
+ $normal_event = [];
+ $events_time = array_reverse($events_time);
+ $mtrs_events = [];
+ foreach ($events_time as $key => $event) {
+ if ($event['event_type'] === 'going_up_critical' || $event['event_type'] === 'going_down_critical') {
+ $failed_event[] = $event['utimestamp'];
+ $mtrs_events[]['failed_event'] = $event['utimestamp'];
+ }
+
+ if ($event['event_type'] === 'going_up_normal'
+ || $event['event_type'] === 'going_down_normal'
+ || $event['event_type'] === 'going_up_warning'
+ || $event['event_type'] === 'going_down_warning'
+ ) {
+ $normal_event[] = $event['utimestamp'];
+ $mtrs_events[]['normal_event'] = $event['utimestamp'];
+ }
+ }
+
+ $process_mtrs_events = [];
+
+ if (empty($mtrs_events) === false) {
+ $last_event_key = '';
+ foreach ($mtrs_events as $key => $val) {
+ if (key($val) !== $last_event_key) {
+ $last_event_key = key($val);
+ $process_mtrs_events[] = $val;
+ }
+ }
+ }
+
+ $mtrs_array = [];
+ if (empty($normal_event) === true) {
+ $mtrs_array[] = ($current_time - $failed_event[0]);
+ } else if (empty($failed_event) === true) {
+ $mtrs_array[] = 0;
+ } else {
+ $last_value = '';
+ foreach ($process_mtrs_events as $key => $val) {
+ $current_value = $val[key($val)];
+ if ($last_value !== '') {
+ $mtrs_array[] = ($current_value - $last_value);
+ }
+
+ $last_value = $current_value;
+ }
+
+ $last_mtrs_event = key(end($process_mtrs_events));
+ if ($last_mtrs_event === 'failed_event') {
+ $mtrs_array[] = ($current_time - $last_value);
+ }
+ }
+
+ $mtbf_array = [];
+
+ if (!empty($failed_event) === true) {
+ if (count($failed_event) > 1) {
+ for ($i = 1; $i <= array_key_last($failed_event); $i++) {
+ $mtbf_array[] = ($failed_event[$i] - ($failed_event[($i - 1)]));
+ }
+ } else {
+ $mtbf_array[] = 0;
+ }
+ } else {
+ $mtbf_array[] = 0;
+ }
+
+ $total_time_failed = array_sum($mtrs_array);
+ $total_time_ok = ($interval_time - $total_time_failed);
+ if (count($events_time) === 1) {
+ if ((int) $first_utimestamp !== 0) {
+ $availability = round((($total_time_ok / $interval_time) * 100), 2);
+ }
+ } else {
+ $availability = round((($total_time_ok / $interval_time) * 100), 2);
+ }
+
+ if ($critical_events > 1) {
+ $mtbf = round(array_sum($mtbf_array) / count($mtbf_array));
+ } else {
+ $mtbf = false;
+ }
+
+ if (count($mtrs_array) === 1 && (int) $first_utimestamp !== 0) {
+ $mtrs = round($total_time_failed / count($mtrs_array));
+ } else if (count($mtrs_array) > 1 && (int) $first_utimestamp !== 0) {
+ $mtrs = round((array_sum($mtrs_array) / count($mtrs_array)));
+ } else {
+ $mtrs = false;
+ }
+
+ $data['mtbf'] = $mtbf;
+ $data['mtrs'] = $mtrs;
+ $data['availability'] = $availability;
+ } else {
+ $data['mtbf'] = false;
+ $data['mtrs'] = false;
+ $data['availability'] = false;
+ }
+
+ // Get last status change.
+ $sql = 'SELECT last_status_change FROM tagente_estado
+ WHERE id_agente_modulo = '.$id_agentmodule.' ';
+
+ $last_status_change = db_get_sql($sql);
+
+ // Get module name.
+ /*
+ $sql = 'SELECT nombre FROM tagente_modulo
+ WHERE id_agente_modulo = '.$id_agentmodule;*/
+
+ $sql = 'SELECT tagente_modulo.nombre as nombre, tagente.alias as alias
+ FROM tagente_modulo INNER JOIN tagente
+ ON tagente_modulo.id_agente = tagente.id_agente
+ WHERE id_agente_modulo = '.$id_agentmodule.' ';
+ $sql_query = db_get_all_rows_sql($sql);
+
+ $data['critical_events'] = $critical_events;
+ $data['warning_events'] = $warning_events;
+ $data['last_status_change'] = $last_status_change;
+ $data['module_name'] = $sql_query[0]['nombre'];
+ if ((bool) is_metaconsole() === true) {
+ $data['agent_alias'] = $server_name['server_name'].' » '.$sql_query[0]['alias'];
+ } else {
+ $data['agent_alias'] = $sql_query[0]['alias'];
+ }
+
+ if ((bool) is_metaconsole() === true) {
+ metaconsole_restore_db();
+ }
+
+ return $data;
+}
+
+
+/*
+ Check if modules are compatible with MADE server.
*
* @param integer $id_tipo_modulo
* @retur boolean True if compatible, false otherwise.
diff --git a/pandora_console/include/lib/Dashboard/Widget.php b/pandora_console/include/lib/Dashboard/Widget.php
index ca48e6d61a..8ed3ece7f9 100644
--- a/pandora_console/include/lib/Dashboard/Widget.php
+++ b/pandora_console/include/lib/Dashboard/Widget.php
@@ -466,6 +466,10 @@ class Widget
$className .= '\HeatmapWidget';
break;
+ case 'service_level':
+ $className .= '\ServiceLevelWidget';
+ break;
+
case 'security_hardening':
if (\enterprise_installed() === false) {
$not_installed = true;
diff --git a/pandora_console/include/lib/Dashboard/Widgets/service_level.php b/pandora_console/include/lib/Dashboard/Widgets/service_level.php
new file mode 100644
index 0000000000..8184495587
--- /dev/null
+++ b/pandora_console/include/lib/Dashboard/Widgets/service_level.php
@@ -0,0 +1,672 @@
+width = $width;
+
+ // Height.
+ $this->height = $height;
+
+ // Grid Width.
+ $this->gridWidth = $gridWidth;
+
+ // Options.
+ $this->values = $this->decoders($this->getOptionsWidget());
+
+ // Positions.
+ $this->position = $this->getPositionWidget();
+
+ // Page.
+ $this->page = basename(__FILE__);
+
+ // ClassName.
+ $class = new \ReflectionClass($this);
+ $this->className = $class->getShortName();
+
+ // Title.
+ $this->title = __('Service Level Detail');
+
+ // Name.
+ if (empty($this->name) === true) {
+ $this->name = 'service_level';
+ }
+
+ // This forces at least a first configuration.
+ $this->configurationRequired = false;
+ if (isset($this->values['mModules']) === false) {
+ $this->configurationRequired = true;
+ }
+
+ $this->overflow_scrollbars = false;
+ }
+
+
+ /**
+ * Decoders hack for retrocompability.
+ *
+ * @param array $decoder Values.
+ *
+ * @return array Returns the values with the correct key.
+ */
+ public function decoders(array $decoder): array
+ {
+ $values = [];
+ // Retrieve global - common inputs.
+ $values = parent::decoders($decoder);
+
+ if (isset($decoder['interval']) === true) {
+ $values['interval'] = $decoder['interval'];
+ } else {
+ $values['interval'] = '28800';
+ }
+
+ if (isset($decoder['show_agents']) === true) {
+ $values['show_agents'] = $decoder['show_agents'];
+ } else {
+ $values['show_agents'] = '0';
+ }
+
+ if (isset($decoder['mTypeShow']) === true) {
+ $values['mTypeShow'] = $decoder['mTypeShow'];
+ }
+
+ if (isset($decoder['mGroup']) === true) {
+ $values['mGroup'] = $decoder['mGroup'];
+ }
+
+ if (isset($decoder['mRecursion']) === true) {
+ $values['mRecursion'] = $decoder['mRecursion'];
+ }
+
+ if (isset($decoder['mModuleGroup']) === true) {
+ $values['mModuleGroup'] = $decoder['mModuleGroup'];
+ }
+
+ if (isset($decoder['mAgents']) === true) {
+ $values['mAgents'] = $decoder['mAgents'];
+ }
+
+ if (isset($decoder['mShowCommonModules']) === true) {
+ $values['mShowCommonModules'] = $decoder['mShowCommonModules'];
+ }
+
+ if (isset($decoder['mModules']) === true) {
+ $values['mModules'] = $decoder['mModules'];
+ }
+
+ return $values;
+ }
+
+
+ /**
+ * Generates inputs for form (specific).
+ *
+ * @return array Of inputs.
+ *
+ * @throws Exception On error.
+ */
+ public function getFormInputs(): array
+ {
+ $values = $this->values;
+
+ // Retrieve global - common inputs.
+ $inputs = parent::getFormInputs();
+
+ // Interval.
+ $fields = [
+ '604800' => __('1 week'),
+ '172800' => __('48 hours'),
+ '86400' => __('24 hours'),
+ '43200' => __('12 hours'),
+ '28800' => __('8 hours'),
+
+ ];
+
+ $inputs[] = [
+ 'label' => __('Interval'),
+ 'arguments' => [
+ 'type' => 'select',
+ 'fields' => $fields,
+ 'name' => 'interval-'.$this->cellId,
+ 'selected' => $values['interval'],
+ 'return' => true,
+ ],
+ ];
+
+ // Show agent.
+ $inputs[] = [
+ 'label' => __('Show agents'),
+ 'arguments' => [
+ 'type' => 'switch',
+ 'name' => 'show_agents-'.$this->cellId,
+ 'value' => $values['show_agents'],
+ 'return' => true,
+ ],
+ ];
+
+ $return_all_group = false;
+
+ if (users_can_manage_group_all('RM') || $this->values['mGroup'] == 0) {
+ $return_all_group = true;
+ }
+
+ $mgroup = '';
+ if (isset($this->values['mGroup']) === false) {
+ $sql = sprintf(
+ 'SELECT id_group FROM tdashboard WHERE id = %d',
+ $this->dashboardId
+ );
+
+ $group_dahsboard = db_get_value_sql($sql);
+ if ($group_dahsboard > 0) {
+ $mgroup = $group_dahsboard;
+ }
+ }
+
+ if (is_metaconsole() === true) {
+ $this->values['mAgents'] = $this->getIdCacheAgent($this->values['mAgents']);
+ }
+
+ $inputs[] = [
+ 'class' => 'flex flex-row',
+ 'id' => 'select_multiple_modules_filtered',
+ 'arguments' => [
+ 'type' => 'select_multiple_modules_filtered',
+ 'uniqId' => $this->cellId,
+ 'mGroup' => (isset($this->values['mGroup']) === true) ? $this->values['mGroup'] : $mgroup,
+ 'mRecursion' => (isset($this->values['mRecursion']) === true) ? $this->values['mRecursion'] : '',
+ 'mModuleGroup' => (isset($this->values['mModuleGroup']) === true) ? $this->values['mModuleGroup'] : '',
+ 'mAgents' => (isset($this->values['mAgents']) === true) ? $this->values['mAgents'] : '',
+ 'mShowCommonModules' => (isset($this->values['mShowCommonModules']) === true) ? $this->values['mShowCommonModules'] : '',
+ 'mModules' => (isset($this->values['mModules']) === true) ? $this->values['mModules'] : '',
+ 'mShowSelectedOtherGroups' => true,
+ 'mReturnAllGroup' => $return_all_group,
+ 'mMetaFields' => ((bool) is_metaconsole()),
+ 'commonModulesSwitch' => true,
+ ],
+ ];
+
+ return $inputs;
+ }
+
+
+ /**
+ * Get Post for widget.
+ *
+ * @return array
+ */
+ public function getPost():array
+ {
+ // Retrieve global - common inputs.
+ $values = parent::getPost();
+
+ $values['interval'] = \get_parameter('interval-'.$this->cellId, '28800');
+
+ $values['show_agents'] = \get_parameter('show_agents-'.$this->cellId, '0');
+
+ $values['mTypeShow'] = \get_parameter(
+ 'filtered-type-show-'.$this->cellId
+ );
+
+ $values['mGroup'] = \get_parameter(
+ 'filtered-module-group-'.$this->cellId
+ );
+ $values['mRecursion'] = \get_parameter_switch(
+ 'filtered-module-recursion-'.$this->cellId
+ );
+ $values['mModuleGroup'] = \get_parameter(
+ 'filtered-module-module-group-'.$this->cellId
+ );
+ $values['mAgents'] = \get_parameter(
+ 'filtered-module-agents-'.$this->cellId
+ );
+ if (is_metaconsole() === true) {
+ $values['mAgents'] = $this->getRealIdAgentNode($values['mAgents']);
+ }
+
+ $values['mShowCommonModules'] = \get_parameter(
+ 'filtered-module-show-common-modules-'.$this->cellId
+ );
+ $values['mModules'] = explode(
+ ',',
+ \get_parameter(
+ 'filtered-module-modules-'.$this->cellId
+ )
+ );
+
+ return $values;
+ }
+
+
+ /**
+ * Draw widget.
+ *
+ * @return string;
+ */
+ public function load()
+ {
+ global $config;
+
+ $output = '';
+ if (check_acl($config['id_user'], 0, 'AR') === 0) {
+ $output .= '';
+ $output .= ui_print_error_message(
+ __('You don\'t have access'),
+ '',
+ true
+ );
+ $output .= '
';
+ return $output;
+ }
+
+ $interval_range = [];
+ $current_timestamp = time();
+ $interval_range['start'] = ($current_timestamp - $this->values['interval']);
+ $interval_range['end'] = $current_timestamp;
+
+ $reduceAllModules = array_reduce(
+ $this->values['mModules'],
+ function ($carry, $item) {
+ if ($item === null) {
+ return $carry;
+ }
+
+ if (is_metaconsole() === true) {
+ $item = explode('|', $item);
+ $serverId = $item[0];
+ $fullname = $item[1];
+ if ($this->values['mShowCommonModules'] !== 'on') {
+ $item = explode(' » ', $fullname);
+ $name = $item[1];
+ $carry['modules_selected'][$serverId][$name] = null;
+ $carry['modules'][$name] = null;
+ } else {
+ $carry['modules'][$fullname] = null;
+ }
+ } else {
+ $carry['modules'][$item] = null;
+ }
+
+ return $carry;
+ }
+ );
+
+ $allModules = $reduceAllModules['modules'];
+ $visualData = [];
+ // Extract info agents selected.
+ $target_agents = explode(',', $this->values['mAgents']);
+ foreach ($target_agents as $agent_id) {
+ try {
+ if (is_metaconsole() === true && str_contains($agent_id, '|') === true) {
+ $server_agent = explode('|', $agent_id);
+ } else {
+ $id_agente = $agent_id;
+ }
+
+ if ((bool) is_metaconsole() === true) {
+ if (isset($server_agent) === true) {
+ $id_agente = $server_agent[1];
+ $tserver = $server_agent[0];
+ } else {
+ $tmeta_agent = db_get_row_filter(
+ 'tmetaconsole_agent',
+ [ 'id_agente' => $id_agente ]
+ );
+ $id_agente = $tmeta_agent['id_tagente'];
+ $tserver = $tmeta_agent['id_tmetaconsole_setup'];
+ }
+
+ if (metaconsole_connect(null, $tserver) !== NOERR) {
+ continue;
+ }
+ }
+
+ $agent = new Agent((int) $id_agente);
+ $visualData[$agent_id]['agent_status'] = $agent->lastStatus();
+ $visualData[$agent_id]['agent_name'] = $agent->name();
+ $visualData[$agent_id]['agent_alias'] = $agent->alias();
+ $visualData[$agent_id]['modules'] = [];
+ if (empty($allModules) === false) {
+ if (is_metaconsole() === true && $this->values['mShowCommonModules'] !== 'on') {
+ if (isset($reduceAllModules['modules_selected'][$tserver]) === true) {
+ $modules = $agent->searchModules(
+ ['nombre' => array_keys($reduceAllModules['modules_selected'][$tserver])]
+ );
+ } else {
+ $modules = null;
+ }
+ } else {
+ $modules = $agent->searchModules(
+ ['nombre' => array_keys($allModules)]
+ );
+ }
+ }
+
+ $visualData[$agent_id]['modules'] = $allModules;
+
+ if ((bool) is_metaconsole() === true) {
+ metaconsole_restore_db();
+ }
+
+ foreach ($modules as $module) {
+ if ($module === null) {
+ continue;
+ }
+
+ $data_module_array = $module->toArray();
+ $visualData[$agent_id]['modules'][$module->name()] = [];
+ $last_status = $module->getStatus()->toArray();
+ $visualData[$agent_id]['modules'][$module->name()]['last_status_change'] = $last_status['last_status_change'];
+
+ // Mean Time Between Failure.
+ // Mean Time To Solution.
+ // Availability.
+ if ((bool) is_metaconsole() === true) {
+ $module_id = $tserver.'|'.$data_module_array['id_agente_modulo'];
+ } else {
+ $module_id = $data_module_array['id_agente_modulo'];
+ }
+
+ $module_data = service_level_module_data($interval_range['start'], $interval_range['end'], $module_id);
+ $visualData[$agent_id]['modules'][$module->name()]['mtrs'] = ($module_data['mtrs'] !== false) ? human_milliseconds_to_string(($module_data['mtrs'] * 100), 'short') : '-';
+ $visualData[$agent_id]['modules'][$module->name()]['mtbf'] = ($module_data['mtbf'] !== false) ? human_milliseconds_to_string(($module_data['mtbf'] * 100), 'short') : '-';
+ $visualData[$agent_id]['modules'][$module->name()]['availability'] = ($module_data['availability'] !== false) ? $module_data['availability'] : '100';
+ $visualData[$agent_id]['modules'][$module->name()]['critical_events'] = ($module_data['critical_events'] !== false) ? $module_data['critical_events'] : '';
+ $visualData[$agent_id]['modules'][$module->name()]['warning_events'] = ($module_data['warning_events'] !== false) ? $module_data['warning_events'] : '';
+ $visualData[$agent_id]['modules'][$module->name()]['last_status_change'] = ($module_data['last_status_change'] !== false) ? $module_data['last_status_change'] : '';
+ $visualData[$agent_id]['modules'][$module->name()]['agent_alias'] = ($module_data['agent_alias'] !== false) ? $module_data['agent_alias'] : '';
+ $visualData[$agent_id]['modules'][$module->name()]['module_name'] = ($module_data['module_name'] !== false) ? $module_data['module_name'] : '';
+ }
+ } catch (\Exception $e) {
+ echo 'Error: ['.$agent_id.']'.$e->getMessage();
+ }
+ }
+
+ $table = new \stdClass();
+
+ $table->width = '100%';
+ $table->class = 'databox filters filter-table-adv';
+
+ $table->head = [];
+ $show_agents = $this->values['show_agents'];
+ if ($show_agents === 'on') {
+ $table->head[0] = __('Agent / Modules');
+ } else {
+ $table->head[0] = __('Modules');
+ }
+
+ $table->head[1] = __('% Av.');
+ $table->head[2] = __('MTBF');
+ $table->head[3] = __('MTRS');
+ $table->head[4] = __('Crit. Events').ui_print_help_tip(__('Counted only critical events generated automatic by the module'), true);
+ $table->head[5] = __('Warn. Events').ui_print_help_tip(__('Counted only warning events generated automatic by the module'), true);
+ $table->head[6] = __('Last change');
+ $table->data = [];
+ $table->cellstyle = [];
+ $row = 0;
+ foreach ($visualData as $agent_id => $data) {
+ foreach ($data['modules'] as $module_name => $module_data) {
+ if (isset($module_data) === true) {
+ if ($show_agents === 'on') {
+ $table->data[$row][0] = $module_data['agent_alias'].' / '.$module_data['module_name'];
+ $table->cellstyle[$row][0] = 'text-align:left';
+ } else {
+ $table->data[$row][0] = $module_data['module_name'];
+ $table->cellstyle[$row][0] = 'text-align:left';
+ }
+
+ $table->data[$row][1] = $module_data['availability'].'%';
+ $table->data[$row][2] = $module_data['mtbf'];
+ $table->data[$row][3] = $module_data['mtrs'];
+ $table->data[$row][4] = $module_data['critical_events'];
+ $table->data[$row][5] = $module_data['warning_events'];
+ $table->data[$row][6] = date(TIME_FORMAT, $module_data['last_status_change']);
+ }
+
+ $row++;
+ }
+ }
+
+ $height = (count($table->data) * 32);
+ $style = 'min-width:400px; min-height:'.$height.'px;';
+ $output = '';
+ $output .= html_print_table($table, true);
+ $output .= '
';
+
+ return $output;
+ }
+
+
+ /**
+ * Get description.
+ *
+ * @return string.
+ */
+ public static function getDescription()
+ {
+ return __('Service Level Detail');
+ }
+
+
+ /**
+ * Get Name.
+ *
+ * @return string.
+ */
+ public static function getName()
+ {
+ return 'service_level';
+ }
+
+
+ /**
+ * Get size Modal Configuration.
+ *
+ * @return array
+ */
+ public function getSizeModalConfiguration(): array
+ {
+ $size = [
+ 'width' => 800,
+ 'height' => 270,
+ ];
+
+ return $size;
+ }
+
+
+ /**
+ * Return array with the real id agent and server.
+ *
+ * @param string $id_agents_cache String with the agents cache id.
+ *
+ * @return string $agents_servers with the real id agent and server.
+ */
+ public function getRealIdAgentNode($id_agents_cache)
+ {
+ $agents_servers = [];
+ $target_agents = explode(',', $id_agents_cache);
+ foreach ($target_agents as $agent_id) {
+ $id_agente = $agent_id;
+ $tmeta_agent = db_get_row_filter(
+ 'tmetaconsole_agent',
+ ['id_agente' => $id_agente]
+ );
+
+ $id_agente = $tmeta_agent['id_tagente'];
+ $tserver = $tmeta_agent['id_tmetaconsole_setup'];
+ $agents_servers[] = $tserver.'|'.$id_agente;
+ }
+
+ return implode(',', $agents_servers);
+ }
+
+
+ /**
+ * Return string with the cache id agent in metaconsole.
+ *
+ * @param string $id_agents String with the agents and server id.
+ *
+ * @return string $cache_id_agents with the cache id agent.
+ */
+ public function getIdCacheAgent($id_agents)
+ {
+ $target_agents = explode(',', $id_agents);
+ $cache_id_agents = [];
+ foreach ($target_agents as $agent_id) {
+ if (str_contains($agent_id, '|') === false) {
+ $cache_id_agents[] = $agent_id;
+ continue;
+ }
+
+ $server_agent = explode('|', $agent_id);
+ $tmeta_agent = db_get_row_filter(
+ 'tmetaconsole_agent',
+ [
+ 'id_tagente' => $server_agent[1],
+ 'id_tmetaconsole_setup' => $server_agent[0],
+ ]
+ );
+ $cache_id_agents[] = $tmeta_agent['id_agente'];
+ }
+
+ return implode(',', $cache_id_agents);
+ }
+
+
+}
diff --git a/pandora_console/include/styles/dashboards.css b/pandora_console/include/styles/dashboards.css
index 5a263b9246..1bcf43a16f 100644
--- a/pandora_console/include/styles/dashboards.css
+++ b/pandora_console/include/styles/dashboards.css
@@ -284,6 +284,11 @@ li#div-textarea label {
display: initial;
}
+.content-widget .container-top {
+ height: 100%;
+ width: 99%;
+}
+
.widget-groups-status {
display: flex;
flex-direction: row;
diff --git a/pandora_console/include/styles/pandora_black.css b/pandora_console/include/styles/pandora_black.css
index 1e2cc377fc..a3025c3a33 100644
--- a/pandora_console/include/styles/pandora_black.css
+++ b/pandora_console/include/styles/pandora_black.css
@@ -784,6 +784,11 @@ form ul.form_flex {
width: 100%;
}
+.content-widget .container-top {
+ height: 100%;
+ width: 99%;
+}
+
.container-layout {
border-radius: 5px;
border: 3px dashed #fff;
diff --git a/pandora_console/operation/agentes/pandora_networkmap.view.php b/pandora_console/operation/agentes/pandora_networkmap.view.php
index 5256c10871..3cbe53e815 100644
--- a/pandora_console/operation/agentes/pandora_networkmap.view.php
+++ b/pandora_console/operation/agentes/pandora_networkmap.view.php
@@ -1205,57 +1205,6 @@ if (is_ajax() === true) {
return;
}
- if ($get_agents_in_group) {
- $id = (int) get_parameter('id', 0);
- $group = (int) get_parameter('group', -1);
-
- $return = [];
- $return['correct'] = false;
-
- if ($group != -1) {
- $where_id_agente = ' 1=1 ';
-
- $agents_in_networkmap = db_get_all_rows_filter(
- 'titem',
- [
- 'id_map' => $id,
- 'deleted' => 0,
- ]
- );
- if ($agents_in_networkmap !== false) {
- $ids = [];
- foreach ($agents_in_networkmap as $agent) {
- if ($agent['type'] == 0) {
- $ids[] = $agent['source_data'];
- }
- }
-
- $where_id_agente = ' id_agente NOT IN ('.implode(',', $ids).')';
- }
-
-
- $sql = 'SELECT id_agente, alias
- FROM tagente
- WHERE id_grupo = '.$group.' AND '.$where_id_agente.'
- ORDER BY alias ASC';
-
- $agents = db_get_all_rows_sql($sql);
-
- if ($agents !== false) {
- $return['agents'] = [];
- foreach ($agents as $agent) {
- $return['agents'][$agent['id_agente']] = $agent['alias'];
- }
-
- $return['correct'] = true;
- }
- }
-
- echo json_encode($return);
-
- return;
- }
-
if ($get_agent_info) {
$id_agent = (int) get_parameter('id_agent');