diff --git a/pandora_console/ChangeLog b/pandora_console/ChangeLog index 6f68e9ef82..af7fd07656 100644 --- a/pandora_console/ChangeLog +++ b/pandora_console/ChangeLog @@ -1,3 +1,13 @@ +2011-10-26 Juan Manuel Ramon + + * include/functions_graph.php + include/functions_forecast.php + include/functions_reporting.php + include/functions.php + godmode/reporting/reporting_builder.php + godmode/reporting/reporting_builder.item_editor.php: Added two new + types of reports 'projection graph' and 'prediction date'. + 2011-10-25 Sergio Martin * godmode/agentes/module_manager_editor.php: Fixed keep_alive diff --git a/pandora_console/godmode/reporting/reporting_builder.item_editor.php b/pandora_console/godmode/reporting/reporting_builder.item_editor.php index 09c736c662..b807ce3466 100644 --- a/pandora_console/godmode/reporting/reporting_builder.item_editor.php +++ b/pandora_console/godmode/reporting/reporting_builder.item_editor.php @@ -51,7 +51,13 @@ $exception_condition = 0; $exception_condition_value = 10; $modulegroup = 0; $period = 86400; +// Added support for projection graphs +$period_pg = 432000; +$projection_period = 432000; $only_display_wrong = 0; +// Added support for prediction date report +$min_interval = 0; +$max_interval = 0; $monday = true; $tuesday = true; $wednesday = true; @@ -90,6 +96,7 @@ switch ($action) { $show_in_two_columns = $style['show_in_two_columns']; $show_in_landscape = $style['show_in_landscape']; $type = $item['type']; + switch ($type) { case 'avg_value': $period = $item['period']; @@ -99,10 +106,26 @@ switch ($action) { break; case 'simple_baseline_graph': case 'simple_graph': + case 'projection_graph': $description = $item['description']; $idAgentModule = $item['id_agent_module']; $idAgent = db_get_value_filter('id_agente', 'tagente_modulo', array('id_agente_modulo' => $idAgentModule)); $period = $item['period']; + // 'top_n_value' field will be reused for projection report + if ($type == 'projection_graph'){ + $projection_period = $item['top_n_value']; + $period_pg = $item['period']; + } + break; + case 'prediction_date': + $description = $item['description']; + $idAgentModule = $item['id_agent_module']; + $idAgent = db_get_value_filter('id_agente', 'tagente_modulo', array('id_agente_modulo' => $idAgentModule)); + // 'top_n' field will be reused for prediction_date report + $max_interval = $item['top_n']; + // 'top_n_value' field will be reused for prediction_date report + $min_interval = $item['top_n_value']; + $period_pg = $item['period']; break; case 'custom_graph': $description = $item['description']; @@ -297,6 +320,19 @@ $intervals[432000] = human_time_description_raw (432000); $intervals[1296000] = human_time_description_raw (1296000); $intervals[2592000] = human_time_description_raw (2592000); +// Intervals for projection graph +$intervals_1 = array (); +/*$intervals_1[300] = human_time_description_raw (300); +$intervals_1[600] = human_time_description_raw (600); +$intervals_1[86400] = human_time_description_raw (86400);*/ +$intervals_1[432000] = human_time_description_raw (432000); +$intervals_1[1296000] = human_time_description_raw (1296000); +$intervals_1[2592000] = human_time_description_raw (2592000); +$intervals_1[5184000] = human_time_description_raw (5184000); +$intervals_1[7776000] = human_time_description_raw (7776000); +$intervals_1[10368000] = human_time_description_raw (10368000); +$intervals_1[12960000] = human_time_description_raw (12960000); + $urlForm = 'index.php?sec=greporting&sec2=godmode/reporting/reporting_builder&tab=item_editor&action=' . $actionParameter . '&id_report=' . $idReport; echo '
'; @@ -326,6 +362,23 @@ html_print_input_hidden('id_item', $idItem); + + + + + + + + + + + + @@ -384,7 +437,7 @@ html_print_input_hidden('id_item', $idItem); data = array(); + // Creates data for calculation + foreach ($module_data as $utimestamp => $row) { + if ($utimestamp == '') { continue; } + $data[0] = ''; + $data[1] = $cont; + $data[2] = date('d M Y H:i:s', $utimestamp); + $data[3] = $utimestamp; + $data[4] = $row['sum']; + $data[5] = $utimestamp * $row['sum']; + $data[6] = $utimestamp * $utimestamp; + $data[7] = $row['sum'] * $row['sum']; + if ($cont == 1){ + $data[8] = 0; + }else{ + $data[8] = $utimestamp - $last_timestamp; + } + + $sum_obs = $sum_obs + $cont; + $sum_xi = $sum_xi + $utimestamp; + $sum_yi = $sum_yi + $row['sum']; + $sum_xi_yi = $sum_xi_yi + $data[5]; + $sum_xi2 = $sum_xi2 + $data[6]; + $sum_yi2 = $sum_yi2 + $data[7]; + $sum_diff_dates = $sum_diff_dates + $data[8]; + $last_timestamp = $utimestamp; + $cont++; + + array_push($table->data, $data); + } + + $cont--; + + // Calculation over data above: + // 1. Calculation of linear correlation coefficient... + + // 1.1 Average for X: Sum(Xi)/Obs + // 1.2 Average for Y: Sum(Yi)/Obs + // 2. Covariance between vars + // 3.1 Standard deviation for X: sqrt((Sum(Xi²)/Obs) - (avg X)²) + // 3.2 Standard deviation for Y: sqrt((Sum(Yi²)/Obs) - (avg Y)²) + // Linear correlation coefficient: + + $avg_x = $cont/$sum_xi; + $avg_y = $cont/$sum_yi; + $covariance = $sum_xi_yi/$cont; + $dev_x = sqrt(($sum_xi2/$cont) - ($avg_x*$avg_x)); + $dev_y = sqrt(($sum_yi2/$cont) - ($avg_y*$avg_y)); + // Prevents division by zero + if ($dev_x != 0 and $dev_y != 0){ + $linear_coef = $covariance / ($dev_x * $dev_y); + } + // Agent interval could be zero, 300 is the predefined + ($sum_obs == 0)? $agent_interval = 300 : $agent_interval = $sum_diff_dates / $sum_obs; + + // Could be a inverse correlation coefficient + // if $linear_coef < 0.0 + // if $linear_coef >= -1.0 and $linear_coef <= -0.8999 + // Function variables have an inverse linear relathionship! + // else + // Function variables don't have an inverse linear relathionship! + + // Could be a direct correlation coefficient + // else + // if ($linear_coef >= 0.8999 and $linear_coef <= 1.0) { + // Function variables have a direct linear relathionship! + // else + // Function variables don't have a direct linear relathionship! + + // 2. Calculation of linear regresion... + + $b_num = (($cont * $sum_xi_yi) - ($sum_xi * $sum_yi)); + $b_den = (($cont * $sum_xi2) - ($sum_xi * $sum_xi)); + $b = $b_num / $b_den; + + $a_num = ($sum_yi) - ($b * $sum_xi); + $a = $a_num / $cont; + + // Data inicialization + $output_data = array(); + if ($prediction_period != false){ + $limit_timestamp = $last_timestamp + $prediction_period; + } + $current_ts = $last_timestamp; + $in_range = true; + + if ($period <= 3600) { + $title_period = __('Last hour'); + $time_format = 'G:i:s'; + } + elseif ($period <= 86400) { + $title_period = __('Last day'); + $time_format = 'G:i'; + } + elseif ($period <= 604800) { + $title_period = __('Last week'); + $time_format = 'M j'; + } + elseif ($period <= 2419200) { + $title_period = __('Last month'); + $time_format = 'M j'; + } + else { + $title_period = __('Last %s days', format_numeric (($period / (3600 * 24)), 2)); + $time_format = 'M j'; + } + + // Aplying linear regression to module data in order to do the prediction + $output_data = array(); + // Create data in graph format like + while ($in_range){ + $timestamp_f = date($time_format, $current_ts); + $output_data[$timestamp_f] = ($a + ($b * $current_ts)); + // Using this function for prediction_date + if ($prediction_period == false){ + // This statements stop the prediction when interval is greater than 4 years + if ($current_ts - $last_timestamp >= 126144000){ + return false; + } + // Found it + if ($max_value >= $output_data[$timestamp_f] and $min_value <= $output_data[$timestamp_f]){ + return $current_ts; + } + }else if ($current_ts > $limit_timestamp){ + $in_range = false; + } + $current_ts = $current_ts + $agent_interval; + } + + return $output_data; +} + +/** + * Return a date when the date interval is reached + * + * @param int Module id. + * @param int Max value in the interval. + * @param int Min value in the interval. + * + * @return mixed timestamp with the prediction date or false + */ +function forecast_prediction_date ($module_id, $max_value = 0, $min_value = 0){ + // Checks interval + if ($min_value > $max_value){ + return false; + } + + return forecast_projection_graph($module_id, 5184000, false, $max_value, $min_value); +} diff --git a/pandora_console/include/functions_graph.php b/pandora_console/include/functions_graph.php index 831ec401ef..a4e53322ea 100755 --- a/pandora_console/include/functions_graph.php +++ b/pandora_console/include/functions_graph.php @@ -71,6 +71,7 @@ function grafico_modulo_sparse ($agent_module_id, $period, $show_events, "utimestamp < $date", 'order' => 'utimestamp ASC'), array ('datos', 'utimestamp'), 'AND', true); + if ($data === false) { $data = array (); } @@ -213,7 +214,7 @@ function grafico_modulo_sparse ($agent_module_id, $period, $show_events, $timestamp_short = date($time_format, $timestamp); $long_index[$timestamp_short] = date( html_entity_decode($config['date_format'], ENT_QUOTES, "UTF-8"), $timestamp); - $timestamp = $timestamp_short; + //$timestamp = $timestamp_short; // Data if ($count > 0) { @@ -221,6 +222,8 @@ function grafico_modulo_sparse ($agent_module_id, $period, $show_events, $chart[$timestamp]['sum'] = $total; } else { + $chart[$timestamp]['utimestamp'] = $timestamp; + $chart[$timestamp]['datos'] = $total; $chart[$timestamp]['sum'] = $total; $chart[$timestamp]['min'] = $interval_min; $chart[$timestamp]['max'] = $interval_max; @@ -358,12 +361,14 @@ function grafico_modulo_sparse ($agent_module_id, $period, $show_events, * @param int Show alerts in graph (set to 1) * @param int Pure mode (without titles) (set to 1) * @param int Date to start of getting info. + * @param mixed If is a projection graph this parameter will be module data with prediction data (the projection) + * or false in other case. * * @return Mixed */ function graphic_combined_module ($module_list, $weight_list, $period, $width, $height, $title, $unit_name, $show_events = 0, $show_alerts = 0, $pure = 0, - $stacked = 0, $date = 0, $only_image = false, $homeurl = '', $ttl = 1) { + $stacked = 0, $date = 0, $only_image = false, $homeurl = '', $ttl = 1, $projection = false) { global $config; global $graphic_type; @@ -391,13 +396,35 @@ function graphic_combined_module ($module_list, $weight_list, $period, $width, $ $title_period = __('Last %s days', format_numeric (($period / (3600 * 24)), 2)); $time_format = 'M j'; } - + // Set variables if ($date == 0) $date = get_system_time(); $datelimit = $date - $period; $resolution = $config['graph_res'] * 50; //Number of points of the graph - $interval = (int) ($period / $resolution); - $module_number = count ($module_list); + $interval = (int) ($period / $resolution); + + // If projection graph, fill with zero previous data to projection interval + if ($projection != false){ + $j = $datelimit; + $in_range = true; + while ($in_range){ + $timestamp_f = date($time_format, $j); + //$timestamp_f = date('d M Y H:i:s', $j); + $before_projection[$timestamp_f] = 0; + + if ($j > $date){ + $in_range = false; + } + $j = $j + $interval; + } + } + + // Added support for projection graphs (normal_module + 1(prediction data)) + if ($projection !== false){ + $module_number = count ($module_list) + 1; + }else{ + $module_number = count ($module_list); + } // interval - This is the number of "rows" we are divided the time to fill data. // more interval, more resolution, and slower. @@ -431,17 +458,46 @@ function graphic_combined_module ($module_list, $weight_list, $period, $width, $ $long_index = array(); + if ($period <= 3600) { + $title_period = __('Last hour'); + $time_format = 'G:i:s'; + } elseif ($period <= 86400) { + $title_period = __('Last day'); + $time_format = 'G:i'; + } elseif ($period <= 604800) { + $title_period = __('Last week'); + $time_format = 'M j'; + } elseif ($period <= 2419200) { + $title_period = __('Last month'); + $time_format = 'M j'; + } else { + $title_period = __('Last %s days', format_numeric (($period / (3600 * 24)), 2)); + $time_format = 'M j'; + } + // Calculate data for each module for ($i = 0; $i < $module_number; $i++) { - - $agent_module_id = $module_list[$i]; - $agent_name = modules_get_agentmodule_agent_name ($agent_module_id); - $agent_id = agents_get_agent_id ($agent_name); - $module_name = modules_get_agentmodule_name ($agent_module_id); - $module_name_list[$i] = substr($agent_name, 0,80) ." / ".substr ($module_name, 0, 40); - $id_module_type = modules_get_agentmodule_type ($agent_module_id); - $module_type = modules_get_moduletype_name ($id_module_type); - $uncompressed_module = is_module_uncompressed ($module_type); + // If its a projection graph, first module will be data and second will be the projection + if ($projection != false and $i != 0){ + $agent_module_id = $module_list[0]; + $agent_name = modules_get_agentmodule_agent_name ($agent_module_id); + $agent_id = agents_get_agent_id ($agent_name); + $module_name = "projection for " . io_safe_output(modules_get_agentmodule_name ($agent_module_id)); + $module_name_list[$i] = substr($agent_name, 0,80) ." / ".substr ($module_name, 0, 40); + $id_module_type = modules_get_agentmodule_type ($agent_module_id); + $module_type = modules_get_moduletype_name ($id_module_type); + $uncompressed_module = is_module_uncompressed ($module_type); + }else{ + $agent_module_id = $module_list[$i]; + $agent_name = modules_get_agentmodule_agent_name ($agent_module_id); + $agent_id = agents_get_agent_id ($agent_name); + $module_name = io_safe_output(modules_get_agentmodule_name ($agent_module_id)); + $module_name_list[$i] = substr($agent_name, 0,80) ." / ".substr ($module_name, 0, 40); + $id_module_type = modules_get_agentmodule_type ($agent_module_id); + $module_type = modules_get_moduletype_name ($id_module_type); + $uncompressed_module = is_module_uncompressed ($module_type); + } + if ($uncompressed_module) { $avg_only = 1; } @@ -608,7 +664,14 @@ function graphic_combined_module ($module_list, $weight_list, $period, $width, $ } $avg += $temp_graph_values[$timestamp_short]; - $graph_values[$i] = $temp_graph_values; + // Added to support projection graphs + if ($projection != false and $i != 0){ + $projection_data = array(); + $projection_data = array_merge($before_projection, $projection); + $graph_values[$i] = $projection_data; + }else{ + $graph_values[$i] = $temp_graph_values; + } } //Add the max, min and avg in the legend @@ -619,7 +682,9 @@ function graphic_combined_module ($module_list, $weight_list, $period, $width, $ $avg = format_for_graph($avg); $units = modules_get_unit($agent_module_id); - $module_name_list[$i] .= " (".__("Max"). ":$max, ".__("Min"). ":$min, ". __("Avg"). ": $avg, ". __("Units"). ": $units)"; + if ($projection == false or ($projection != false and $i == 0)){ + $module_name_list[$i] .= " (".__("Max"). ":$max, ".__("Min"). ":$min, ". __("Avg"). ": $avg, ". __("Units"). ": $units)"; + } if ($weight_list[$i] != 1) { //$module_name_list[$i] .= " (x". format_numeric ($weight_list[$i], 1).")"; @@ -632,8 +697,8 @@ function graphic_combined_module ($module_list, $weight_list, $period, $width, $ //$graph_values[$i] = $graph_values[$i]; } - $temp = array(); + foreach ($graph_values as $graph_group => $point) { foreach ($point as $timestamp_point => $point_value) { $temp[$timestamp_point][$graph_group] = $point_value; @@ -665,13 +730,13 @@ function graphic_combined_module ($module_list, $weight_list, $period, $width, $ $title_period = __('Last %s days', format_numeric (($period / (3600 * 24)), 2)); $time_format = 'M j'; } - + $flash_charts = $config['flash_charts']; if ($only_image) { $flash_charts = false; } - + switch ($stacked) { case GRAPH_AREA: $color = null; diff --git a/pandora_console/include/functions_reporting.php b/pandora_console/include/functions_reporting.php index 3bb0f4a2f3..41fd1202ae 100644 --- a/pandora_console/include/functions_reporting.php +++ b/pandora_console/include/functions_reporting.php @@ -32,6 +32,7 @@ include_once($config['homedir'] . "/include/functions_events.php"); include_once($config['homedir'] . "/include/functions_alerts.php"); include_once($config['homedir'] . '/include/functions_users.php'); enterprise_include_once ('include/functions_metaconsole.php'); +include_once($config['homedir'] . "/include/functions_forecast.php"); /** * Get the average value of an agent module in a period of time. @@ -2056,8 +2057,79 @@ function reporting_render_report_html_item ($content, $table, $report, $mini = f array_push ($table->data, $data); - break; + break; + case 'projection_graph': + //RUNNING + $table->colspan[1][0] = 4; + $data = array (); + $data[0] = $sizh.__('Projection graph').$sizhfin; + $data[1] = $sizh . ui_print_truncate_text($agent_name, 75, false).'
' . ui_print_truncate_text($module_name, 75, false).$sizhfin; + $data[2] = $sizh.human_time_description_raw ($content['period']).$sizhfin; + array_push ($table->data, $data); + // Put description at the end of the module (if exists) + $table->colspan[2][0] = 4; + if ($content["description"] != ""){ + $data_desc = array(); + $data_desc[0] = $content["description"]; + array_push ($table->data, $data_desc); + } + + $data = array (); + + $output_projection = forecast_projection_graph($content['id_agent_module'], $content['period'], $content['top_n_value']); + + $modules = array($content['id_agent_module']); + $weights = array(); + $data[0] = graphic_combined_module( + $modules, + $weights, + $content['period'], + $sizgraph_w, $sizgraph_h, + 'Projection%20Sample%20Graph', + '', + 0, + 0, + 0, + $graph["stacked"], + $report["datetime"], + false, + '', + 1, + // Important parameter, this tell to graphic_combined_module function that is a projection graph + $output_projection + ); + array_push ($table->data, $data); + break; + case 'prediction_date': + //RUNNING + $table->colspan[1][0] = 4; + $data = array (); + $data[0] = $sizh.__('Prediction date').$sizhfin; + $data[1] = $sizh . ui_print_truncate_text($agent_name, 75, false).'
' . ui_print_truncate_text($module_name, 75, false).$sizhfin; + $data[2] = $sizh.human_time_description_raw ($content['period']).$sizhfin; + array_push ($table->data, $data); + + // Put description at the end of the module (if exists) + $table->colspan[2][0] = 4; + if ($content["description"] != ""){ + $data_desc = array(); + $data_desc[0] = $content["description"]; + array_push ($table->data, $data_desc); + } + + $data = array (); + $table->colspan[2][0] = 3; + $value = forecast_prediction_date ($content['id_agent_module'], $content['top_n'], $content['top_n_value']); + + if ($value === false) { + $value = __('Unknown'); + } else { + $value = date ('d M Y H:i:s', $value); + } + $data[0] = '

'.$value.'

'; + array_push ($table->data, $data); + break; case 'simple_baseline_graph': //RUNNING $table->colspan[1][0] = 4; @@ -2079,6 +2151,20 @@ function reporting_render_report_html_item ($content, $table, $report, $mini = f $data[0] = grafico_modulo_sparse($layout_data['id_agente_modulo'], $content['period'], false, $sizgraph_w, $sizgraph_h, '', '', false, true, true, $report["datetime"], '', true, 0, true, true); + + /*$data[0] = graphic_combined_module( + $modules, + $weights, + $content['period'], + $sizgraph_w, $sizgraph_h, + 'Combined%20Sample%20Graph', + '', + 0, + 0, + 0, + $graph["stacked"], + $report["datetime"]); */ + array_push ($table->data, $data); break;