diff --git a/pandora_console/ChangeLog b/pandora_console/ChangeLog index 0805da4f3c..fccf0d4e19 100644 --- a/pandora_console/ChangeLog +++ b/pandora_console/ChangeLog @@ -1,3 +1,12 @@ +2014-05-05 Sergio Martin + + * extensions/realtime_graphs + extensions/realtime_graphs/ajax.php + extensions/realtime_graphs/realtime_graphs.css + extensions/realtime_graphs/realtime_graphs.js + extensions/realtime_graphs.php: Added real time graphs + extension for ticket #736 + 2014-05-05 Ramon Novoa * extras/pandoradb_migrate_5.0.x_to_5.1.mysql.sql diff --git a/pandora_console/extensions/realtime_graphs.php b/pandora_console/extensions/realtime_graphs.php new file mode 100644 index 0000000000..a55516e52b --- /dev/null +++ b/pandora_console/extensions/realtime_graphs.php @@ -0,0 +1,132 @@ +'; + $canvas .= '
'; + $canvas .= area_graph($interactive_graph, $chart, 800, 300, $color, $legend, $long_index, $no_data_image, "", "", "", + "", '', '', '', 1, array(), array(), 0, 0, '', false, '', false); + $canvas .= ''; + echo $canvas; + + $table->width = '99%'; + $table->id = 'table-form'; + $table->class = 'databox'; + $table->style = array (); + $table->style[0] = 'font-weight: bold;'; + $table->style[1] = 'font-weight: bold;'; + $table->style[2] = 'font-weight: bold;'; + $table->data = array (); + + $graph_fields['cpu_load'] = __('Pandora Server CPU'); + $graph_fields['pending_packets'] = __('Pandora Server Pending packets'); + $graph_fields['disk_io_wait'] = __('Pandora Server Disk IO Wait'); + $graph_fields['apache_load'] = __('Pandora Server Apache load'); + $graph_fields['mysql_load'] = __('Pandora Server MySQL load'); + $graph_fields['server_load'] = __('Pandora Server load'); + $graph_fields['snmp_interface'] = __('SNMP Interface throughput'); + + $graph = get_parameter('graph', 'cpu_load'); + $refresh = get_parameter('refresh', '1000'); + + $data['graph'] = __('Graph') . '
' . html_print_select ($graph_fields, 'graph', $graph, '', '', 0, true); + $data['reset'] = html_print_button(__('Clear graph'), 'reset', false, 'clearGraph()', 'class="sub delete"', true); + + $refresh_fields[1000] = human_time_description_raw(1, true, 'large'); + $refresh_fields[5000] = human_time_description_raw(5, true, 'large'); + $refresh_fields[10000] = human_time_description_raw(10, true, 'large'); + $refresh_fields[30000] = human_time_description_raw(30, true, 'large'); + + $data['refresh'] = __('Refresh interval') . '
' . html_print_select ($refresh_fields, 'refresh', $refresh, '', '', 0, true); + $data['incremental'] = __('Incremental') . '
' . html_print_checkbox ('incremental', 1, 0, true); + + $table->data[] = $data; + + + if ($graph == 'snmp_interface') { + $snmp_address = ''; + $snmp_community = ''; + $snmp_oid = ''; + $snmp_ver = '1'; + $snmp_inc = false; + + $data = array(); + + $data['snmp_address'] = __('Target IP') . '
' . html_print_input_text ('ip_target', $snmp_address, '', 50, 255, true); + $table->colspan[1]['snmp_address'] = 2; + + $data['snmp_community'] = __('Community') . '
' . html_print_input_text ('snmp_community', $snmp_community, '', 50, 255, true); + $table->colspan[1]['snmp_community'] = 2; + + $table->data[] = $data; + + $snmp_versions = array(); + $snmp_versions['1'] = '1'; + $snmp_versions['2'] = '2'; + $snmp_versions['2c'] = '2c'; + + $data = array(); + $data['snmp_oid'] = __('OID') . '
' . html_print_input_text ('snmp_oid', $snmp_oid, '', 100, 255, true); + $data['snmp_oid'] .= html_print_button (__('SNMP walk'), 'snmp_walk', false, 'snmpBrowserWindow()', 'class="sub next"', true); + $table->colspan[2]['snmp_oid'] = 2; + + $data['snmp_ver'] = __('Version') . '
' . html_print_select ($snmp_versions, 'snmp_version', $snmp_ver, '', '', 0, true); + + $table->colspan[2]['snmp_ver'] = 2; + + $table->data[] = $data; + + snmp_browser_print_container (false, '100%', '60%', 'none'); + } + + echo '
'; + html_print_table($table); + echo '
'; + + // Define a custom action to save the OID selected in the SNMP browser to the form + html_print_input_hidden ('custom_action', urlencode (base64_encode(' ')), false); + html_print_input_hidden ('incremental_base', '0'); + + echo ''; + echo ''; + echo ''; +} + +extensions_add_operation_menu_option (__('Realtime graphs'), null, null, "v1r1"); +extensions_add_main_function ('pandora_realtime_graphs'); + +$db = NULL; +?> diff --git a/pandora_console/extensions/realtime_graphs/ajax.php b/pandora_console/extensions/realtime_graphs/ajax.php new file mode 100644 index 0000000000..d2eaf4b29d --- /dev/null +++ b/pandora_console/extensions/realtime_graphs/ajax.php @@ -0,0 +1,76 @@ + 1) { + $data = $data_array[1]; + } + } + } + break; + default: + $data = 0; +} + +if (empty($data)) { + $data = 0; +} + +$graph_title .= ' (' . $refresh/1000 . ' ' . __('Seconds') . ')'; +echo '{ + "label": "' . $graph_title . '", + "data": [["' . time() . '", ' . $data . ']] +}'; +?> diff --git a/pandora_console/extensions/realtime_graphs/realtime_graphs.css b/pandora_console/extensions/realtime_graphs/realtime_graphs.css new file mode 100644 index 0000000000..e5a1f8a2bb --- /dev/null +++ b/pandora_console/extensions/realtime_graphs/realtime_graphs.css @@ -0,0 +1,15 @@ +#chartLegend { + width: 100%; + position: relative; + height: 30px; +} + +#chartLegend table { + position: absolute; + right: 0px; +} + +#graph_container { + width: 800px; + margin: 20px auto !important; +} diff --git a/pandora_console/extensions/realtime_graphs/realtime_graphs.js b/pandora_console/extensions/realtime_graphs/realtime_graphs.js new file mode 100644 index 0000000000..6ff54eb15c --- /dev/null +++ b/pandora_console/extensions/realtime_graphs/realtime_graphs.js @@ -0,0 +1,173 @@ +var max_data_plot = 100; + +var options = { + legend: { container: $("#chartLegend") }, + xaxis: { + tickFormatter: function (timestamp, axis) { + var date = new Date(timestamp * 1000); + var hours = (date.getHours() < 10 ? '0' + date.getHours() : date.getHours()); + var minutes = (date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()); + var seconds = (date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()); + var formattedTime = hours + ':' + minutes + ':' + seconds; + return formattedTime; + } + }, + series: { + lines: { + lineWidth: 2, + fill: true + } + }, + colors: ['#6db431'] + } + +var data = []; + +var id = $('.graph').attr('id'); +var plot = $.plot("#" + id, data, options); + + +var refresh = parseInt($('#refresh').val()); +var incremental = $('#checkbox-incremental').is(':checked'); +var incremental_base = 0; +var last_inc = 0; + +refresh_graph(); + +function refresh_graph () { + var refresh = parseInt($('#refresh').val()); + + var postvars = new Array(); + var postvars = {}; + postvars['graph'] = $('#graph :selected').val(); + postvars['graph_title'] = $('#graph :selected').html(); + + postvars['snmp_community'] = $('#text-snmp_community').val(); + postvars['snmp_oid'] = $('#text-snmp_oid').val(); + postvars['snmp_ver'] = $('#snmp_version :selected').val(); + postvars['snmp_address'] = $('#text-ip_target').val(); + + postvars['refresh'] = refresh; + + $.ajax({ + url: "extensions/realtime_graphs/ajax.php", + type: "POST", + dataType: "json", + data: postvars, + success: function(serie) { + var timestamp = serie.data[0][0]; + data = plot.getData(); + if (data.length == 0) { + for(i = 0; i < max_data_plot; i ++) { + step = i * (refresh/1000); + serie.data.unshift([timestamp-step, 0]); + } + + serie = [serie]; + plot = $.plot("#" + id, serie, options); + return; + } + data[0].label = serie.label; + if (data[0].data.length >= max_data_plot) { + data[0].data.shift(); + } + + if (incremental) { + var last_item = parseInt(data[0].data.length)-1; + var last_value = data[0].data[last_item][1]; + + var current_value = serie.data[0][1]; + + serie.data[0][1] = current_value - last_inc; + + last_inc = current_value; + + // Incremental is always positive + if (serie.data[0][1] < 0) { + serie.data[0][1] = 0; + } + + } + + data[0].data.push(serie.data[0]); + $.plot("#" + id, data, options); + } + }); + window.setTimeout(refresh_graph, refresh); +} + +$('#graph').change(function() { + $('form#realgraph').submit(); +}); + +$('#refresh').change(function() { + //refresh_graph(); +}); + +// Show the SNMP browser window +function snmpBrowserWindow () { + + // Keep elements in the form and the SNMP browser synced + $('#text-target_ip').val($('#text-ip_target').val()); + $('#text-community').val($('#text-snmp_community').val()); + $('#snmp_browser_version').val($('#snmp_version').val()); + $('#snmp3_browser_auth_user').val($('#snmp3_auth_user').val()); + $('#snmp3_browser_security_level').val($('#snmp3_security_level').val()); + $('#snmp3_browser_auth_method').val($('#snmp3_auth_method').val()); + $('#snmp3_browser_auth_pass').val($('#snmp3_auth_pass').val()); + $('#snmp3_browser_privacy_method').val($('#snmp3_privacy_method').val()); + $('#snmp3_browser_privacy_pass').val($('#snmp3_privacy_pass').val()); + + $("#snmp_browser_container").show().dialog ({ + title: '', + resizable: true, + draggable: true, + modal: true, + overlay: { + opacity: 0.5, + background: "black" + }, + width: 730, + height: 430 + }); +} + +// Set the form OID to the value selected in the SNMP browser +function setOID () { + $('#text-snmp_oid').val($('#snmp_selected_oid').text()); + + // Close the SNMP browser + $('.ui-dialog-titlebar-close').trigger('click'); +} + +$('#checkbox-incremental').change(function() { + incremental = $('#checkbox-incremental').is(':checked'); + clearGraph(); +}); + +function firstNotZero(data) { + var notZero = 0; + for(i = 0; i < data[0].data.length; i ++) { + if (data[0].data[i][1] != 0) { + return data[0].data[i][1]; + } + } +} + +function setOnIncremental() { + +} + +function clearGraph() { + data = plot.getData(); + if (data.length == 0) { + return; + } + console.log(data); + + for(i = 0; i < data[0].data.length; i ++) { + data[0].data[i][1] = 0; + } + + $.plot("#" + id, data, options); +}