index-dashboard.js
663 lines
| 20.3 KiB
| application/javascript
|
JavascriptLexer
r112 | // Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors | |||
// | ||||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||||
// you may not use this file except in compliance with the License. | ||||
// You may obtain a copy of the License at | ||||
// | ||||
// http://www.apache.org/licenses/LICENSE-2.0 | ||||
// | ||||
// Unless required by applicable law or agreed to in writing, software | ||||
// distributed under the License is distributed on an "AS IS" BASIS, | ||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
// See the License for the specific language governing permissions and | ||||
// limitations under the License. | ||||
r0 | ||||
r75 | angular.module('appenlight.components.indexDashboardView', []) | |||
.component('indexDashboardView', { | ||||
templateUrl: 'components/views/index-dashboard/index-dashboard.html', | ||||
controller: IndexDashboardController | ||||
}); | ||||
r0 | ||||
r71 | IndexDashboardController.$inject = ['$rootScope', '$scope', '$location','$cookies', '$interval', 'stateHolder', 'applicationsPropertyResource', 'AeConfig']; | |||
r0 | ||||
r71 | function IndexDashboardController($rootScope, $scope, $location, $cookies, $interval, stateHolder, applicationsPropertyResource, AeConfig) { | |||
r0 | var vm = this; | |||
r147 | vm.$onInit = function () { | |||
stateHolder.section = 'dashboard'; | ||||
vm.timeOptions = {}; | ||||
var allowed = ['1h', '4h', '12h', '24h', '1w', '2w', '1M']; | ||||
_.each(allowed, function (key) { | ||||
if (allowed.indexOf(key) !== -1) { | ||||
vm.timeOptions[key] = AeConfig.timeOptions[key]; | ||||
} | ||||
}); | ||||
vm.stateHolder = stateHolder; | ||||
vm.urls = AeConfig.urls; | ||||
vm.applications = stateHolder.AeUser.applications_map; | ||||
vm.show_dashboard = false; | ||||
vm.resource = null; | ||||
vm.graphType = {selected: null}; | ||||
vm.timeSpan = vm.timeOptions['1h']; | ||||
vm.trendingReports = []; | ||||
vm.exceptions = 0; | ||||
vm.satisfyingRequests = 0; | ||||
vm.toleratedRequests = 0; | ||||
vm.frustratingRequests = 0; | ||||
vm.uptimeStats = 0; | ||||
vm.apdexStats = []; | ||||
vm.seriesRequestsData = []; | ||||
vm.seriesMetricsData = []; | ||||
vm.seriesSlowData = []; | ||||
vm.slowCalls = []; | ||||
vm.slowURIS = []; | ||||
vm.reportChartConfig = { | ||||
data: { | ||||
json: [], | ||||
xFormat: '%Y-%m-%dT%H:%M:%S' | ||||
}, | ||||
color: { | ||||
pattern: ['#6baed6', '#e6550d', '#74c476', '#fdd0a2', '#8c564b'] | ||||
}, | ||||
axis: { | ||||
x: { | ||||
type: 'timeseries', | ||||
tick: { | ||||
culling: { | ||||
max: 6 // the number of tick texts will be adjusted to less than this value | ||||
}, | ||||
format: '%Y-%m-%d %H:%M' | ||||
} | ||||
}, | ||||
y: { | ||||
tick: { | ||||
count: 5, | ||||
format: d3.format('.2s') | ||||
} | ||||
r0 | } | |||
}, | ||||
r147 | subchart: { | |||
show: true, | ||||
size: { | ||||
height: 20 | ||||
r0 | } | |||
r147 | }, | |||
r0 | size: { | |||
r147 | height: 250 | |||
}, | ||||
zoom: { | ||||
rescale: true | ||||
}, | ||||
grid: { | ||||
x: { | ||||
show: true | ||||
r0 | }, | |||
r147 | y: { | |||
show: true | ||||
r0 | } | |||
r147 | }, | |||
tooltip: { | ||||
format: { | ||||
title: function (d) { | ||||
return '' + d; | ||||
r0 | }, | |||
r147 | value: function (v) { | |||
return v | ||||
} | ||||
r0 | } | |||
r147 | } | |||
}; | ||||
vm.reportChartData = {}; | ||||
vm.reportSlowChartConfig = { | ||||
data: { | ||||
json: [], | ||||
xFormat: '%Y-%m-%dT%H:%M:%S' | ||||
r0 | }, | |||
r147 | color: { | |||
pattern: ['#6baed6', '#e6550d', '#74c476', '#fdd0a2', '#8c564b'] | ||||
}, | ||||
axis: { | ||||
x: { | ||||
type: 'timeseries', | ||||
tick: { | ||||
culling: { | ||||
max: 6 // the number of tick texts will be adjusted to less than this value | ||||
}, | ||||
format: '%Y-%m-%d %H:%M' | ||||
} | ||||
}, | ||||
y: { | ||||
tick: { | ||||
count: 5, | ||||
format: d3.format('.2s') | ||||
} | ||||
r0 | } | |||
r147 | }, | |||
subchart: { | ||||
show: true, | ||||
size: { | ||||
height: 20 | ||||
} | ||||
}, | ||||
r0 | size: { | |||
r147 | height: 250 | |||
}, | ||||
zoom: { | ||||
rescale: true | ||||
}, | ||||
grid: { | ||||
x: { | ||||
show: true | ||||
r0 | }, | |||
r147 | y: { | |||
show: true | ||||
r0 | } | |||
r147 | }, | |||
tooltip: { | ||||
format: { | ||||
title: function (d) { | ||||
return '' + d; | ||||
r0 | }, | |||
r147 | value: function (v) { | |||
return v | ||||
} | ||||
} | ||||
} | ||||
}; | ||||
vm.reportSlowChartData = {}; | ||||
vm.metricsChartConfig = { | ||||
data: { | ||||
json: [], | ||||
xFormat: '%Y-%m-%dT%H:%M:%S', | ||||
keys: { | ||||
x: 'x', | ||||
value: ["main", "sql", "nosql", "tmpl", "remote", "custom"] | ||||
}, | ||||
names: { | ||||
main: 'View/Application logic', | ||||
sql: 'Relational database queries', | ||||
nosql: 'NoSql datastore calls', | ||||
tmpl: 'Template rendering', | ||||
custom: 'Custom timed calls', | ||||
remote: 'Requests to remote resources' | ||||
}, | ||||
type: 'area', | ||||
groups: [["main", "sql", "nosql", "remote", "custom", "tmpl"]], | ||||
order: null | ||||
}, | ||||
color: { | ||||
pattern: ['#6baed6', '#c7e9c0', '#fd8d3c', '#d6616b', '#ffcc00', '#c6dbef'] | ||||
}, | ||||
axis: { | ||||
x: { | ||||
type: 'timeseries', | ||||
tick: { | ||||
culling: { | ||||
max: 6 // the number of tick texts will be adjusted to less than this value | ||||
}, | ||||
format: '%Y-%m-%d %H:%M' | ||||
} | ||||
}, | ||||
y: { | ||||
tick: { | ||||
count: 5, | ||||
format: d3.format('.2f') | ||||
} | ||||
r0 | } | |||
}, | ||||
r147 | point: { | |||
show: false | ||||
}, | ||||
subchart: { | ||||
show: true, | ||||
size: { | ||||
height: 20 | ||||
r0 | } | |||
r147 | }, | |||
r0 | size: { | |||
r147 | height: 350 | |||
}, | ||||
zoom: { | ||||
rescale: true | ||||
}, | ||||
grid: { | ||||
x: { | ||||
show: true | ||||
r0 | }, | |||
r147 | y: { | |||
show: true | ||||
r0 | } | |||
r147 | }, | |||
tooltip: { | ||||
format: { | ||||
title: function (d) { | ||||
return '' + d; | ||||
r0 | }, | |||
r147 | value: function (v) { | |||
return v | ||||
} | ||||
r0 | } | |||
r147 | } | |||
}; | ||||
vm.metricsChartData = {}; | ||||
vm.responseChartConfig = { | ||||
data: { | ||||
json: [], | ||||
xFormat: '%Y-%m-%dT%H:%M:%S' | ||||
r0 | }, | |||
r147 | color: { | |||
pattern: ['#d6616b', '#6baed6', '#fd8d3c'] | ||||
}, | ||||
axis: { | ||||
x: { | ||||
type: 'timeseries', | ||||
tick: { | ||||
culling: { | ||||
max: 6 // the number of tick texts will be adjusted to less than this value | ||||
}, | ||||
format: '%Y-%m-%d %H:%M' | ||||
} | ||||
}, | ||||
y: { | ||||
tick: { | ||||
count: 5, | ||||
format: d3.format('.2f') | ||||
} | ||||
r0 | } | |||
r147 | }, | |||
point: { | ||||
show: false | ||||
}, | ||||
subchart: { | ||||
show: true, | ||||
size: { | ||||
height: 20 | ||||
} | ||||
}, | ||||
r0 | size: { | |||
r147 | height: 350 | |||
}, | ||||
zoom: { | ||||
rescale: true | ||||
}, | ||||
grid: { | ||||
x: { | ||||
show: true | ||||
r0 | }, | |||
r147 | y: { | |||
show: true | ||||
r0 | } | |||
r147 | }, | |||
tooltip: { | ||||
format: { | ||||
title: function (d) { | ||||
return '' + d; | ||||
r0 | }, | |||
r147 | value: function (v) { | |||
return v | ||||
} | ||||
r0 | } | |||
r147 | } | |||
}; | ||||
vm.responseChartData = {}; | ||||
vm.requestsChartConfig = { | ||||
data: { | ||||
json: [], | ||||
xFormat: '%Y-%m-%dT%H:%M:%S' | ||||
}, | ||||
color: { | ||||
pattern: ['#d6616b', '#6baed6', '#fd8d3c'] | ||||
r0 | }, | |||
r147 | axis: { | |||
x: { | ||||
type: 'timeseries', | ||||
tick: { | ||||
culling: { | ||||
max: 6 // the number of tick texts will be adjusted to less than this value | ||||
}, | ||||
format: '%Y-%m-%d %H:%M' | ||||
} | ||||
}, | ||||
y: { | ||||
tick: { | ||||
count: 5, | ||||
format: d3.format('.2f') | ||||
} | ||||
r0 | } | |||
r147 | }, | |||
point: { | ||||
show: false | ||||
}, | ||||
subchart: { | ||||
show: true, | ||||
size: { | ||||
height: 20 | ||||
} | ||||
}, | ||||
r0 | size: { | |||
r147 | height: 350 | |||
}, | ||||
zoom: { | ||||
rescale: true | ||||
}, | ||||
grid: { | ||||
x: { | ||||
show: true | ||||
r0 | }, | |||
r147 | y: { | |||
show: true | ||||
r0 | } | |||
r147 | }, | |||
tooltip: { | ||||
format: { | ||||
title: function (d) { | ||||
return '' + d; | ||||
}, | ||||
value: function (v) { | ||||
return v | ||||
} | ||||
} | ||||
} | ||||
}; | ||||
vm.requestsChartData = {}; | ||||
vm.loading = { | ||||
'apdex': true, | ||||
'reports': true, | ||||
'graphs': true, | ||||
'slowCalls': true, | ||||
'slowURIS': true, | ||||
'requestsBreakdown': true, | ||||
'series': true | ||||
}; | ||||
vm.stream = {paused: false, filtered: false, messages: [], reports: []}; | ||||
vm.intervalId = $interval(function () { | ||||
if (_.contains(['30m', "1h"], vm.timeSpan.key)) { | ||||
// don't do anything if window is unfocused | ||||
if(document.hidden === true){ | ||||
return ; | ||||
} | ||||
vm.refreshData(); | ||||
r0 | } | |||
r147 | }, 60000); | |||
if (stateHolder.AeUser.applications.length){ | ||||
vm.show_dashboard = true; | ||||
vm.determineStartState(); | ||||
r0 | } | |||
r147 | } | |||
r71 | $rootScope.$on('channelstream-message.front_dashboard.new_topic', function(event, message){ | |||
r64 | var ws_report = message.message.report; | |||
if (ws_report.http_status != 500) { | ||||
return | ||||
} | ||||
if (vm.stream.paused == true) { | ||||
return | ||||
} | ||||
if (vm.stream.filtered && ws_report.resource_id != vm.resource) { | ||||
return | ||||
} | ||||
var should_insert = true; | ||||
_.each(vm.stream.reports, function (report) { | ||||
if (report.report_id == ws_report.report_id) { | ||||
report.occurences = ws_report.occurences; | ||||
should_insert = false; | ||||
} | ||||
}); | ||||
if (should_insert) { | ||||
if (vm.stream.reports.length > 7) { | ||||
vm.stream.reports.pop(); | ||||
} | ||||
vm.stream.reports.unshift(ws_report); | ||||
} | ||||
r0 | }); | |||
vm.determineStartState = function () { | ||||
r62 | if (stateHolder.AeUser.applications.length) { | |||
r0 | vm.resource = Number($location.search().resource); | |||
if (!vm.resource){ | ||||
var cookieResource = $cookies.getObject('resource'); | ||||
console.log('cookieResource', cookieResource); | ||||
if (cookieResource) { | ||||
vm.resource = cookieResource; | ||||
} | ||||
else{ | ||||
r62 | vm.resource = stateHolder.AeUser.applications[0].resource_id; | |||
r0 | } | |||
} | ||||
} | ||||
var timespan = $location.search().timespan; | ||||
if(_.has(vm.timeOptions, timespan)){ | ||||
vm.timeSpan = vm.timeOptions[timespan]; | ||||
} | ||||
else{ | ||||
vm.timeSpan = vm.timeOptions['1h']; | ||||
} | ||||
var graphType = $location.search().graphtype; | ||||
if(!graphType){ | ||||
vm.graphType = {selected: 'metrics_graphs'}; | ||||
} | ||||
else{ | ||||
vm.graphType = {selected: graphType}; | ||||
} | ||||
vm.updateSearchParams(); | ||||
}; | ||||
vm.updateSearchParams = function () { | ||||
$location.search('resource', vm.resource); | ||||
$location.search('timespan', vm.timeSpan.key); | ||||
$location.search('graphtype', vm.graphType.selected); | ||||
stateHolder.resource = vm.resource; | ||||
r74 | ||||
r0 | if (vm.resource){ | |||
$cookies.putObject('resource', vm.resource, | ||||
{expires:new Date(3000, 1, 1)}); | ||||
} | ||||
r74 | vm.refreshData(); | |||
r0 | }; | |||
vm.refreshData = function () { | ||||
vm.fetchApdexStats(); | ||||
vm.fetchTrendingReports(); | ||||
vm.fetchMetrics(); | ||||
vm.fetchRequestsBreakdown(); | ||||
vm.fetchSlowCalls(); | ||||
r64 | }; | |||
r0 | ||||
vm.changedTimeSpan = function(){ | ||||
vm.startDateFilter = timeSpanToStartDate(vm.timeSpan.key); | ||||
vm.refreshData(); | ||||
r64 | }; | |||
r0 | ||||
vm.fetchApdexStats = function () { | ||||
vm.loading.apdex = true; | ||||
vm.apdexStats = applicationsPropertyResource.query({ | ||||
'key': 'apdex_stats', | ||||
'resourceId': vm.resource, | ||||
"start_date": timeSpanToStartDate(vm.timeSpan.key) | ||||
}, | ||||
function (data) { | ||||
vm.loading.apdex = false; | ||||
vm.exceptions = _.reduce(data, function (memo, row) { | ||||
return memo + row.errors; | ||||
}, 0); | ||||
vm.satisfyingRequests = _.reduce(data, function (memo, row) { | ||||
return memo + row.satisfying_requests; | ||||
}, 0); | ||||
vm.toleratedRequests = _.reduce(data, function (memo, row) { | ||||
return memo + row.tolerated_requests; | ||||
}, 0); | ||||
vm.frustratingRequests = _.reduce(data, function (memo, row) { | ||||
return memo + row.frustrating_requests; | ||||
}, 0); | ||||
if (data.length) { | ||||
vm.uptimeStats = data[0].uptime; | ||||
} | ||||
}, | ||||
function () { | ||||
vm.loading.apdex = false; | ||||
} | ||||
); | ||||
} | ||||
vm.fetchMetrics = function () { | ||||
vm.loading.series = true; | ||||
applicationsPropertyResource.query({ | ||||
'resourceId': vm.resource, | ||||
'key': vm.graphType.selected, | ||||
"start_date": timeSpanToStartDate(vm.timeSpan.key) | ||||
}, function (data) { | ||||
if (vm.graphType.selected == 'metrics_graphs') { | ||||
vm.metricsChartData = { | ||||
json: data, | ||||
xFormat: '%Y-%m-%dT%H:%M:%S', | ||||
keys: { | ||||
x: 'x', | ||||
value: ["main", "sql", "nosql", "tmpl", "remote", "custom"] | ||||
}, | ||||
names: { | ||||
main: 'View/Application logic', | ||||
sql: 'Relational database queries', | ||||
nosql: 'NoSql datastore calls', | ||||
tmpl: 'Template rendering', | ||||
custom: 'Custom timed calls', | ||||
remote: 'Requests to remote resources' | ||||
}, | ||||
type: 'area', | ||||
groups: [["main", "sql", "nosql", "remote", "custom", "tmpl"]], | ||||
order: null | ||||
}; | ||||
} | ||||
else if (vm.graphType.selected == 'report_graphs') { | ||||
vm.reportChartData = { | ||||
json: data, | ||||
xFormat: '%Y-%m-%dT%H:%M:%S', | ||||
keys: { | ||||
x: 'x', | ||||
value: ["not_found", "report"] | ||||
}, | ||||
names: { | ||||
report: 'Errors', | ||||
not_found: '404\'s requests' | ||||
}, | ||||
type: 'bar' | ||||
}; | ||||
} | ||||
else if (vm.graphType.selected == 'slow_report_graphs') { | ||||
vm.reportSlowChartData = { | ||||
json: data, | ||||
xFormat: '%Y-%m-%dT%H:%M:%S', | ||||
keys: { | ||||
x: 'x', | ||||
value: ["slow_report"] | ||||
}, | ||||
names: { | ||||
slow_report: 'Slow reports' | ||||
}, | ||||
type: 'bar' | ||||
}; | ||||
} | ||||
else if (vm.graphType.selected == 'response_graphs') { | ||||
vm.responseChartData = { | ||||
json: data, | ||||
xFormat: '%Y-%m-%dT%H:%M:%S', | ||||
keys: { | ||||
x: 'x', | ||||
value: ["today", "days_ago_2", "days_ago_7"] | ||||
}, | ||||
names: { | ||||
today: 'Today', | ||||
"days_ago_2": '2 days ago', | ||||
"days_ago_7": '7 days ago' | ||||
} | ||||
}; | ||||
} | ||||
else if (vm.graphType.selected == 'requests_graphs') { | ||||
vm.requestsChartData = { | ||||
json: data, | ||||
xFormat: '%Y-%m-%dT%H:%M:%S', | ||||
keys: { | ||||
x: 'x', | ||||
value: ["requests"] | ||||
}, | ||||
names: { | ||||
requests: 'Requests/s' | ||||
} | ||||
}; | ||||
} | ||||
vm.loading.series = false; | ||||
}, function(){ | ||||
vm.loading.series = false; | ||||
}); | ||||
} | ||||
vm.fetchSlowCalls = function () { | ||||
vm.loading.slowCalls = true; | ||||
applicationsPropertyResource.query({ | ||||
'resourceId': vm.resource, | ||||
"start_date": timeSpanToStartDate(vm.timeSpan.key), | ||||
'key': 'slow_calls' | ||||
}, function (data) { | ||||
vm.slowCalls = data; | ||||
vm.loading.slowCalls = false; | ||||
}, function () { | ||||
vm.loading.slowCalls = false; | ||||
}); | ||||
} | ||||
vm.fetchRequestsBreakdown = function () { | ||||
vm.loading.requestsBreakdown = true; | ||||
applicationsPropertyResource.query({ | ||||
'resourceId': vm.resource, | ||||
"start_date": timeSpanToStartDate(vm.timeSpan.key), | ||||
'key': 'requests_breakdown' | ||||
}, function (data) { | ||||
vm.requestsBreakdown = data; | ||||
vm.loading.requestsBreakdown = false; | ||||
}, function () { | ||||
vm.loading.requestsBreakdown = false; | ||||
}); | ||||
} | ||||
vm.fetchTrendingReports = function () { | ||||
if (vm.graphType.selected == 'slow_report_graphs') { | ||||
var report_type = 'slow'; | ||||
} | ||||
else { | ||||
var report_type = 'error'; | ||||
} | ||||
vm.loading.reports = true; | ||||
vm.trendingReports = applicationsPropertyResource.query({ | ||||
'key': 'trending_reports', | ||||
'resourceId': vm.resource, | ||||
"start_date": timeSpanToStartDate(vm.timeSpan.key), | ||||
"report_type": report_type | ||||
}, | ||||
function () { | ||||
vm.loading.reports = false; | ||||
}, | ||||
function () { | ||||
vm.loading.reports = false; | ||||
} | ||||
r71 | ); | |||
}; | ||||
r0 | ||||
r74 | $scope.$on('$destroy',function(){ | |||
$interval.cancel(vm.intervalId); | ||||
}); | ||||
r0 | } | |||