var App = {
queuedJobsCountHistory: [], failedJobsCountHistory: [], jobsCompletedHistory: [], jobsCompletedPerSecondHistory: [], totalMemoryHistory: [], maxTime: 1000, pollingInterval: 10, chartFont: 'arial', freshDataCount: function() { return (this.maxTime / (this.pollingInterval) ) + 1; }, tab: null, removeStaleData: function() { if (this.queuedJobsCountHistory.length > this.freshDataCount) { this.queuedJobsCountHistory.pop(); this.failedJobsCountHistory.pop(); this.jobsCompletedHistory.pop(); this.totalMemoryHistory.pop(); } }, getUrlParameter: function(param) { var pageUrl = decodeURIComponent(window.location.search.substring(1)); var urlVariables = pageUrl.split('&') var parameterName; for (var i = 0; i < urlVariables.length; i++) { parameterName = urlVariables[i].split('='); if (parameterName[0] === param) { return parameterName[1] === undefined ? true : parameterName[1]; } } }, getOverviewData: function() { $.ajax({ url: 'overview-data', context: this, success: function(data) { var deserializedData = JSON.parse(data); var scheduledJobsCount = deserializedData.scheduled_jobs; var completedJobs = deserializedData.completed_jobs.reduce(function(sum, subArray) { return sum + subArray[1]; }, 0); var failedJobsCount= deserializedData.failed_jobs.reduce(function(sum, subArray) { return sum + subArray[1]; }, 0); var queuedJobs = deserializedData.queued_jobs; var queuedJobsCount = queuedJobs.reduce(function(sum, queue) { return sum + queue[1]; }, 0); var memoryUsage = deserializedData.memory_usage; var totalMemoryUsage = 0; $('.removable').remove(); for (id in memoryUsage) { totalMemoryUsage = totalMemoryUsage + parseInt(memoryUsage[id]); $('.nested').last().after("<tr class='nested removable'><td>" + id + "</td><td id='process_" + id + "'" + "class='process_memory'" + ">" + memoryUsage[id] / 1000 + ' MB' + "</td></tr>") } this.queuedJobsCountHistory.unshift(queuedJobsCount); this.failedJobsCountHistory.unshift(failedJobsCount); this.jobsCompletedHistory.unshift(completedJobs); this.totalMemoryHistory.unshift(totalMemoryUsage / 1000); for (var i = 0; i < this.freshDataCount(); i++) { this.jobsCompletedPerSecondHistory[i] = (parseInt(deserializedData.completed_jobs_per_second[i]) / 10 || 0); } this.removeStaleData(); this.drawChart(); $('.completed_jobs').text(completedJobs); $('.failed_jobs').text(failedJobsCount); $('.queue_count').text(queuedJobs.length); $('.queued_jobs_count').text(queuedJobsCount); $('.scheduled_jobs').text(scheduledJobsCount); $('.memory_usage').text(totalMemoryUsage / 1000 + ' MB'); } }); }, getQueueData: function() { $.ajax({ url: 'queues-data', success: function(data) { var deserializedData = JSON.parse(data); var queuedJobs = deserializedData.queued_jobs; var total = 0; for (var i = 0; i < queuedJobs.length; i++) { $('#queue_name_' + queuedJobs[i][0].split(':').pop()).text(queuedJobs[i][0]); $('#queue_count_' + queuedJobs[i][0].split(':').pop()).text(queuedJobs[i][1]); total = total + queuedJobs[i][1]; } $('#queue_total').text(total); } }); }, getDetailData: function() { $.ajax({ url: 'details-data', success: function(data) { var deserializedData = JSON.parse(data); var completedJobs = deserializedData.completed_jobs; var failedJobs = deserializedData.failed_jobs; var completedTotal = 0; var failedTotal = 0; completedJobs.forEach(function(job) { $('#completed_' + job[0]).text(job[1]); completedTotal = completedTotal + job[1]; }); failedJobs.forEach(function(job) { $('#failed_' + job[0]).text(job[1]); failedTotal = failedTotal + job[1]; }); $('#failed_total').text(failedTotal); $('#completed_total').text(completedTotal); } }) }, getHistoryData: function() { var className = $('#class_selector select').find(':selected').val(); var days = this.getUrlParameter('days') || 7; $('#button_' + days).addClass('is-dark'); $('#class_selector').on('change', function(e) { location = window.location.origin + window.location.pathname + '?days=' + days + '&class=' + e.target.value; }); $('#day_tabs a').on('click', function(e) { e.preventDefault(); location = window.location.origin + window.location.pathname + '?days=' + $(e.target).attr('data-day') + '&class=' + className; }); $.ajax({ url: 'historic-data', data: { days: days, className: className, }, dataType: 'json', success: function(data) { this.drawHistoryChart(days, className, data['completed_jobs'], data['failed_jobs']); }.bind(this) }) }, getHistoricalOverviewData: function() { $.ajax({ url: 'overview-data-on-load', dataType: 'json', success: function(data) { for (var i = 0; i < this.freshDataCount(); i++) { this.jobsCompletedPerSecondHistory[i] = (parseInt(data['completed_jobs'][i]) / 10 || 0); } for (var i = 0; i < this.freshDataCount(); i++) { this.failedJobsCountHistory.push(parseInt(data['failed_jobs'][i]) || 0); } for (var i = 0; i < this.freshDataCount(); i++) { this.queuedJobsCountHistory.push(0); } for (var i = 0; i < this.freshDataCount(); i++) { this.totalMemoryHistory.push(0); } this.drawChart(); }.bind(this) }) }, drawChart: function() { var processedJobsChart = new CanvasJS.Chart('jobs_processed_container', { title: { text: 'Jobs Processed per second', fontFamily: 'Arial', fontSize: 24, }, axisX: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, reversed: true, gridColor: 'Silver', tickColor: 'silver', animationEnabled: true, title: 'Time ago (s)', maximum: this.maxTime }, toolTip: { shared: true }, theme: "theme2", axisY: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: "Silver", tickColor: "silver", title: 'Jobs per second', }, data: [{ type: "line", showInLegend: false, name: "Jobs completed", color: "blue", markerType: 'circle', lineThickness: 6, dataPoints: this.setDataPoints(this.jobsCompletedPerSecondHistory, this.freshDataCount()), }] }); var queuedJobsChart = new CanvasJS.Chart('queued_jobs_container', { title: { text: 'Queued Jobs', fontFamily: 'Arial', fontSize: 24, }, axisX: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, reversed: true, gridColor: 'Silver', tickColor: 'silver', animationEnabled: true, title: 'Time ago (s)', // minimum: 0, maximum: this.maxTime, }, toolTip: { shared: true }, theme: "theme2", axisY: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: "Silver", tickColor: "silver", title: 'Jobs' }, data: [{ type: "line", showInLegend: false, lineThickness: 6, name: "Queued Jobs", markerType: "circle", color: "#F08080", dataPoints: this.setDataPoints(this.queuedJobsCountHistory, this.freshDataCount()), }], }); var failedJobsChart = new CanvasJS.Chart('failed_jobs_container', { title: { text: 'Failed Jobs', fontFamily: 'Arial', fontSize: 24, }, axisX: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, reversed: true, gridColor: 'Silver', tickColor: 'silver', animationEnabled: true, title: 'Time ago (s)', // minimum: 0, maximum: this.maxTime, }, toolTip: { shared: true }, theme: "theme2", axisY: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: "Silver", tickColor: "silver", title: 'Jobs' }, data: [{ type: "line", showInLegend: false, name: "Failed Jobs", color: "#20B2AA", markerType: 'circle', lineThickness: 6, dataPoints: this.setDataPoints(this.failedJobsCountHistory, this.freshDataCount()), }, ] }); var totalMemoryChart = new CanvasJS.Chart('total_memory_container', { title: { text: 'Memory Usage', fontFamily: 'Arial', fontSize: 24, }, axisX: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, reversed: true, gridColor: 'Silver', tickColor: 'silver', animationEnabled: true, title: 'Time ago (s)', // minimum: 0, maximum: this.maxTime }, toolTip: { shared: true }, theme: "theme2", axisY: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: "Silver", tickColor: "silver", title: 'Memory (mb)' }, data: [{ type: "line", showInLegend: false, name: "Memory usage", color: "#20B2AA", markerType: 'circle', lineThickness: 6, dataPoints: this.setDataPoints(this.totalMemoryHistory, this.freshDataCount()), }], }); queuedJobsChart.render(); failedJobsChart.render(); processedJobsChart.render(); totalMemoryChart.render(); }, drawHistoryChart: function(days, className, completed_jobs, failed_jobs) { var completedHistoryChart = new CanvasJS.Chart('history_container_completed', { title: { text: 'Completed History for ' + days + ' days', fontFamily: 'Arial', fontSize: 24, }, axisX: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: 'Silver', tickColor: 'silver', animationEnabled: true, title: 'Date', minimum: parseInt((completed_jobs['date_ranges'][days]) * 1000), }, toolTip: { shared: true }, theme: "theme2", axisY: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: "Silver", tickColor: "silver", title: 'Jobs' }, data: [{ type: "line", showInLegend: false, name: "Completed Job for " + className, color: "#20B2AA", markerType: 'circle', lineThickness: 2, xValueType: 'dateTime', dataPoints: this.setHistoryDataPoints(completed_jobs), }], }); var failedHistoryChart = new CanvasJS.Chart('history_container_failed', { title: { text: 'Failed History for ' + days + ' days', fontFamily: 'Arial', fontSize: 24, }, axisX: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: 'Silver', tickColor: 'silver', animationEnabled: true, title: 'Date', minimum: parseInt((completed_jobs['date_ranges'][days]) * 1000), }, toolTip: { shared: true }, theme: "theme2", axisY: { labelFontFamily: this.chartFont, titleFontFamily: this.chartFont, gridColor: "Silver", tickColor: "silver", title: 'Jobs' }, data: [{ type: "line", showInLegend: false, name: "Failed Jobs for " + className, color: "#20B2AA", markerType: 'circle', lineThickness: 2, xValueType: 'dateTime', dataPoints: this.setHistoryDataPoints(failed_jobs), }], }); completedHistoryChart.render(); failedHistoryChart.render(); }, setHistoryDataPoints: function(jobs) { data = [] for (var i = 0; i <= jobs['date_ranges'].length; i++) { var point = { x: this.getLocalDate(parseInt(jobs['date_ranges'][i])).getTime(), y: jobs['job_counts'][i]}; data.push(point); } return data; }, setDataPoints: function(array, count) { var data = []; for (var i = 0; i <= count; i++) { var point = { x: (i * this.pollingInterval).toString(), y: array[i] }; data.push(point); } return data; }, getLocalDate: function(seconds) { var date = new Date(seconds * 1000); var day = date.getUTCDate(); var month = date.getUTCMonth(); var year = date.getUTCFullYear(); return new Date(year, month, day); }, setActiveTab: function() { this.tab = $(location).attr('href').match(/(?:(?!\?).)*/)[0].split('/').pop(); var $active = $('a[href=' + this.tab + ']'); $active.addClass('is-active'); }, pollData: function(tab) { if (tab === 'overview') { this.getHistoricalOverviewData(); this.getOverviewData(); setInterval(function() { this.getOverviewData(); }.bind(this), this.pollingInterval * 1000); } if (tab === 'queues') { setInterval(function() { this.getQueueData(); }.bind(this), this.pollingInterval * 1000); } if (tab === 'details') { setInterval(function() { this.getDetailData(); }.bind(this), this.pollingInterval * 1000); } if (tab === 'history') { this.getHistoryData(); } }, bindEvents: function() { $('#memory_usage').on('click', function(e) { $('.nested th').toggle(); $('.nested td').toggle(); }); }, init: function() { this.setActiveTab(); this.bindEvents(); this.pollData(this.tab); }
}
$(document).ready(App.init.bind(App));