##// END OF EJS Templates
setup: change url to github
setup: change url to github

File last commit:

r147:bb4c1b51
r196:472d1df0 master
Show More
index-dashboard.js
663 lines | 20.3 KiB | application/javascript | JavascriptLexer
// 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.
angular.module('appenlight.components.indexDashboardView', [])
.component('indexDashboardView', {
templateUrl: 'components/views/index-dashboard/index-dashboard.html',
controller: IndexDashboardController
});
IndexDashboardController.$inject = ['$rootScope', '$scope', '$location','$cookies', '$interval', 'stateHolder', 'applicationsPropertyResource', 'AeConfig'];
function IndexDashboardController($rootScope, $scope, $location, $cookies, $interval, stateHolder, applicationsPropertyResource, AeConfig) {
var vm = this;
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')
}
}
},
subchart: {
show: true,
size: {
height: 20
}
},
size: {
height: 250
},
zoom: {
rescale: true
},
grid: {
x: {
show: true
},
y: {
show: true
}
},
tooltip: {
format: {
title: function (d) {
return '' + d;
},
value: function (v) {
return v
}
}
}
};
vm.reportChartData = {};
vm.reportSlowChartConfig = {
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')
}
}
},
subchart: {
show: true,
size: {
height: 20
}
},
size: {
height: 250
},
zoom: {
rescale: true
},
grid: {
x: {
show: true
},
y: {
show: true
}
},
tooltip: {
format: {
title: function (d) {
return '' + d;
},
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')
}
}
},
point: {
show: false
},
subchart: {
show: true,
size: {
height: 20
}
},
size: {
height: 350
},
zoom: {
rescale: true
},
grid: {
x: {
show: true
},
y: {
show: true
}
},
tooltip: {
format: {
title: function (d) {
return '' + d;
},
value: function (v) {
return v
}
}
}
};
vm.metricsChartData = {};
vm.responseChartConfig = {
data: {
json: [],
xFormat: '%Y-%m-%dT%H:%M:%S'
},
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')
}
}
},
point: {
show: false
},
subchart: {
show: true,
size: {
height: 20
}
},
size: {
height: 350
},
zoom: {
rescale: true
},
grid: {
x: {
show: true
},
y: {
show: true
}
},
tooltip: {
format: {
title: function (d) {
return '' + d;
},
value: function (v) {
return v
}
}
}
};
vm.responseChartData = {};
vm.requestsChartConfig = {
data: {
json: [],
xFormat: '%Y-%m-%dT%H:%M:%S'
},
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')
}
}
},
point: {
show: false
},
subchart: {
show: true,
size: {
height: 20
}
},
size: {
height: 350
},
zoom: {
rescale: true
},
grid: {
x: {
show: true
},
y: {
show: true
}
},
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();
}
}, 60000);
if (stateHolder.AeUser.applications.length){
vm.show_dashboard = true;
vm.determineStartState();
}
}
$rootScope.$on('channelstream-message.front_dashboard.new_topic', function(event, message){
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);
}
});
vm.determineStartState = function () {
if (stateHolder.AeUser.applications.length) {
vm.resource = Number($location.search().resource);
if (!vm.resource){
var cookieResource = $cookies.getObject('resource');
console.log('cookieResource', cookieResource);
if (cookieResource) {
vm.resource = cookieResource;
}
else{
vm.resource = stateHolder.AeUser.applications[0].resource_id;
}
}
}
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;
if (vm.resource){
$cookies.putObject('resource', vm.resource,
{expires:new Date(3000, 1, 1)});
}
vm.refreshData();
};
vm.refreshData = function () {
vm.fetchApdexStats();
vm.fetchTrendingReports();
vm.fetchMetrics();
vm.fetchRequestsBreakdown();
vm.fetchSlowCalls();
};
vm.changedTimeSpan = function(){
vm.startDateFilter = timeSpanToStartDate(vm.timeSpan.key);
vm.refreshData();
};
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;
}
);
};
$scope.$on('$destroy',function(){
$interval.cancel(vm.intervalId);
});
}