diff --git a/pandora_console/include/class/TreeService.class.php b/pandora_console/include/class/TreeService.class.php
index cb5ae2011c..150eb5f7c3 100644
--- a/pandora_console/include/class/TreeService.class.php
+++ b/pandora_console/include/class/TreeService.class.php
@@ -1,31 +1,85 @@
0) {
$this->metaID = $id_server_meta;
+ $this->serverID = $id_server_meta;
}
parent::__construct(
@@ -66,23 +121,45 @@ class TreeService extends Tree
$this->L2inner = 'LEFT JOIN tservice_element tse
ON tse.id_agent = ta.id_agente';
- $this->L2condition = 'AND tse.id_service='.$this->id;
+ $this->L2condition = sprintf(
+ ' AND tse.id_service=%d AND tse.id_server_meta=0 ',
+ $this->id
+ );
}
+ /**
+ * Setter (propagate counters).
+ *
+ * @param boolean $value Set.
+ *
+ * @return void
+ */
public function setPropagateCounters($value)
{
$this->propagateCounters = (bool) $value;
}
+ /**
+ * Set display all groups.
+ *
+ * @param boolean $value Set.
+ *
+ * @return void
+ */
public function setDisplayAllGroups($value)
{
$this->displayAllGroups = (bool) $value;
}
+ /**
+ * Generates tree data.
+ *
+ * @return void
+ */
protected function getData()
{
if (is_metaconsole() === true && $this->metaID > 0) {
@@ -95,6 +172,7 @@ class TreeService extends Tree
$this->metaID,
]
);
+ $this->connectedToNode = true;
}
if ($this->id == -1) {
@@ -112,6 +190,11 @@ class TreeService extends Tree
}
+ /**
+ * Generates first level data.
+ *
+ * @return void
+ */
protected function getFirstLevel()
{
global $config;
@@ -160,6 +243,11 @@ class TreeService extends Tree
}
+ /**
+ * Retrieve root services.
+ *
+ * @return array Of root services.
+ */
protected function getProcessedServices()
{
$is_favourite = $this->getServiceFavouriteFilter();
@@ -224,6 +312,13 @@ class TreeService extends Tree
}
+ /**
+ * Retrieve first level fields.
+ *
+ * @deprecated 746.
+ *
+ * @return string With a first level fields.
+ */
protected function getFirstLevelFields()
{
$fields = [];
@@ -232,194 +327,310 @@ class TreeService extends Tree
}
+ /**
+ * Retrieves elements (second level) from selected rootID.
+ *
+ * @return void
+ */
protected function getSecondLevel()
{
- $data = [];
- $data_agents = [];
- $data_modules = [];
- $data_services = [];
+ $service = new Service($this->id, true);
- $sql = $this->getSecondLevelSql();
- $data_agents = db_process_sql($sql);
+ $output = [];
+ foreach ($service->children() as $item) {
+ $tmp = [];
- if (empty($data_agents)) {
- $data_agents = [];
- }
-
- $this->processAgents($data_agents);
-
- foreach ($data_agents as $key => $agent) {
- $data_agents[$key]['showEventsBtn'] = 1;
- $data_agents[$key]['eventAgent'] = $agent['id'];
- }
-
- $sql = $this->getSecondLevelModulesSql();
- $data_modules = db_process_sql($sql);
-
- if (empty($data_modules)) {
- $data_modules = [];
- } else {
- foreach ($data_modules as $key => $module) {
- switch ($module['estado']) {
- case '0':
- $module_status = 'ok';
- $module_title = 'NORMAL';
- break;
-
- case '1':
- $module_status = 'critical';
- $module_title = 'CRITICAL';
- break;
-
- case '2':
- $module_status = 'warning';
- $module_title = 'WARNING';
- break;
-
- case '3':
- $module_status = 'down';
- $module_title = 'UNKNOWN';
- break;
-
- case '4':
- $module_status = 'no_data';
- $module_title = 'NOT INITIALIZED';
- break;
-
- default:
- $module_status = 'down';
- $module_title = 'UNKNOWN';
- break;
- }
-
- $data_modules[$key]['statusImageHTML'] = '';
- $data_modules[$key]['showEventsBtn'] = 1;
- $data_modules[$key]['eventModule'] = $module['id_agente_modulo'];
+ if ($this->metaID > 0) {
+ $tmp['metaID'] = $this->metaID;
+ } else if ($item->id_server_meta() !== 0) {
+ $tmp['metaID'] = $item->id_server_meta();
}
- }
- $sql = $this->getSecondLevelServicesSql();
- $data_services = db_process_sql($sql);
+ $tmp['serverID'] = $tmp['metaID'];
- $data_services = array_reduce(
- $data_services,
- function ($carry, $item) {
- if ($item['id_server_meta'] > 0
- && is_metaconsole() === true
- ) {
- // Impersonate node.
- \enterprise_include_once('include/functions_metaconsole.php');
- $r = \enterprise_hook(
- 'metaconsole_connect',
- [
- null,
- $item['id_server_meta'],
- ]
- );
-
- if ($r === NOERR) {
- $item = db_get_row_sql(
- sprintf(
- 'SELECT
- ts.id,
- ts.id_agent_module,
- ts.name,
- ts.name as `alias`,
- %d as `rootID`,
- "services" as `rootType`,
- "services" as `type`,
- ts.quiet,
- %d as id_server_meta,
- SUM(if((tse.id_agent<>0), 1, 0)) AS `total_agents`,
- SUM(if((tse.id_agente_modulo<>0), 1, 0)) AS `total_modules`,
- SUM(if((tse.id_service_child<>0), 1, 0)) AS `total_services`
- FROM tservice ts
- LEFT JOIN tservice_element tse
- ON tse.id_service = ts.id
- WHERE ts.id = %d
- GROUP BY ts.id',
- $item['id_server_meta'],
- $item['rootID'],
- $item['id']
- )
- );
- $item['obj'] = new Service($item['id']);
+ switch ($item->type()) {
+ case SERVICE_ELEMENT_AGENT:
+ if ($item->agent() === null) {
+ // Skip item.
+ continue 2;
}
- // Restore connection.
- \enterprise_hook('metaconsole_restore_db');
- } else {
- $item['obj'] = new Service($item['id']);
- }
+ $tmp['id'] = $item->agent()->id_agente();
+ $tmp['name'] = $item->agent()->nombre();
+ $tmp['alias'] = $item->agent()->alias();
+ $tmp['fired_count'] = $item->agent()->fired_count();
+ $tmp['normal_count'] = $item->agent()->normal_count();
+ $tmp['warning_count'] = $item->agent()->warning_count();
+ $tmp['critical_count'] = $item->agent()->critical_count();
+ $tmp['unknown_count'] = $item->agent()->unknown_count();
+ $tmp['notinit_count'] = $item->agent()->notinit_count();
+ $tmp['total_count'] = $item->agent()->total_count();
- $carry[] = $item;
- return $carry;
- },
- []
- );
+ if ($item->agent()->quiet() > 0
+ || $item->agent()->cps() > 0
+ ) {
+ $tmp['quiet'] = 1;
+ } else {
+ $tmp['quiet'] = 0;
+ }
- $service_stats = [];
+ $tmp['state_critical'] = $tmp['critical_count'];
+ $tmp['state_warning'] = $tmp['warning_count'];
+ $tmp['state_unknown'] = $tmp['unknown_count'];
+ $tmp['state_notinit'] = $tmp['notinit_count'];
+ $tmp['state_normal'] = $tmp['normal_count'];
+ $tmp['state_total'] = $tmp['total_count'];
+ $tmp['type'] = SERVICE_ELEMENT_AGENT;
+ $tmp['rootID'] = $this->rootID;
+ $tmp['rootType'] = $this->rootType;
+ $tmp['counters'] = [
+ 'alerts' => $item->agent()->fired_count(),
+ 'ok' => $item->agent()->normal_count(),
+ 'warning' => $item->agent()->warning_count(),
+ 'critical' => $item->agent()->critical_count(),
+ 'unknown' => $item->agent()->unknown_count(),
+ 'not_init' => $item->agent()->notinit_count(),
+ 'total' => $item->agent()->total_count(),
+ ];
- foreach ($data_services as $service) {
- $service_stats[$service['id']]['id'] = (int) $service['id'];
- $service_stats[$service['id']]['name'] = $service['name'];
- $service_stats[$service['id']]['alias'] = $service['name'];
- if (($service['total_services'] + $service['total_agents'] + $service['total_modules']) > 0) {
- $service_stats[$service['id']]['searchChildren'] = 1;
- } else {
- $services[$service['id']]['searchChildren'] = 0;
- }
+ switch ($item->agent()->lastStatus()) {
+ case AGENT_STATUS_NORMAL:
+ $tmp['statusImageHTML'] = '';
+ break;
- $service_stats[$service['id']]['rootID'] = $service['rootID'];
- if ($this->metaID > 0) {
- $service_stats[$service['id']]['metaID'] = $this->metaID;
- } else {
- $service_stats[$service['id']]['metaID'] = $service['id_server_meta'];
- }
+ case AGENT_STATUS_CRITICAL:
+ case AGENT_STATUS_ALERT_FIRED:
+ $tmp['statusImageHTML'] = '';
+ break;
- $service_stats[$service['id']]['rootType'] = $service['rootType'];
- $service_stats[$service['id']]['type'] = 'services';
- $service_stats[$service['id']]['children'] = [];
- $service_stats[$service['id']]['serviceDetail'] = 'index.php?sec=network&sec2=enterprise/operation/services/services&tab=service_map&id_service='.(int) $service['id'];
- $service_stats[$service['id']]['counters'] = [
- 'total_services' => $service['total_services'],
- 'total_agents' => $service['total_agents'],
- 'total_modules' => $service['total_modules'],
- ];
+ case AGENT_STATUS_WARNING:
+ $tmp['statusImageHTML'] = '';
+ break;
- switch ($service['obj']->status()) {
- case SERVICE_STATUS_NORMAL:
- $service_stats[$service['id']]['statusImageHTML'] = '';
+ case AGENT_STATUS_UNKNOWN:
+ default:
+ $tmp['statusImageHTML'] = '';
+ break;
+ }
+
+ $tmp['children'] = [];
+ $tmp['searchChildren'] = 1;
+ $tmp['showEventsBtn'] = 1;
+ $tmp['eventAgent'] = $item->agent()->id_agente();
break;
- case SERVICE_STATUS_CRITICAL:
- $service_stats[$service['id']]['statusImageHTML'] = '';
+ case SERVICE_ELEMENT_MODULE:
+ if ($item->module() === null) {
+ // Skip item.
+ continue 2;
+ }
+
+ $tmp['id'] = $item->module()->id_agente_modulo();
+ $tmp['name'] = $item->module()->nombre();
+ $tmp['id_tipo_modulo'] = $item->module()->id_tipo_modulo();
+ $tmp['id_modulo'] = $item->module()->id_modulo();
+ $tmp['estado'] = $item->module()->lastStatus();
+ $tmp['datos'] = $item->module()->lastValue();
+ $tmp['parent'] = $item->module()->parent_module_id();
+ $alerts = alerts_get_alerts_module_name(
+ $item->module()->id_agente_modulo()
+ );
+ if ($alerts !== false) {
+ // Seems to be used as 'flag'.
+ $tmp['alerts'] = $alerts[0]['id'];
+ }
+
+ $tmp['unit'] = $item->module()->unit();
+ $tmp['type'] = SERVICE_ELEMENT_MODULE;
+ $tmp['id_module_type'] = $item->module()->id_tipo_modulo();
+ $tmp['server_type'] = $tmp['id_module_type'];
+ $tmp['status'] = $item->module()->lastStatus();
+ $tmp['value'] = modules_get_agentmodule_data_for_humans(
+ array_merge(
+ $item->module()->toArray(),
+ [ 'datos' => $item->module()->lastValue() ]
+ )
+ );
+
+ $title = $item->module()->lastStatusTitle();
+
+ if (is_numeric($item->module()->lastValue())) {
+ $divisor = get_data_multiplier($item->module()->unit());
+ $title .= ' : '.format_for_graph(
+ $item->module()->lastValue(),
+ 1,
+ '.',
+ ',',
+ $divisor
+ );
+ } else {
+ $title .= ' : '.substr(
+ io_safe_output(
+ $item->module()->lastValue()
+ ),
+ 0,
+ 42
+ );
+ }
+
+ $tmp['serverName'] = $item->module()->agent()->server_name();
+ $tmp['serverID'] = $tmp['metaID'];
+ $tmp['statusText'] = $item->module()->lastStatusText();
+ $tmp['showGraphs'] = 1;
+ $tmp['showEventsBtn'] = 1;
+ $tmp['eventAgent'] = $item->module()->id_agente();
+
+ $html = 'module()->lastStatusTitle().'" />';
+ $tmp['statusImageHTML'] = $html;
+ $tmp = array_merge(
+ $tmp,
+ $this->getModuleGraphLinks(
+ $tmp
+ )
+ );
break;
- case SERVICE_STATUS_WARNING:
- $service_stats[$service['id']]['statusImageHTML'] = '';
+ case SERVICE_ELEMENT_SERVICE:
+ if ($item->service() === null) {
+ // Skip item.
+ continue 2;
+ }
+
+ $tmp['id'] = (int) $item->service()->id();
+ $tmp['name'] = $item->service()->name();
+ $tmp['alias'] = $item->service()->name();
+
+ if ($this->connectedToNode === false
+ && is_metaconsole() === true
+ && $tmp['metaID'] > 0
+ ) {
+ // Impersonate node.
+ \enterprise_include_once('include/functions_metaconsole.php');
+ \enterprise_hook(
+ 'metaconsole_connect',
+ [
+ null,
+ $tmp['metaID'],
+ ]
+ );
+ }
+
+ $grandchildren = $item->service()->children();
+
+ if ($this->connectedToNode === false
+ && is_metaconsole() === true
+ && $tmp['metaID'] > 0
+ ) {
+ // Restore connection.
+ \enterprise_hook('metaconsole_restore_db');
+ }
+
+ $counters = [
+ 'total_modules' => 0,
+ 'total_agents' => 0,
+ 'total_services' => 0,
+ 'total_dynamic' => 0,
+ 'total' => 0,
+ ];
+
+ if (is_array($grandchildren) === true) {
+ $counters = array_reduce(
+ $grandchildren,
+ function ($carry, $item) {
+ if ($item->type() === SERVICE_ELEMENT_MODULE) {
+ $carry['total_modules']++;
+ } else if ($item->type() === SERVICE_ELEMENT_AGENT) {
+ $carry['total_agents']++;
+ } else if ($item->type() === SERVICE_ELEMENT_SERVICE) {
+ $carry['total_services']++;
+ } else if ($item->type() === SERVICE_ELEMENT_DYNAMIC) {
+ $carry['total_dynamic']++;
+ }
+
+ $carry['total']++;
+
+ return $carry;
+ },
+ $counters
+ );
+ }
+
+ if ($counters['total'] > 0) {
+ $tmp['searchChildren'] = 1;
+ }
+
+ $tmp['type'] = 'services';
+ $tmp['rootType'] = 'services';
+ $tmp['children'] = [];
+ $tmp['serviceDetail'] = ui_get_full_url(
+ 'index.php?sec=network&sec2=enterprise/operation/services/services&tab=service_map&id_service='.$item->service()->id()
+ );
+ $tmp['counters'] = $counters;
+ $tmp['rootID'] = $this->rootID;
+ switch ($item->service()->lastStatus()) {
+ case SERVICE_STATUS_NORMAL:
+ $tmp['statusImageHTML'] = '';
+ break;
+
+ case SERVICE_STATUS_CRITICAL:
+ $tmp['statusImageHTML'] = '';
+ break;
+
+ case SERVICE_STATUS_WARNING:
+ $tmp['statusImageHTML'] = '';
+ break;
+
+ case SERVICE_STATUS_UNKNOWN:
+ default:
+ $tmp['statusImageHTML'] = '';
+ break;
+ }
break;
- case SERVICE_STATUS_UNKNOWN:
+ case SERVICE_ELEMENT_DYNAMIC:
+ // TODO.
+ continue 2;
+
default:
- $service_stats[$service['id']]['statusImageHTML'] = '';
- break;
+ // Unknown type.
+ continue 2;
}
+
+ $output[] = $tmp;
}
- $data_services = array_values($service_stats);
-
- $data = array_merge($data_services, $data_agents, $data_modules);
-
- if (empty($data)) {
- $this->tree = [];
- return;
- }
-
- $this->tree = $data;
+ $this->tree = $output;
}
+ /**
+ * SQL query to retrieve second level items.
+ *
+ * @return string SQL.
+ */
protected function getSecondLevelServicesSql()
{
$group_acl = $this->getGroupAclCondition();
@@ -453,28 +664,16 @@ class TreeService extends Tree
}
- protected function getSecondLevelModulesSql()
- {
- $sql = "SELECT tse.id_agente_modulo, nombre AS `name`, nombre AS `alias`, tse.id_service AS `rootID`, 'services' AS `rootType`, 'modules' AS `type`, estado
- FROM tservice_element tse
- INNER JOIN tagente_modulo tam ON tse.id_agente_modulo=tam.id_agente_modulo
- INNER JOIN tagente_estado tae ON tam.id_agente_modulo=tae.id_agente_estado
- WHERE tse.id_service=$this->id AND tse.id_agente_modulo<>0
- ";
-
- return $sql;
- }
-
-
- protected function getAgentStatusFilter($status=self::TV_DEFAULT_AGENT_STATUS)
- {
- return '';
- }
-
-
+ /**
+ * Retrieve SQL filter for current filte.r
+ *
+ * @return string SQL filter.
+ */
protected function getServiceFavouriteFilter()
{
- if (isset($this->filter['is_favourite']) && !empty($this->filter['is_favourite'])) {
+ if (isset($this->filter['is_favourite']) === true
+ && empty($this->filter['is_favourite']) === false
+ ) {
return ' AND is_favourite = 1';
}
@@ -482,4 +681,70 @@ class TreeService extends Tree
}
+ /**
+ * Overwrites partial functionality of general Tree.class.
+ *
+ * @param array $module Data of given module.
+ *
+ * @return array Complementary information.
+ */
+ protected function getModuleGraphLinks(array $module)
+ {
+ $graphType = return_graphtype($module['id_module_type']);
+ $url = ui_get_full_url(
+ 'operation/agentes/stat_win.php',
+ false,
+ false,
+ false
+ );
+ $winHandle = dechex(crc32($module['id'].$module['name']));
+
+ $graph_params = [
+ 'type' => $graphType,
+ 'period' => SECONDS_1DAY,
+ 'id' => $module['id'],
+ 'refresh' => SECONDS_10MINUTES,
+ ];
+
+ if (is_metaconsole() === true) {
+ // Set the server id.
+ $graph_params['server'] = $module['serverID'];
+ }
+
+ $graph_params_str = http_build_query($graph_params);
+ $moduleGraphURL = $url.'?'.$graph_params_str;
+
+ return [
+ 'moduleGraph' => [
+ 'url' => $moduleGraphURL,
+ 'handle' => $winHandle,
+ ],
+ 'snapshot' => ui_get_snapshot_link(
+ [
+ 'id_module' => $module['id'],
+ 'interval' => $module['current_interval'],
+ 'module_name' => $module['name'],
+ 'id_node' => (($module['serverID'] > 0) ? $module['serverID'] : 0),
+ ],
+ true
+ ),
+ ];
+
+ }
+
+
+ /**
+ * Needs to be defined to maintain Tree view functionality.
+ *
+ * @param integer $status Status.
+ *
+ * @return string Fixed string.
+ */
+ protected function getAgentStatusFilter(
+ $status=self::TV_DEFAULT_AGENT_STATUS
+ ) {
+ return '';
+ }
+
+
}
diff --git a/pandora_console/include/lib/Module.php b/pandora_console/include/lib/Module.php
index 3076455d81..48240ca288 100644
--- a/pandora_console/include/lib/Module.php
+++ b/pandora_console/include/lib/Module.php
@@ -393,6 +393,99 @@ class Module extends Entity
}
+ /**
+ * Retrieves last status in text format.
+ *
+ * @return string Status in text format.
+ */
+ public function lastStatusText()
+ {
+ switch ($this->lastStatus()) {
+ case AGENT_MODULE_STATUS_CRITICAL_ALERT:
+ case AGENT_MODULE_STATUS_CRITICAL_BAD:
+ return 'critical';
+
+ case AGENT_MODULE_STATUS_WARNING_ALERT:
+ case AGENT_MODULE_STATUS_WARNING:
+ return 'warning';
+
+ case AGENT_MODULE_STATUS_UNKNOWN:
+ return 'unknown';
+
+ case AGENT_MODULE_STATUS_NO_DATA:
+ case AGENT_MODULE_STATUS_NOT_INIT:
+ return 'not_init';
+
+ case AGENT_MODULE_STATUS_NORMAL_ALERT:
+ case AGENT_MODULE_STATUS_NORMAL:
+ default:
+ return 'ok';
+ }
+ }
+
+
+ /**
+ * Return path to image representing last status.
+ *
+ * @return string Relative URL to image.
+ */
+ public function lastStatusImage()
+ {
+ switch ($this->lastStatus()) {
+ case AGENT_MODULE_STATUS_CRITICAL_ALERT:
+ case AGENT_MODULE_STATUS_CRITICAL_BAD:
+ return STATUS_MODULE_CRITICAL_BALL;
+
+ case AGENT_MODULE_STATUS_WARNING_ALERT:
+ case AGENT_MODULE_STATUS_WARNING:
+ return STATUS_MODULE_WARNING_BALL;
+
+ case AGENT_MODULE_STATUS_UNKNOWN:
+ return STATUS_MODULE_UNKNOWN_BALL;
+
+ case AGENT_MODULE_STATUS_NO_DATA:
+ case AGENT_MODULE_STATUS_NOT_INIT:
+ return STATUS_MODULE_NO_DATA_BALL;
+
+ case AGENT_MODULE_STATUS_NORMAL_ALERT:
+ case AGENT_MODULE_STATUS_NORMAL:
+ default:
+ return STATUS_MODULE_OK_BALL;
+ }
+ }
+
+
+ /**
+ * Return translated string representing last status of the module.
+ *
+ * @return string Title.
+ */
+ public function lastStatusTitle()
+ {
+ switch ($this->lastStatus()) {
+ case AGENT_MODULE_STATUS_CRITICAL_ALERT:
+ case AGENT_MODULE_STATUS_CRITICAL_BAD:
+ return __('CRITICAL');
+
+ case AGENT_MODULE_STATUS_WARNING_ALERT:
+ case AGENT_MODULE_STATUS_WARNING:
+ return __('WARNING');
+
+ case AGENT_MODULE_STATUS_UNKNOWN:
+ return __('UNKNOWN');
+
+ case AGENT_MODULE_STATUS_NO_DATA:
+ case AGENT_MODULE_STATUS_NOT_INIT:
+ return __('NO DATA');
+
+ case AGENT_MODULE_STATUS_NORMAL_ALERT:
+ case AGENT_MODULE_STATUS_NORMAL:
+ default:
+ return __('NORMAL');
+ }
+ }
+
+
/**
* Sets or retrieves value of id_tipo_modulo (complex).
*
diff --git a/pandora_server/lib/PandoraFMS/PredictionServer.pm b/pandora_server/lib/PandoraFMS/PredictionServer.pm
index 361eb338e2..6f77845456 100644
--- a/pandora_server/lib/PandoraFMS/PredictionServer.pm
+++ b/pandora_server/lib/PandoraFMS/PredictionServer.pm
@@ -105,7 +105,7 @@ sub data_producer ($) {
AND tagente_modulo.id_modulo = 5
AND (tagente_modulo.flag = 1
OR (tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())
- ORDER BY last_execution_try ASC ', (is_metaconsole($pa_config) ? '' : safe_input($pa_config->{'servername'})));
+ ORDER BY last_execution_try ASC ', safe_input($pa_config->{'servername'}));
}
else {
@rows = get_db_rows ($dbh, 'SELECT DISTINCT(tagente_modulo.id_agente_modulo),
@@ -123,7 +123,7 @@ sub data_producer ($) {
AND tagente_modulo.id_modulo = 5
AND (tagente_modulo.flag = 1
OR (tagente_estado.last_execution_try + tagente_estado.current_interval) < UNIX_TIMESTAMP())
- ORDER BY last_execution_try ASC', (is_metaconsole($pa_config) ? '' : safe_input($pa_config->{'servername'})), PREDICTIONSERVER);
+ ORDER BY last_execution_try ASC', safe_input($pa_config->{'servername'}), PREDICTIONSERVER);
}
foreach my $row (@rows) {