diff options
Diffstat (limited to 'srcs/phpmyadmin/js/server/status/monitor.js')
| -rw-r--r-- | srcs/phpmyadmin/js/server/status/monitor.js | 2219 |
1 files changed, 2219 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/js/server/status/monitor.js b/srcs/phpmyadmin/js/server/status/monitor.js new file mode 100644 index 0000000..3cb4fe9 --- /dev/null +++ b/srcs/phpmyadmin/js/server/status/monitor.js @@ -0,0 +1,2219 @@ +/* vim: set expandtab sw=4 ts=4 sts=4: */ +/** + * @fileoverview Javascript functions used in server status monitor page + * @name Server Status Monitor + * + * @requires jQuery + * @requires jQueryUI + * @requires js/functions.js + */ + +/* global isStorageSupported */ // js/config.js +/* global codeMirrorEditor:writable */ // js/functions.js +/* global pmaThemeImage */ // js/messages.php +/* global variableNames */ // templates/server/status/monitor/index.twig + +var runtime = {}; +var serverTimeDiff; +var serverOs; +var isSuperUser; +var serverDbIsLocal; +var chartSize; +var monitorSettings; + +AJAX.registerOnload('server/status/monitor.js', function () { + var $jsDataForm = $('#js_data'); + serverTimeDiff = new Date().getTime() - $jsDataForm.find('input[name=server_time]').val(); + serverOs = $jsDataForm.find('input[name=server_os]').val(); + isSuperUser = $jsDataForm.find('input[name=is_superuser]').val(); + serverDbIsLocal = $jsDataForm.find('input[name=server_db_isLocal]').val(); +}); + +/** + * Unbind all event handlers before tearing down a page + */ +AJAX.registerTeardown('server/status/monitor.js', function () { + $('#emptyDialog').remove(); + $('#addChartDialog').remove(); + $('a.popupLink').off('click'); + $('body').off('click'); +}); +/** + * Popup behaviour + */ +AJAX.registerOnload('server/status/monitor.js', function () { + $('<div></div>') + .attr('id', 'emptyDialog') + .appendTo('#page_content'); + $('#addChartDialog') + .appendTo('#page_content'); + + $('a.popupLink').on('click', function () { + var $link = $(this); + $('div.' + $link.attr('href').substr(1)) + .show() + .offset({ top: $link.offset().top + $link.height() + 5, left: $link.offset().left }) + .addClass('openedPopup'); + + return false; + }); + $('body').on('click', function (event) { + $('div.openedPopup').each(function () { + var $cnt = $(this); + var pos = $cnt.offset(); + // Hide if the mouseclick is outside the popupcontent + if (event.pageX < pos.left || + event.pageY < pos.top || + event.pageX > pos.left + $cnt.outerWidth() || + event.pageY > pos.top + $cnt.outerHeight() + ) { + $cnt.hide().removeClass('openedPopup'); + } + }); + }); +}); + +AJAX.registerTeardown('server/status/monitor.js', function () { + $('a[href="#rearrangeCharts"], a[href="#endChartEditMode"]').off('click'); + $('div.popupContent select[name="chartColumns"]').off('change'); + $('div.popupContent select[name="gridChartRefresh"]').off('change'); + $('a[href="#addNewChart"]').off('click'); + $('a[href="#exportMonitorConfig"]').off('click'); + $('a[href="#importMonitorConfig"]').off('click'); + $('a[href="#clearMonitorConfig"]').off('click'); + $('a[href="#pauseCharts"]').off('click'); + $('a[href="#monitorInstructionsDialog"]').off('click'); + $('input[name="chartType"]').off('click'); + $('input[name="useDivisor"]').off('click'); + $('input[name="useUnit"]').off('click'); + $('select[name="varChartList"]').off('click'); + $('a[href="#kibDivisor"]').off('click'); + $('a[href="#mibDivisor"]').off('click'); + $('a[href="#submitClearSeries"]').off('click'); + $('a[href="#submitAddSeries"]').off('click'); + // $("input#variableInput").destroy(); + $('#chartPreset').off('click'); + $('#chartStatusVar').off('click'); + destroyGrid(); +}); + +AJAX.registerOnload('server/status/monitor.js', function () { + // Show tab links + $('div.tabLinks').show(); + $('#loadingMonitorIcon').remove(); + // Codemirror is loaded on demand so we might need to initialize it + if (! codeMirrorEditor) { + var $elm = $('#sqlquery'); + if ($elm.length > 0 && typeof CodeMirror !== 'undefined') { + codeMirrorEditor = CodeMirror.fromTextArea( + $elm[0], + { + lineNumbers: true, + matchBrackets: true, + indentUnit: 4, + mode: 'text/x-mysql', + lineWrapping: true + } + ); + } + } + // Timepicker is loaded on demand so we need to initialize + // datetime fields from the 'load log' dialog + $('#logAnalyseDialog').find('.datetimefield').each(function () { + Functions.addDatepicker($(this)); + }); + + /** ** Monitor charting implementation ****/ + /* Saves the previous ajax response for differential values */ + var oldChartData = null; + // Holds about to be created chart + var newChart = null; + var chartSpacing; + + // Whenever the monitor object (runtime.charts) or the settings object + // (monitorSettings) changes in a way incompatible to the previous version, + // increase this number. It will reset the users monitor and settings object + // in his localStorage to the default configuration + var monitorProtocolVersion = '1.0'; + + // Runtime parameter of the monitor, is being fully set in initGrid() + runtime = { + // Holds all visible charts in the grid + charts: null, + // Stores the timeout handler so it can be cleared + refreshTimeout: null, + // Stores the GET request to refresh the charts + refreshRequest: null, + // Chart auto increment + chartAI: 0, + // To play/pause the monitor + redrawCharts: false, + // Object that contains a list of nodes that need to be retrieved + // from the server for chart updates + dataList: [], + // Current max points per chart (needed for auto calculation) + gridMaxPoints: 20, + // displayed time frame + xmin: -1, + xmax: -1 + }; + monitorSettings = null; + + var defaultMonitorSettings = { + columns: 3, + chartSize: { width: 295, height: 250 }, + // Max points in each chart. Settings it to 'auto' sets + // gridMaxPoints to (chartwidth - 40) / 12 + gridMaxPoints: 'auto', + /* Refresh rate of all grid charts in ms */ + gridRefresh: 5000 + }; + + // Allows drag and drop rearrange and print/edit icons on charts + var editMode = false; + + /* List of preconfigured charts that the user may select */ + var presetCharts = { + // Query cache efficiency + 'qce': { + title: Messages.strQueryCacheEfficiency, + series: [{ + label: Messages.strQueryCacheEfficiency + }], + nodes: [{ + dataPoints: [{ type: 'statusvar', name: 'Qcache_hits' }, { type: 'statusvar', name: 'Com_select' }], + transformFn: 'qce' + }], + maxYLabel: 0 + }, + // Query cache usage + 'qcu': { + title: Messages.strQueryCacheUsage, + series: [{ + label: Messages.strQueryCacheUsed + }], + nodes: [{ + dataPoints: [{ type: 'statusvar', name: 'Qcache_free_memory' }, { type: 'servervar', name: 'query_cache_size' }], + transformFn: 'qcu' + }], + maxYLabel: 0 + } + }; + + // time span selection + var selectionTimeDiff = []; + var selectionStartX; + var selectionStartY; + var drawTimeSpan = false; + + /* Add OS specific system info charts to the preset chart list */ + switch (serverOs) { + case 'WINNT': + $.extend(presetCharts, { + 'cpu': { + title: Messages.strSystemCPUUsage, + series: [{ + label: Messages.strAverageLoad + }], + nodes: [{ + dataPoints: [{ type: 'cpu', name: 'loadavg' }] + }], + maxYLabel: 100 + }, + + 'memory': { + title: Messages.strSystemMemory, + series: [{ + label: Messages.strTotalMemory, + fill: true + }, { + dataType: 'memory', + label: Messages.strUsedMemory, + fill: true + }], + nodes: [{ dataPoints: [{ type: 'memory', name: 'MemTotal' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 } + ], + maxYLabel: 0 + }, + + 'swap': { + title: Messages.strSystemSwap, + series: [{ + label: Messages.strTotalSwap, + fill: true + }, { + label: Messages.strUsedSwap, + fill: true + }], + nodes: [{ dataPoints: [{ type: 'memory', name: 'SwapTotal' }] }, + { dataPoints: [{ type: 'memory', name: 'SwapUsed' }] } + ], + maxYLabel: 0 + } + }); + break; + + case 'Linux': + $.extend(presetCharts, { + 'cpu': { + title: Messages.strSystemCPUUsage, + series: [{ + label: Messages.strAverageLoad + }], + nodes: [{ dataPoints: [{ type: 'cpu', name: 'irrelevant' }], transformFn: 'cpu-linux' }], + maxYLabel: 0 + }, + 'memory': { + title: Messages.strSystemMemory, + series: [ + { label: Messages.strBufferedMemory, fill: true }, + { label: Messages.strUsedMemory, fill: true }, + { label: Messages.strCachedMemory, fill: true }, + { label: Messages.strFreeMemory, fill: true } + ], + nodes: [ + { dataPoints: [{ type: 'memory', name: 'Buffers' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'Cached' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 } + ], + maxYLabel: 0 + }, + 'swap': { + title: Messages.strSystemSwap, + series: [ + { label: Messages.strCachedSwap, fill: true }, + { label: Messages.strUsedSwap, fill: true }, + { label: Messages.strFreeSwap, fill: true } + ], + nodes: [ + { dataPoints: [{ type: 'memory', name: 'SwapCached' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 } + ], + maxYLabel: 0 + } + }); + break; + + case 'SunOS': + $.extend(presetCharts, { + 'cpu': { + title: Messages.strSystemCPUUsage, + series: [{ + label: Messages.strAverageLoad + }], + nodes: [{ + dataPoints: [{ type: 'cpu', name: 'loadavg' }] + }], + maxYLabel: 0 + }, + 'memory': { + title: Messages.strSystemMemory, + series: [ + { label: Messages.strUsedMemory, fill: true }, + { label: Messages.strFreeMemory, fill: true } + ], + nodes: [ + { dataPoints: [{ type: 'memory', name: 'MemUsed' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'MemFree' }], valueDivisor: 1024 } + ], + maxYLabel: 0 + }, + 'swap': { + title: Messages.strSystemSwap, + series: [ + { label: Messages.strUsedSwap, fill: true }, + { label: Messages.strFreeSwap, fill: true } + ], + nodes: [ + { dataPoints: [{ type: 'memory', name: 'SwapUsed' }], valueDivisor: 1024 }, + { dataPoints: [{ type: 'memory', name: 'SwapFree' }], valueDivisor: 1024 } + ], + maxYLabel: 0 + } + }); + break; + } + + // Default setting for the chart grid + var defaultChartGrid = { + 'c0': { + title: Messages.strQuestions, + series: [ + { label: Messages.strQuestions } + ], + nodes: [ + { dataPoints: [{ type: 'statusvar', name: 'Questions' }], display: 'differential' } + ], + maxYLabel: 0 + }, + 'c1': { + title: Messages.strChartConnectionsTitle, + series: [ + { label: Messages.strConnections }, + { label: Messages.strProcesses } + ], + nodes: [ + { dataPoints: [{ type: 'statusvar', name: 'Connections' }], display: 'differential' }, + { dataPoints: [{ type: 'proc', name: 'processes' }] } + ], + maxYLabel: 0 + }, + 'c2': { + title: Messages.strTraffic, + series: [ + { label: Messages.strBytesSent }, + { label: Messages.strBytesReceived } + ], + nodes: [ + { dataPoints: [{ type: 'statusvar', name: 'Bytes_sent' }], display: 'differential', valueDivisor: 1024 }, + { dataPoints: [{ type: 'statusvar', name: 'Bytes_received' }], display: 'differential', valueDivisor: 1024 } + ], + maxYLabel: 0 + } + }; + + // Server is localhost => We can add cpu/memory/swap to the default chart + if (serverDbIsLocal && typeof presetCharts.cpu !== 'undefined') { + defaultChartGrid.c3 = presetCharts.cpu; + defaultChartGrid.c4 = presetCharts.memory; + defaultChartGrid.c5 = presetCharts.swap; + } + + $('a[href="#rearrangeCharts"], a[href="#endChartEditMode"]').on('click', function (event) { + event.preventDefault(); + editMode = !editMode; + if ($(this).attr('href') === '#endChartEditMode') { + editMode = false; + } + + $('a[href="#endChartEditMode"]').toggle(editMode); + + if (editMode) { + // Close the settings popup + $('div.popupContent').hide().removeClass('openedPopup'); + + $('#chartGrid').sortableTable({ + ignoreRect: { + top: 8, + left: chartSize.width - 63, + width: 54, + height: 24 + } + }); + } else { + $('#chartGrid').sortableTable('destroy'); + } + saveMonitor(); // Save settings + return false; + }); + + // global settings + $('div.popupContent select[name="chartColumns"]').on('change', function () { + monitorSettings.columns = parseInt(this.value, 10); + + calculateChartSize(); + // Empty cells should keep their size so you can drop onto them + $('#chartGrid').find('tr td').css('width', chartSize.width + 'px'); + $('#chartGrid').find('.monitorChart').css({ + width: chartSize.width + 'px', + height: chartSize.height + 'px' + }); + + /* Reorder all charts that it fills all column cells */ + var numColumns; + var $tr = $('#chartGrid').find('tr:first'); + + var tempManageCols = function () { + if (numColumns > monitorSettings.columns) { + if ($tr.next().length === 0) { + $tr.after('<tr></tr>'); + } + $tr.next().prepend($(this)); + } + numColumns++; + }; + + var tempAddCol = function () { + if ($(this).next().length !== 0) { + $(this).append($(this).next().find('td:first')); + } + }; + + while ($tr.length !== 0) { + numColumns = 1; + // To many cells in one row => put into next row + $tr.find('td').each(tempManageCols); + + // To little cells in one row => for each cell to little, + // move all cells backwards by 1 + if ($tr.next().length > 0) { + var cnt = monitorSettings.columns - $tr.find('td').length; + for (var i = 0; i < cnt; i++) { + $tr.append($tr.next().find('td:first')); + $tr.nextAll().each(tempAddCol); + } + } + + $tr = $tr.next(); + } + + if (monitorSettings.gridMaxPoints === 'auto') { + runtime.gridMaxPoints = Math.round((chartSize.width - 40) / 12); + } + + runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; + runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; + + if (editMode) { + $('#chartGrid').sortableTable('refresh'); + } + + refreshChartGrid(); + saveMonitor(); // Save settings + }); + + $('div.popupContent select[name="gridChartRefresh"]').on('change', function () { + monitorSettings.gridRefresh = parseInt(this.value, 10) * 1000; + clearTimeout(runtime.refreshTimeout); + + if (runtime.refreshRequest) { + runtime.refreshRequest.abort(); + } + + runtime.xmin = new Date().getTime() - serverTimeDiff - runtime.gridMaxPoints * monitorSettings.gridRefresh; + // fixing chart shift towards left on refresh rate change + // runtime.xmax = new Date().getTime() - serverTimeDiff + monitorSettings.gridRefresh; + runtime.refreshTimeout = setTimeout(refreshChartGrid, monitorSettings.gridRefresh); + + saveMonitor(); // Save settings + }); + + $('a[href="#addNewChart"]').on('click', function (event) { + event.preventDefault(); + var dlgButtons = { }; + + dlgButtons[Messages.strAddChart] = function () { + var type = $('input[name="chartType"]:checked').val(); + + if (type === 'preset') { + newChart = presetCharts[$('#addChartDialog').find('select[name="presetCharts"]').prop('value')]; + } else { + // If user builds his own chart, it's being set/updated + // each time he adds a series + // So here we only warn if he didn't add a series yet + if (! newChart || ! newChart.nodes || newChart.nodes.length === 0) { + alert(Messages.strAddOneSeriesWarning); + return; + } + } + + newChart.title = $('input[name="chartTitle"]').val(); + // Add a cloned object to the chart grid + addChart($.extend(true, {}, newChart)); + + newChart = null; + + saveMonitor(); // Save settings + + $(this).dialog('close'); + }; + + dlgButtons[Messages.strClose] = function () { + newChart = null; + $('span#clearSeriesLink').hide(); + $('#seriesPreview').html(''); + $(this).dialog('close'); + }; + + var $presetList = $('#addChartDialog').find('select[name="presetCharts"]'); + if ($presetList.html().length === 0) { + $.each(presetCharts, function (key, value) { + $presetList.append('<option value="' + key + '">' + value.title + '</option>'); + }); + $presetList.on('change', function () { + $('input[name="chartTitle"]').val( + $presetList.find(':selected').text() + ); + $('#chartPreset').prop('checked', true); + }); + $('#chartPreset').on('click', function () { + $('input[name="chartTitle"]').val( + $presetList.find(':selected').text() + ); + }); + $('#chartStatusVar').on('click', function () { + $('input[name="chartTitle"]').val( + $('#chartSeries').find(':selected').text().replace(/_/g, ' ') + ); + }); + $('#chartSeries').on('change', function () { + $('input[name="chartTitle"]').val( + $('#chartSeries').find(':selected').text().replace(/_/g, ' ') + ); + }); + } + + $('#addChartDialog').dialog({ + width: 'auto', + height: 'auto', + buttons: dlgButtons + }); + + $('#seriesPreview').html('<i>' + Messages.strNone + '</i>'); + + return false; + }); + + $('a[href="#exportMonitorConfig"]').on('click', function (event) { + event.preventDefault(); + var gridCopy = {}; + $.each(runtime.charts, function (key, elem) { + gridCopy[key] = {}; + gridCopy[key].nodes = elem.nodes; + gridCopy[key].series = elem.series; + gridCopy[key].settings = elem.settings; + gridCopy[key].title = elem.title; + gridCopy[key].maxYLabel = elem.maxYLabel; + }); + var exportData = { + monitorCharts: gridCopy, + monitorSettings: monitorSettings + }; + + var blob = new Blob([JSON.stringify(exportData)], { type: 'application/octet-stream' }); + var url = null; + var fileName = 'monitor-config.json'; + if (window.navigator && window.navigator.msSaveOrOpenBlob) { + window.navigator.msSaveOrOpenBlob(blob, fileName); + } else { + url = URL.createObjectURL(blob); + window.location.href = url; + } + setTimeout(function () { + // For some browsers it is necessary to delay revoking the ObjectURL + if (url !== null) { + window.URL.revokeObjectURL(url); + } + url = undefined; + blob = undefined; + }, 100); + }); + + $('a[href="#importMonitorConfig"]').on('click', function (event) { + event.preventDefault(); + $('#emptyDialog').dialog({ title: Messages.strImportDialogTitle }); + $('#emptyDialog').html(Messages.strImportDialogMessage + ':<br><form>' + + '<input type="file" name="file" id="import_file"> </form>'); + + var dlgBtns = {}; + + dlgBtns[Messages.strImport] = function () { + var input = $('#emptyDialog').find('#import_file')[0]; + var reader = new FileReader(); + + reader.onerror = function (event) { + alert(Messages.strFailedParsingConfig + '\n' + event.target.error.code); + }; + reader.onload = function (e) { + var data = e.target.result; + var json = null; + // Try loading config + try { + json = JSON.parse(data); + } catch (err) { + alert(Messages.strFailedParsingConfig); + $('#emptyDialog').dialog('close'); + return; + } + + // Basic check, is this a monitor config json? + if (!json || ! json.monitorCharts || ! json.monitorCharts) { + alert(Messages.strFailedParsingConfig); + $('#emptyDialog').dialog('close'); + return; + } + + // If json ok, try applying config + try { + if (isStorageSupported('localStorage')) { + window.localStorage.monitorCharts = JSON.stringify(json.monitorCharts); + window.localStorage.monitorSettings = JSON.stringify(json.monitorSettings); + } + rebuildGrid(); + } catch (err) { + alert(Messages.strFailedBuildingGrid); + // If an exception is thrown, load default again + if (isStorageSupported('localStorage')) { + window.localStorage.removeItem('monitorCharts'); + window.localStorage.removeItem('monitorSettings'); + } + rebuildGrid(); + } + + $('#emptyDialog').dialog('close'); + }; + reader.readAsText(input.files[0]); + }; + + dlgBtns[Messages.strCancel] = function () { + $(this).dialog('close'); + }; + + $('#emptyDialog').dialog({ + width: 'auto', + height: 'auto', + buttons: dlgBtns + }); + }); + + $('a[href="#clearMonitorConfig"]').on('click', function (event) { + event.preventDefault(); + if (isStorageSupported('localStorage')) { + window.localStorage.removeItem('monitorCharts'); + window.localStorage.removeItem('monitorSettings'); + window.localStorage.removeItem('monitorVersion'); + } + $(this).hide(); + rebuildGrid(); + }); + + $('a[href="#pauseCharts"]').on('click', function (event) { + event.preventDefault(); + runtime.redrawCharts = ! runtime.redrawCharts; + if (! runtime.redrawCharts) { + $(this).html(Functions.getImage('play') + Messages.strResumeMonitor); + } else { + $(this).html(Functions.getImage('pause') + Messages.strPauseMonitor); + if (! runtime.charts) { + initGrid(); + $('a[href="#settingsPopup"]').show(); + } + } + return false; + }); + + $('a[href="#monitorInstructionsDialog"]').on('click', function (event) { + event.preventDefault(); + + var $dialog = $('#monitorInstructionsDialog'); + var dlgBtns = {}; + dlgBtns[Messages.strClose] = function () { + $(this).dialog('close'); + }; + $dialog.dialog({ + width: '60%', + height: 'auto', + buttons: dlgBtns + }).find('img.ajaxIcon').show(); + + var loadLogVars = function (getvars) { + var vars = { + 'ajax_request': true, + 'logging_vars': true + }; + if (getvars) { + $.extend(vars, getvars); + } + + $.post('server_status_monitor.php' + CommonParams.get('common_query'), vars, + function (data) { + var logVars; + if (typeof data !== 'undefined' && data.success === true) { + logVars = data.message; + } else { + return serverResponseError(); + } + var icon = Functions.getImage('s_success'); + var msg = ''; + var str = ''; + + if (logVars.general_log === 'ON') { + if (logVars.slow_query_log === 'ON') { + msg = Messages.strBothLogOn; + } else { + msg = Messages.strGenLogOn; + } + } + + if (msg.length === 0 && logVars.slow_query_log === 'ON') { + msg = Messages.strSlowLogOn; + } + + if (msg.length === 0) { + icon = Functions.getImage('s_error'); + msg = Messages.strBothLogOff; + } + + str = '<b>' + Messages.strCurrentSettings + '</b><br><div class="smallIndent">'; + str += icon + msg + '<br>'; + + if (logVars.log_output !== 'TABLE') { + str += Functions.getImage('s_error') + ' ' + Messages.strLogOutNotTable + '<br>'; + } else { + str += Functions.getImage('s_success') + ' ' + Messages.strLogOutIsTable + '<br>'; + } + + if (logVars.slow_query_log === 'ON') { + if (logVars.long_query_time > 2) { + str += Functions.getImage('s_attention') + ' '; + str += Functions.sprintf(Messages.strSmallerLongQueryTimeAdvice, logVars.long_query_time); + str += '<br>'; + } + + if (logVars.long_query_time < 2) { + str += Functions.getImage('s_success') + ' '; + str += Functions.sprintf(Messages.strLongQueryTimeSet, logVars.long_query_time); + str += '<br>'; + } + } + + str += '</div>'; + + if (isSuperUser) { + str += '<p></p><b>' + Messages.strChangeSettings + '</b>'; + str += '<div class="smallIndent">'; + str += Messages.strSettingsAppliedGlobal + '<br>'; + + var varValue = 'TABLE'; + if (logVars.log_output === 'TABLE') { + varValue = 'FILE'; + } + + str += '- <a class="set" href="#log_output-' + varValue + '">'; + str += Functions.sprintf(Messages.strSetLogOutput, varValue); + str += ' </a><br>'; + + if (logVars.general_log !== 'ON') { + str += '- <a class="set" href="#general_log-ON">'; + str += Functions.sprintf(Messages.strEnableVar, 'general_log'); + str += ' </a><br>'; + } else { + str += '- <a class="set" href="#general_log-OFF">'; + str += Functions.sprintf(Messages.strDisableVar, 'general_log'); + str += ' </a><br>'; + } + + if (logVars.slow_query_log !== 'ON') { + str += '- <a class="set" href="#slow_query_log-ON">'; + str += Functions.sprintf(Messages.strEnableVar, 'slow_query_log'); + str += ' </a><br>'; + } else { + str += '- <a class="set" href="#slow_query_log-OFF">'; + str += Functions.sprintf(Messages.strDisableVar, 'slow_query_log'); + str += ' </a><br>'; + } + + varValue = 5; + if (logVars.long_query_time > 2) { + varValue = 1; + } + + str += '- <a class="set" href="#long_query_time-' + varValue + '">'; + str += Functions.sprintf(Messages.setSetLongQueryTime, varValue); + str += ' </a><br>'; + } else { + str += Messages.strNoSuperUser + '<br>'; + } + + str += '</div>'; + + $dialog.find('div.monitorUse').toggle( + logVars.log_output === 'TABLE' && (logVars.slow_query_log === 'ON' || logVars.general_log === 'ON') + ); + + $dialog.find('div.ajaxContent').html(str); + $dialog.find('img.ajaxIcon').hide(); + $dialog.find('a.set').on('click', function () { + var nameValue = $(this).attr('href').split('-'); + loadLogVars({ varName: nameValue[0].substr(1), varValue: nameValue[1] }); + $dialog.find('img.ajaxIcon').show(); + }); + } + ); + }; + + + loadLogVars(); + + return false; + }); + + $('input[name="chartType"]').on('change', function () { + $('#chartVariableSettings').toggle(this.checked && this.value === 'variable'); + var title = $('input[name="chartTitle"]').val(); + if (title === Messages.strChartTitle || + title === $('label[for="' + $('input[name="chartTitle"]').data('lastRadio') + '"]').text() + ) { + $('input[name="chartTitle"]') + .data('lastRadio', $(this).attr('id')) + .val($('label[for="' + $(this).attr('id') + '"]').text()); + } + }); + + $('input[name="useDivisor"]').on('change', function () { + $('span.divisorInput').toggle(this.checked); + }); + + $('input[name="useUnit"]').on('change', function () { + $('span.unitInput').toggle(this.checked); + }); + + $('select[name="varChartList"]').on('change', function () { + if (this.selectedIndex !== 0) { + $('#variableInput').val(this.value); + } + }); + + $('a[href="#kibDivisor"]').on('click', function (event) { + event.preventDefault(); + $('input[name="valueDivisor"]').val(1024); + $('input[name="valueUnit"]').val(Messages.strKiB); + $('span.unitInput').toggle(true); + $('input[name="useUnit"]').prop('checked', true); + return false; + }); + + $('a[href="#mibDivisor"]').on('click', function (event) { + event.preventDefault(); + $('input[name="valueDivisor"]').val(1024 * 1024); + $('input[name="valueUnit"]').val(Messages.strMiB); + $('span.unitInput').toggle(true); + $('input[name="useUnit"]').prop('checked', true); + return false; + }); + + $('a[href="#submitClearSeries"]').on('click', function (event) { + event.preventDefault(); + $('#seriesPreview').html('<i>' + Messages.strNone + '</i>'); + newChart = null; + $('#clearSeriesLink').hide(); + }); + + $('a[href="#submitAddSeries"]').on('click', function (event) { + event.preventDefault(); + if ($('#variableInput').val() === '') { + return false; + } + + if (newChart === null) { + $('#seriesPreview').html(''); + + newChart = { + title: $('input[name="chartTitle"]').val(), + nodes: [], + series: [], + maxYLabel: 0 + }; + } + + var serie = { + dataPoints: [{ type: 'statusvar', name: $('#variableInput').val() }], + display: $('input[name="differentialValue"]').prop('checked') ? 'differential' : '' + }; + + if (serie.dataPoints[0].name === 'Processes') { + serie.dataPoints[0].type = 'proc'; + } + + if ($('input[name="useDivisor"]').prop('checked')) { + serie.valueDivisor = parseInt($('input[name="valueDivisor"]').val(), 10); + } + + if ($('input[name="useUnit"]').prop('checked')) { + serie.unit = $('input[name="valueUnit"]').val(); + } + + var str = serie.display === 'differential' ? ', ' + Messages.strDifferential : ''; + str += serie.valueDivisor ? (', ' + Functions.sprintf(Messages.strDividedBy, serie.valueDivisor)) : ''; + str += serie.unit ? (', ' + Messages.strUnit + ': ' + serie.unit) : ''; + + var newSeries = { + label: $('#variableInput').val().replace(/_/g, ' ') + }; + newChart.series.push(newSeries); + $('#seriesPreview').append('- ' + Functions.escapeHtml(newSeries.label + str) + '<br>'); + newChart.nodes.push(serie); + $('#variableInput').val(''); + $('input[name="differentialValue"]').prop('checked', true); + $('input[name="useDivisor"]').prop('checked', false); + $('input[name="useUnit"]').prop('checked', false); + $('input[name="useDivisor"]').trigger('change'); + $('input[name="useUnit"]').trigger('change'); + $('select[name="varChartList"]').get(0).selectedIndex = 0; + + $('#clearSeriesLink').show(); + + return false; + }); + + $('#variableInput').autocomplete({ + source: variableNames + }); + + /* Initializes the monitor, called only once */ + function initGrid () { + var i; + + /* Apply default values & config */ + if (isStorageSupported('localStorage')) { + if (typeof window.localStorage.monitorCharts !== 'undefined') { + runtime.charts = JSON.parse(window.localStorage.monitorCharts); + } + if (typeof window.localStorage.monitorSetti |
