From ea513994607b6869d006248db9a70d90da18c727 Mon Sep 17 00:00:00 2001 From: Daniel Cebrian Date: Wed, 1 Mar 2023 17:27:32 +0100 Subject: [PATCH] #10347 create view tactic for groups with monitoring and alerts --- pandora_console/godmode/groups/tactical.php | 189 ++++++++ pandora_console/include/functions_graph.php | 177 +++++++ pandora_console/include/functions_groups.php | 447 ++++++++++++++++-- .../include/javascript/tactical_groups.js | 1 + pandora_console/include/lib/Group.php | 34 +- .../include/styles/tactical_groups.css | 15 + 6 files changed, 831 insertions(+), 32 deletions(-) create mode 100644 pandora_console/godmode/groups/tactical.php create mode 100644 pandora_console/include/javascript/tactical_groups.js create mode 100644 pandora_console/include/styles/tactical_groups.css diff --git a/pandora_console/godmode/groups/tactical.php b/pandora_console/godmode/groups/tactical.php new file mode 100644 index 0000000000..7f095f8472 --- /dev/null +++ b/pandora_console/godmode/groups/tactical.php @@ -0,0 +1,189 @@ + '', + 'label' => __('Monitoring'), + ], + [ + 'link' => '', + 'label' => __('Tactic group'), + ], + ] + ); +} + +ui_require_css_file('tactical_groups'); +ui_require_javascript_file('tactical_groups'); +$groups = groups_get_children($id_group); +$id_groups = []; +if (count($groups) > 0) { + foreach ($groups as $key => $value) { + $id_groups[] = $value['id_grupo']; + } +} else { + $id_groups[] = $id_group; +} + + +echo '
'; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo ''; +echo '
'; +$table_col1 = new stdClass(); +$table_col1->class = 'no-class'; +$table_col1->data = []; +$table_col1->rowclass[] = ''; +$table_col1->headstyle[0] = 'text-align:center;'; +$table_col1->width = '100%'; +$table_col1->data[0][0] = groups_get_heat_map_agents($id_groups, 320, 100); +$table_col1->data[1][0] = tactical_groups_get_agents_and_monitoring($id_groups); + +$distribution_by_so = '
'; +$distribution_by_so .= '
'; +$distribution_by_so .= ''.__('Distribution by so').''; +$distribution_by_so .= html_print_image('images/spinner.gif', true, ['id' => 'spinner_distribution_by_so_graph']); +$distribution_by_so .= '
'; +$distribution_by_so .= '
'; + + +$table_col1->data[2][0] = $distribution_by_so; + + +ui_toggle( + html_print_table($table_col1, true), + __('Monitoring'), + '', + '', + false, + false +); + +echo '
'; +$table_col2 = new stdClass(); +$table_col2->class = 'no-class'; +$table_col2->data = []; +$table_col2->rowclass[] = ''; +$table_col2->headstyle[0] = 'text-align:center;'; +$table_col2->width = '100%'; +$table_col2->data[0][0] = tactical_groups_get_stats_alerts($id_groups); +$table_col2->data[1][0] = groups_get_stats_modules_status($id_groups); + +$events_by_agents_group = '
'; +$events_by_agents_group .= '
'; +$events_by_agents_group .= ''.__('Events by agent').''; +$events_by_agents_group .= html_print_image('images/spinner.gif', true, ['id' => 'spinner_events_by_agents_group_graph']); +$events_by_agents_group .= '
'; +$events_by_agents_group .= '
'; + + +$table_col2->data[2][0] = $events_by_agents_group; +ui_toggle( + html_print_table($table_col2, true), + __('Alerts'), + '', + '', + false, + false +); +echo '
'; +$table_col3 = new stdClass(); +$table_col3->class = 'no-class'; +$table_col3->data = []; +$table_col3->rowclass[] = ''; +$table_col3->headstyle[0] = 'text-align:center;'; +$table_col3->width = '100%'; +$table_col3->data[0][0] = 'En desarrollo'; + + +ui_toggle( + html_print_table($table_col3, true), + __('Agents'), + '', + '', + false, + false +); +echo '
'; + + +?> + \ No newline at end of file diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index 0f6d03fee7..98ad504b54 100644 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -5339,3 +5339,180 @@ function get_baseline_data( $result['agent_alias'] = $array_data[0]['sum0']['agent_alias']; return ['sum0' => $result]; } + + +function graph_so_by_group($id_group, $width=300, $height=200, $recursive=true) +{ + global $config; + + $id_groups = [$id_group]; + + if ($recursive == true) { + $groups = groups_get_children($id_group); + if (count($groups) > 0) { + $id_groups = []; + foreach ($groups as $key => $value) { + $id_groups[] = $value['id_grupo']; + } + } + } + + $sql = sprintf( + 'SELECT COUNT(id_agente) AS count, + os.name + FROM tagente a + LEFT JOIN tconfig_os os ON a.id_os = os.id_os + WHERE a.id_grupo IN (%s) + GROUP BY os.id_os', + implode(',', $id_groups) + ); + + $result = db_get_all_rows_sql($sql, false, false); + if ($result === false) { + $result = []; + } + + $labels = []; + $data = []; + foreach ($result as $key => $row) { + $labels[] = $row['name']; + $data[] = $row['count']; + } + + $water_mark = [ + 'file' => $config['homedir'].'/images/logo_vertical_water.png', + 'url' => ui_get_full_url('images/logo_vertical_water.png', false, false, false), + ]; + + $options = [ + 'width' => $width, + 'height' => $height, + 'waterMark' => $water_mark, + 'legend' => [ + 'display' => true, + 'position' => 'right', + 'align' => 'center', + ], + 'labels' => $labels, + ]; + + return pie_graph( + $data, + $options + ); + +} + + +function graph_events_agent_by_group($id_group, $width=300, $height=200, $noWaterMark=true, $time_limit=false, $recursive=true) +{ + global $config; + + $data = []; + $labels = []; + $loop = 0; + define('NUM_PIECES_PIE_2', 6); + + // Add tags condition to filter. + $tags_condition = tags_get_acl_tags( + $config['id_user'], + 0, + 'ER', + 'event_condition', + 'AND' + ); + + if ($time_limit && $config['event_view_hr']) { + $tags_condition .= ' AND utimestamp > (UNIX_TIMESTAMP(NOW()) - '.($config['event_view_hr'] * SECONDS_1HOUR).')'; + } + + $id_groups = [$id_group]; + if ($recursive === true) { + $groups = groups_get_children($id_group); + if (count($groups) > 0) { + $id_groups = []; + foreach ($groups as $key => $value) { + $id_groups[] = $value['id_grupo']; + } + } + } + + $filter_groups = ' AND te.id_grupo IN ('.implode(',', $id_groups).') '; + + // This will give the distinct id_agente, give the id_grupo that goes + // with it and then the number of times it occured. GROUP BY statement + // is required if both DISTINCT() and COUNT() are in the statement. + $sql = sprintf( + 'SELECT DISTINCT(id_agente) AS id_agente, + COUNT(id_agente) AS count + FROM tevento te + WHERE 1=1 AND estado = 0 %s %s + GROUP BY id_agente + ORDER BY count DESC LIMIT 8', + $tags_condition, + $filter_groups + ); + $result = db_get_all_rows_sql($sql, false, false); + if ($result === false) { + $result = []; + } + + $system_events = 0; + $other_events = 0; + + foreach ($result as $row) { + $row['id_grupo'] = agents_get_agent_group($row['id_agente']); + if (!check_acl($config['id_user'], $row['id_grupo'], 'ER') == 1) { + continue; + } + + if ($loop >= NUM_PIECES_PIE_2) { + $other_events += $row['count']; + } else { + if ($row['id_agente'] == 0) { + $system_events += $row['count']; + } else { + $alias = agents_get_alias($row['id_agente']); + $name = mb_substr($alias, 0, 25).' #'.$row['id_agente'].' ('.$row['count'].')'; + $labels[] = io_safe_output($name); + $data[] = $row['count']; + } + } + + $loop++; + } + + if ($system_events > 0) { + $name = __('SYSTEM').' ('.$system_events.')'; + $labels[] = io_safe_output($name); + $data[] = $system_events; + } + + // Sort the data. + arsort($data); + if ($noWaterMark) { + $water_mark = [ + 'file' => $config['homedir'].'/images/logo_vertical_water.png', + 'url' => ui_get_full_url('images/logo_vertical_water.png', false, false, false), + ]; + } else { + $water_mark = []; + } + + $options = [ + 'width' => $width, + 'height' => $height, + 'waterMark' => $water_mark, + 'legend' => [ + 'display' => true, + 'position' => 'right', + 'align' => 'center', + ], + 'labels' => $labels, + ]; + + return pie_graph( + $data, + $options + ); +} diff --git a/pandora_console/include/functions_groups.php b/pandora_console/include/functions_groups.php index 20841bf26a..752ec4396a 100644 --- a/pandora_console/include/functions_groups.php +++ b/pandora_console/include/functions_groups.php @@ -1276,7 +1276,7 @@ function groups_get_not_init_agents($group, $agent_filter=[], $module_filter=[], * * @return integer Number of monitors. */ -function groups_get_monitors_counter($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false) +function groups_get_monitors_counter($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false, $secondary_group=true) { if (empty($group)) { return 0; @@ -1291,7 +1291,11 @@ function groups_get_monitors_counter($group, $agent_filter=[], $module_filter=[] } $group_str = implode(',', $groups); - $groups_clause = "AND (ta.id_grupo IN ($group_str) OR tasg.id_group IN ($group_str))"; + if ($secondary_group === true) { + $groups_clause = "AND (ta.id_grupo IN ($group_str) OR tasg.id_group IN ($group_str))"; + } else { + $groups_clause = "AND (ta.id_grupo IN ($group_str))"; + } $tags_clause = ''; @@ -1401,10 +1405,12 @@ function groups_get_monitors_counter($group, $agent_filter=[], $module_filter=[] ON tam.id_agente_modulo = tae.id_agente_modulo $modules_clause INNER JOIN tagente ta - ON tam.id_agente = ta.id_agente - LEFT JOIN tagent_secondary_group tasg - ON ta.id_agente = tasg.id_agent - AND ta.disabled = 0 + ON tam.id_agente = ta.id_agente"; + if ($secondary_group === true) { + $sql .= ' LEFT JOIN tagent_secondary_group tasg ON ta.id_agente = tasg.id_agent'; + } + + $sql .= "AND ta.disabled = 0 $agent_name_filter $agents_clause WHERE tam.disabled = 0 @@ -1450,8 +1456,9 @@ function groups_get_monitors_counter($group, $agent_filter=[], $module_filter=[] } $status_columns_str = implode(',', $status_columns_array); + $status_columns_str_sum = implode('+', $status_columns_array); - $sql = "SELECT SUM($status_columns_str) FROM + $sql = "SELECT SUM($status_columns_str_sum) FROM (SELECT DISTINCT(ta.id_agente), $status_columns_str FROM tagente ta LEFT JOIN tagent_secondary_group tasg ON ta.id_agente = tasg.id_agent @@ -1486,11 +1493,11 @@ function groups_get_monitors_counter($group, $agent_filter=[], $module_filter=[] * * @return integer Number of monitors. */ -function groups_get_total_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false) +function groups_get_total_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false, $secondary_group=true) { // Always modify the module status filter $module_filter['status'] = AGENT_MODULE_STATUS_ALL; - return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime); + return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime, $secondary_group); } @@ -1511,11 +1518,11 @@ function groups_get_total_monitors($group, $agent_filter=[], $module_filter=[], * * @return integer Number of monitors. */ -function groups_get_normal_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false) +function groups_get_normal_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false, $secondary_group=true) { // Always modify the module status filter $module_filter['status'] = AGENT_MODULE_STATUS_NORMAL; - return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime); + return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime, $secondary_group); } @@ -1536,11 +1543,11 @@ function groups_get_normal_monitors($group, $agent_filter=[], $module_filter=[], * * @return integer Number of monitors. */ -function groups_get_critical_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false) +function groups_get_critical_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false, $secondary_group=true) { // Always modify the module status filter $module_filter['status'] = AGENT_MODULE_STATUS_CRITICAL_BAD; - return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime); + return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime, $secondary_group); } @@ -1561,11 +1568,11 @@ function groups_get_critical_monitors($group, $agent_filter=[], $module_filter=[ * * @return integer Number of monitors. */ -function groups_get_warning_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false) +function groups_get_warning_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false, $secondary_group=true) { // Always modify the module status filter $module_filter['status'] = AGENT_MODULE_STATUS_WARNING; - return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime); + return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime, $secondary_group); } @@ -1586,11 +1593,11 @@ function groups_get_warning_monitors($group, $agent_filter=[], $module_filter=[] * * @return integer Number of monitors. */ -function groups_get_unknown_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false) +function groups_get_unknown_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false, $secondary_group=true) { // Always modify the module status filter $module_filter['status'] = AGENT_MODULE_STATUS_UNKNOWN; - return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime); + return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime, $secondary_group); } @@ -1611,11 +1618,11 @@ function groups_get_unknown_monitors($group, $agent_filter=[], $module_filter=[] * * @return integer Number of monitors. */ -function groups_get_not_init_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false) +function groups_get_not_init_monitors($group, $agent_filter=[], $module_filter=[], $strict_user=false, $groups_and_tags=false, $realtime=false, $secondary_group=true) { // Always modify the module status filter $module_filter['status'] = AGENT_MODULE_STATUS_NOT_INIT; - return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime); + return groups_get_monitors_counter($group, $agent_filter, $module_filter, $strict_user, $groups_and_tags, $realtime, $secondary_group); } @@ -1746,7 +1753,7 @@ function groups_monitor_total_counters($group_array, $search_in_testado=false) } -function groups_agents_total_counters($group_array) +function groups_agents_total_counters($group_array, $secondary_groups=true) { $default_total = [ 'ok' => 0, @@ -1763,30 +1770,36 @@ function groups_agents_total_counters($group_array) } $group_clause = implode(',', $group_array); - $group_clause = "(tasg.id_group IN ($group_clause) OR ta.id_grupo IN ($group_clause))"; + if ($secondary_groups === true) { + $group_clause = "(tasg.id_group IN ($group_clause) OR ta.id_grupo IN ($group_clause))"; + } else { + $group_clause = "(ta.id_grupo IN ($group_clause))"; + } $condition_critical = agents_get_status_clause(AGENT_STATUS_CRITICAL); $condition_warning = agents_get_status_clause(AGENT_STATUS_WARNING); $condition_unknown = agents_get_status_clause(AGENT_STATUS_UNKNOWN); $condition_not_init = agents_get_status_clause(AGENT_STATUS_NOT_INIT); $condition_normal = agents_get_status_clause(AGENT_STATUS_NORMAL); + $sql = "SELECT SUM(IF($condition_normal, 1, 0)) AS ok, SUM(IF($condition_critical, 1, 0)) AS critical, SUM(IF($condition_warning, 1, 0)) AS warning, SUM(IF($condition_unknown, 1, 0)) AS unknown, SUM(IF($condition_not_init, 1, 0)) AS not_init, COUNT(ta.id_agente) AS total - FROM tagente ta - WHERE ta.disabled = 0 + FROM tagente ta + WHERE ta.disabled = 0 AND ta.id_agente IN ( - SELECT ta.id_agente FROM tagente ta - LEFT JOIN tagent_secondary_group tasg - ON ta.id_agente = tasg.id_agent - WHERE ta.disabled = 0 - AND $group_clause - GROUP BY ta.id_agente - ) - "; + SELECT ta.id_agente FROM tagente ta"; + if ($secondary_groups === true) { + $sql .= ' LEFT JOIN tagent_secondary_group tasg ON ta.id_agente = tasg.id_agent'; + } + + $sql .= " WHERE ta.disabled = 0 + AND $group_clause + GROUP BY ta.id_agente + )"; $agents = db_get_row_sql($sql); @@ -2438,3 +2451,375 @@ function groups_get_group_deep($id_group) return $deep; } + + +function groups_get_heat_map_agents(array $id_group, float $width=0, float $height=0) +{ + ui_require_css_file('heatmap'); + + if (is_array($id_group) === false) { + $id_group = [$id_group]; + } + + $sql = 'SELECT * FROM tagente WHERE id_grupo IN('.implode(',', $id_group).')'; + + $all_agents = db_get_all_rows_sql($sql); + hd($sql, true); + 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. + $html = sprintf( + '', + $id_group, + $width, + $height + ); + + $html .= ''; + $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; + } + + $html .= 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++; + } + ?> + + '; + $html .= ''; + + return $html; +} + + +function tactical_groups_get_agents_and_monitoring($id_groups) +{ + global $config; + + $data = [ + 'total_agents' => groups_agents_total_counters($id_groups, false)['total'], + 'monitor_total' => groups_get_total_monitors($id_groups, [], [], false, false, false, false), + ]; + + // Link URLS + $urls = []; + $urls['total_agents'] = $config['homeurl'].'index.php?sec=estado&sec2=operation/agentes/estado_agente&refr=60'; + $urls['monitor_total'] = $config['homeurl'].'index.php?sec=view&sec2=operation/agentes/status_monitor&refr=60&status=-1'; + + $table_am = html_get_predefined_table(); + $tdata = []; + $tdata[0] = html_print_image('images/agent.png', true, ['title' => __('Total agents'), 'class' => 'invert_filter'], false, false, false, true); + $tdata[1] = $data['total_agents'] <= 0 ? '-' : $data['total_agents']; + $tdata[1] = ''.$tdata[1].''; + + if ($data['total_agents'] > 500 && !enterprise_installed()) { + $tdata[2] = "
"; + } + + $tdata[3] = html_print_image('images/module.png', true, ['title' => __('Monitor checks'), 'class' => 'invert_filter'], false, false, false, true); + $tdata[4] = $data['monitor_total'] <= 0 ? '-' : $data['monitor_total']; + $tdata[4] = ''.$tdata[4].''; + + /* + Hello there! :) + We added some of what seems to be "buggy" messages to the openSource version recently. This is not to force open-source users to move to the enterprise version, this is just to inform people using Pandora FMS open source that it requires skilled people to maintain and keep it running smoothly without professional support. This does not imply open-source version is limited in any way. If you check the recently added code, it contains only warnings and messages, no limitations except one: we removed the option to add custom logo in header. In the Update Manager section, it warns about the 'danger’ of applying automated updates without a proper backup, remembering in the process that the Enterprise version comes with a human-tested package. Maintaining an OpenSource version with more than 500 agents is not so easy, that's why someone using a Pandora with 8000 agents should consider asking for support. It's not a joke, we know of many setups with a huge number of agents, and we hate to hear that “its becoming unstable and slow” :( + You can of course remove the warnings, that's why we include the source and do not use any kind of trick. And that's why we added here this comment, to let you know this does not reflect any change in our opensource mentality of does the last 14 years. + */ + if ($data['total_agents']) { + if (($data['monitor_total'] / $data['total_agents'] > 100) && !enterprise_installed()) { + $tdata[5] = "
"; + } + } + + $table_am->rowclass[] = ''; + $table_am->data[] = $tdata; + + $output = '
+ '.__('Total agents and monitors').''.html_print_table($table_am, true).'
'; + + return $output; +} + + +function tactical_groups_get_stats_alerts($id_groups) +{ + global $config; + + $alerts = groups_monitor_alerts_total_counters($id_groups); + $data = [ + 'monitor_alerts' => $alerts['total'], + 'monitor_alerts_fired' => $alerts['fired'], + + ]; + + $urls = []; + $urls['monitor_alerts'] = $config['homeurl'].'index.php?sec=estado&sec2=operation/agentes/alerts_status&refr=60'; + $urls['monitor_alerts_fired'] = $config['homeurl'].'index.php?sec=estado&sec2=operation/agentes/alerts_status&refr=60&disabled=fired'; + + // Alerts table. + $table_al = html_get_predefined_table(); + + $tdata = []; + $tdata[0] = html_print_image('images/bell.png', true, ['title' => __('Defined alerts'), 'class' => 'invert_filter'], false, false, false, true); + $tdata[1] = $data['monitor_alerts'] <= 0 ? '-' : $data['monitor_alerts']; + $tdata[1] = ''.$tdata[1].''; + + /* + Hello there! :) + We added some of what seems to be "buggy" messages to the openSource version recently. This is not to force open-source users to move to the enterprise version, this is just to inform people using Pandora FMS open source that it requires skilled people to maintain and keep it running smoothly without professional support. This does not imply open-source version is limited in any way. If you check the recently added code, it contains only warnings and messages, no limitations except one: we removed the option to add custom logo in header. In the Update Manager section, it warns about the 'danger’ of applying automated updates without a proper backup, remembering in the process that the Enterprise version comes with a human-tested package. Maintaining an OpenSource version with more than 500 agents is not so easy, that's why someone using a Pandora with 8000 agents should consider asking for support. It's not a joke, we know of many setups with a huge number of agents, and we hate to hear that “its becoming unstable and slow” :( + You can of course remove the warnings, that's why we include the source and do not use any kind of trick. And that's why we added here this comment, to let you know this does not reflect any change in our opensource mentality of does the last 14 years. + */ + + if ($data['monitor_alerts'] > $data['total_agents'] && !enterprise_installed()) { + $tdata[2] = "
"; + } + + $tdata[3] = html_print_image( + 'images/bell_error.png', + true, + [ + 'title' => __('Fired alerts'), + 'class' => 'invert_filter', + ], + false, + false, + false, + true + ); + $tdata[4] = $data['monitor_alerts_fired'] <= 0 ? '-' : $data['monitor_alerts_fired']; + $tdata[4] = ''.$tdata[4].''; + $table_al->rowclass[] = ''; + $table_al->data[] = $tdata; + + if (!is_metaconsole()) { + $output = '
+ '.__('Defined and fired alerts').''.html_print_table($table_al, true).'
'; + } else { + // Remove the defined alerts cause with the new cache table is difficult to retrieve them. + unset($table_al->data[0][0], $table_al->data[0][1]); + + $table_al->class = 'tactical_view'; + $table_al->style = []; + $output = '
+ '.__('Fired alerts').''.html_print_table($table_al, true).'
'; + } + + return $output; +} + + +function groups_get_stats_modules_status($id_groups, $graph_width=250, $graph_height=150, $links=false, $data_agents=false) +{ + global $config; + + $data = [ + 'monitor_critical' => groups_get_critical_monitors($id_groups, [], [], false, false, false, false), + 'monitor_warning' => groups_get_warning_monitors($id_groups, [], [], false, false, false, false), + 'monitor_ok' => groups_get_normal_monitors($id_groups, [], [], false, false, false, false), + 'monitor_unknown' => groups_get_unknown_monitors($id_groups, [], [], false, false, false, false), + 'monitor_not_init' => groups_get_not_init_monitors($id_groups, [], [], false, false, false, false), + ]; + + // Link URLS. + if ($links === false) { + $urls = []; + $urls['monitor_critical'] = $config['homeurl'].'index.php?'.'sec=view&sec2=operation/agentes/status_monitor&'.'refr=60&status='.AGENT_MODULE_STATUS_CRITICAL_BAD.'&pure='.$config['pure'].'&recursion=1&ag_group='.$id_group; + $urls['monitor_warning'] = $config['homeurl'].'index.php?'.'sec=view&sec2=operation/agentes/status_monitor&'.'refr=60&status='.AGENT_MODULE_STATUS_WARNING.'&pure='.$config['pure'].'&recursion=1&ag_group='.$id_group; + $urls['monitor_ok'] = $config['homeurl'].'index.php?'.'sec=view&sec2=operation/agentes/status_monitor&'.'refr=60&status='.AGENT_MODULE_STATUS_NORMAL.'&pure='.$config['pure'].'&recursion=1&ag_group='.$id_group; + $urls['monitor_unknown'] = $config['homeurl'].'index.php?'.'sec=view&sec2=operation/agentes/status_monitor&'.'refr=60&status='.AGENT_MODULE_STATUS_UNKNOWN.'&pure='.$config['pure'].'&recursion=1&ag_group='.$id_group; + $urls['monitor_not_init'] = $config['homeurl'].'index.php?'.'sec=view&sec2=operation/agentes/status_monitor&'.'refr=60&status='.AGENT_MODULE_STATUS_NOT_INIT.'&pure='.$config['pure'].'&recursion=1&ag_group='.$id_group; + } else { + $urls = []; + $urls['monitor_critical'] = $links['monitor_critical']; + $urls['monitor_warning'] = $links['monitor_warning']; + $urls['monitor_ok'] = $links['monitor_ok']; + $urls['monitor_unknown'] = $links['monitor_unknown']; + $urls['monitor_not_init'] = $links['monitor_not_init']; + } + + // Fixed width non interactive charts + $status_chart_width = $graph_width; + + // Modules by status table + $table_mbs = html_get_predefined_table(); + + $tdata = []; + $tdata[0] = html_print_image('images/module_critical.png', true, ['title' => __('Monitor critical')], false, false, false, true); + $tdata[1] = $data['monitor_critical'] <= 0 ? '-' : $data['monitor_critical']; + $tdata[1] = ''.$tdata[1].''; + + $tdata[2] = html_print_image('images/module_warning.png', true, ['title' => __('Monitor warning')], false, false, false, true); + $tdata[3] = $data['monitor_warning'] <= 0 ? '-' : $data['monitor_warning']; + $tdata[3] = ''.$tdata[3].''; + $table_mbs->rowclass[] = ''; + $table_mbs->data[] = $tdata; + + $tdata = []; + $tdata[0] = html_print_image('images/module_ok.png', true, ['title' => __('Monitor normal')], false, false, false, true); + $tdata[1] = $data['monitor_ok'] <= 0 ? '-' : $data['monitor_ok']; + $tdata[1] = ''.$tdata[1].''; + + $tdata[2] = html_print_image('images/module_unknown.png', true, ['title' => __('Monitor unknown')], false, false, false, true); + $tdata[3] = $data['monitor_unknown'] <= 0 ? '-' : $data['monitor_unknown']; + $tdata[3] = ''.$tdata[3].''; + $table_mbs->rowclass[] = ''; + $table_mbs->data[] = $tdata; + + $tdata = []; + $tdata[0] = html_print_image('images/module_notinit.png', true, ['title' => __('Monitor not init')], false, false, false, true); + $tdata[1] = $data['monitor_not_init'] <= 0 ? '-' : $data['monitor_not_init']; + $tdata[1] = ''.$tdata[1].''; + + $tdata[2] = $tdata[3] = ''; + $table_mbs->rowclass[] = ''; + $table_mbs->data[] = $tdata; + + if ($data['monitor_checks'] > 0) { + $tdata = []; + $table_mbs->colspan[count($table_mbs->data)][0] = 4; + $table_mbs->cellstyle[count($table_mbs->data)][0] = 'text-align: center;'; + $tdata[0] = '
'.'
'.graph_agent_status(false, $graph_width, $graph_height, true, true, $data_agents).'
'; + $table_mbs->rowclass[] = ''; + $table_mbs->data[] = $tdata; + } + + if (!is_metaconsole()) { + $output = ' +
+ '.__('Monitors by status').''.html_print_table($table_mbs, true).'
'; + } else { + $table_mbs->class = 'tactical_view'; + $table_mbs->style = []; + $output = ' +
+ '.__('Monitors by status').''.html_print_table($table_mbs, true).'
'; + } + + return $output; +} + + +function groups_get_agents_group($id_groups) +{ + global $config; + + if (is_array($id_groups) === false) { + $id_groups = [$id_groups]; + } + + if ($rows === false) { + $rows = []; + } + + return $rows; +} \ No newline at end of file diff --git a/pandora_console/include/javascript/tactical_groups.js b/pandora_console/include/javascript/tactical_groups.js new file mode 100644 index 0000000000..cf2a8ca42d --- /dev/null +++ b/pandora_console/include/javascript/tactical_groups.js @@ -0,0 +1 @@ +function showInfoAgent(id_agent) {} diff --git a/pandora_console/include/lib/Group.php b/pandora_console/include/lib/Group.php index 1f34f941fd..745b1e4039 100644 --- a/pandora_console/include/lib/Group.php +++ b/pandora_console/include/lib/Group.php @@ -43,7 +43,11 @@ class Group extends Entity * * @var array */ - private static $ajaxMethods = ['getGroupsForSelect']; + private static $ajaxMethods = [ + 'getGroupsForSelect', + 'distributionBySoGraph', + 'groupEventsByAgent', + ]; /** @@ -473,4 +477,32 @@ class Group extends Entity } + public static function distributionBySoGraph() + { + global $config; + $id_group = get_parameter('id_group', ''); + include_once $config['homedir'].'/include/functions_graph.php'; + + $out = '
'; + $out .= graph_so_by_group($id_group); + $out .= '
'; + echo $out; + return; + } + + + public static function groupEventsByAgent() + { + global $config; + $id_group = get_parameter('id_group', ''); + include_once $config['homedir'].'/include/functions_graph.php'; + + $out = '
'; + $out .= graph_events_agent_by_group($id_group, 300, 200, true, true); + $out .= '
'; + echo $out; + return; + } + + } diff --git a/pandora_console/include/styles/tactical_groups.css b/pandora_console/include/styles/tactical_groups.css new file mode 100644 index 0000000000..423292a336 --- /dev/null +++ b/pandora_console/include/styles/tactical_groups.css @@ -0,0 +1,15 @@ +.tactical_group_left_column { + vertical-align: top; + min-width: 30em; + width: 30%; + padding-top: 0px; +} +.tactical_group_right_column { + width: 40%; + vertical-align: top; + min-width: 30em; + padding-top: 0px; +} +rect { + cursor: pointer; +}