mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Improved error handling via alertSrv service
This commit is contained in:
parent
275221f3e6
commit
f4f8577d91
@ -32,8 +32,8 @@
|
|||||||
<link rel="stylesheet" href="common/css/bootstrap-responsive.min.css">
|
<link rel="stylesheet" href="common/css/bootstrap-responsive.min.css">
|
||||||
<link rel="stylesheet" href="common/css/font-awesome.min.css">
|
<link rel="stylesheet" href="common/css/font-awesome.min.css">
|
||||||
|
|
||||||
<div ng-repeat='alert in global_alert' class="alert-{{alert.severity}} dashboard-notice" ng-show="$last">
|
<div ng-repeat='alert in dashAlerts.list' class="alert-{{alert.severity}} dashboard-notice" ng-show="$last">
|
||||||
<button type="button" class="close" ng-click="clear_alert(alert)" style="padding-right:50px">×</button>
|
<button type="button" class="close" ng-click="dashAlerts.clear(alert)" style="padding-right:50px">×</button>
|
||||||
<strong>{{alert.title}}</strong> <span ng-bind-html-unsafe='alert.text'></span> <div style="padding-right:10px" class='pull-right small'> {{$index + 1}} alert(s) </div>
|
<strong>{{alert.title}}</strong> <span ng-bind-html-unsafe='alert.text'></span> <div style="padding-right:10px" class='pull-right small'> {{$index + 1}} alert(s) </div>
|
||||||
</div>
|
</div>
|
||||||
<div class="navbar navbar-static-top">
|
<div class="navbar navbar-static-top">
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
angular.module('kibana.controllers', [])
|
angular.module('kibana.controllers', [])
|
||||||
.controller('DashCtrl', function($scope, $rootScope, $http, $timeout, $route, ejsResource,
|
.controller('DashCtrl', function($scope, $rootScope, $http, $timeout, $route, ejsResource,
|
||||||
fields, dashboard) {
|
fields, dashboard, alertSrv) {
|
||||||
|
|
||||||
$scope.editor = {
|
$scope.editor = {
|
||||||
index: 0
|
index: 0
|
||||||
@ -16,11 +16,12 @@ angular.module('kibana.controllers', [])
|
|||||||
// Make underscore.js available to views
|
// Make underscore.js available to views
|
||||||
$scope._ = _;
|
$scope._ = _;
|
||||||
$scope.dashboard = dashboard;
|
$scope.dashboard = dashboard;
|
||||||
|
$scope.dashAlerts = alertSrv;
|
||||||
|
alertSrv.clearAll();
|
||||||
|
|
||||||
// Provide a global list of all see fields
|
// Provide a global list of all see fields
|
||||||
$scope.fields = fields;
|
$scope.fields = fields;
|
||||||
$scope.reset_row();
|
$scope.reset_row();
|
||||||
$scope.clear_all_alerts();
|
|
||||||
|
|
||||||
var ejs = $scope.ejs = ejsResource(config.elasticsearch);
|
var ejs = $scope.ejs = ejsResource(config.elasticsearch);
|
||||||
};
|
};
|
||||||
@ -41,28 +42,6 @@ angular.module('kibana.controllers', [])
|
|||||||
return { 'min-height': row.collapse ? '5px' : row.height };
|
return { 'min-height': row.collapse ? '5px' : row.height };
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.alert = function(title,text,severity,timeout) {
|
|
||||||
var alert = {
|
|
||||||
title: title,
|
|
||||||
text: text,
|
|
||||||
severity: severity || 'info',
|
|
||||||
};
|
|
||||||
$scope.global_alert.push(alert);
|
|
||||||
if (timeout > 0) {
|
|
||||||
$timeout(function() {
|
|
||||||
$scope.global_alert = _.without($scope.global_alert,alert);
|
|
||||||
}, timeout);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.clear_alert = function(alert) {
|
|
||||||
$scope.global_alert = _.without($scope.global_alert,alert);
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.clear_all_alerts = function() {
|
|
||||||
$scope.global_alert = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.edit_path = function(type) {
|
$scope.edit_path = function(type) {
|
||||||
if(type) {
|
if(type) {
|
||||||
return 'panels/'+type+'/editor.html';
|
return 'panels/'+type+'/editor.html';
|
||||||
|
@ -4,7 +4,36 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.services', [])
|
angular.module('kibana.services', [])
|
||||||
.service('fields', function(dashboard, $rootScope, $http) {
|
.service('alertSrv', function($timeout) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// List of all alert objects
|
||||||
|
this.list = [];
|
||||||
|
|
||||||
|
this.set = function(title,text,severity,timeout) {
|
||||||
|
var _a = {
|
||||||
|
title: title || '',
|
||||||
|
text: text || '',
|
||||||
|
severity: severity || 'info',
|
||||||
|
};
|
||||||
|
self.list.push(_a);
|
||||||
|
if (timeout > 0) {
|
||||||
|
$timeout(function() {
|
||||||
|
self.list = _.without(self.list,_a);
|
||||||
|
}, timeout);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clear = function(alert) {
|
||||||
|
self.list = _.without(self.list,alert);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.clearAll = function() {
|
||||||
|
self.list = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
})
|
||||||
|
.service('fields', function(dashboard, $rootScope, $http, alertSrv) {
|
||||||
// Save a reference to this
|
// Save a reference to this
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
@ -46,6 +75,14 @@ angular.module('kibana.services', [])
|
|||||||
var request = $http({
|
var request = $http({
|
||||||
url: config.elasticsearch + "/" + indices.join(',') + "/_mapping",
|
url: config.elasticsearch + "/" + indices.join(',') + "/_mapping",
|
||||||
method: "GET"
|
method: "GET"
|
||||||
|
}).error(function(data, status, headers, conf) {
|
||||||
|
if(status === 0) {
|
||||||
|
alertSrv.set('Error',"Could not contact Elasticsearch at "+config.elasticsearch+
|
||||||
|
". Please ensure that Elasticsearch is reachable from your system." ,'error');
|
||||||
|
} else {
|
||||||
|
alertSrv.set('Error',"Could not find "+config.elasticsearch+"/"+indices.join(',')+"/_mapping. If you"+
|
||||||
|
" are using a proxy, ensure it is configured correctly",'error');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return request.then(function(p) {
|
return request.then(function(p) {
|
||||||
@ -83,7 +120,7 @@ angular.module('kibana.services', [])
|
|||||||
};
|
};
|
||||||
|
|
||||||
})
|
})
|
||||||
.service('kbnIndex',function($http) {
|
.service('kbnIndex',function($http,alertSrv) {
|
||||||
|
|
||||||
// returns a promise containing an array of all indices matching the index
|
// returns a promise containing an array of all indices matching the index
|
||||||
// pattern that exist in a given range
|
// pattern that exist in a given range
|
||||||
@ -106,8 +143,14 @@ angular.module('kibana.services', [])
|
|||||||
var something = $http({
|
var something = $http({
|
||||||
url: config.elasticsearch + "/_aliases",
|
url: config.elasticsearch + "/_aliases",
|
||||||
method: "GET"
|
method: "GET"
|
||||||
}).error(function(data, status, headers, config) {
|
}).error(function(data, status, headers, conf) {
|
||||||
// Handle error condition somehow?
|
if(status === 0) {
|
||||||
|
alertSrv.set('Error',"Could not contact Elasticsearch at "+config.elasticsearch+
|
||||||
|
". Please ensure that Elasticsearch is reachable from your system." ,'error');
|
||||||
|
} else {
|
||||||
|
alertSrv.set('Error',"Could not reach "+config.elasticsearch+"/_aliases. If you"+
|
||||||
|
" are using a proxy, ensure it is configured correctly",'error');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return something.then(function(p) {
|
return something.then(function(p) {
|
||||||
@ -502,13 +545,14 @@ angular.module('kibana.services', [])
|
|||||||
self.init();
|
self.init();
|
||||||
|
|
||||||
})
|
})
|
||||||
.service('dashboard', function($routeParams, $http, $rootScope, $injector, ejsResource, timer, kbnIndex) {
|
.service('dashboard', function($routeParams, $http, $rootScope, $injector, ejsResource, timer, kbnIndex, alertSrv) {
|
||||||
// A hash of defaults to use when loading a dashboard
|
// A hash of defaults to use when loading a dashboard
|
||||||
|
|
||||||
var _dash = {
|
var _dash = {
|
||||||
title: "",
|
title: "",
|
||||||
style: "dark",
|
style: "dark",
|
||||||
editable: true,
|
editable: true,
|
||||||
|
failover: false,
|
||||||
rows: [],
|
rows: [],
|
||||||
services: {},
|
services: {},
|
||||||
index: {
|
index: {
|
||||||
@ -584,7 +628,17 @@ angular.module('kibana.services', [])
|
|||||||
if(p.length > 0) {
|
if(p.length > 0) {
|
||||||
self.indices = p;
|
self.indices = p;
|
||||||
} else {
|
} else {
|
||||||
|
//TODO: Option to not failover
|
||||||
|
if(self.current.failover) {
|
||||||
self.indices = [self.current.index.default];
|
self.indices = [self.current.index.default];
|
||||||
|
} else {
|
||||||
|
alertSrv.set('No indices matched','The pattern <i>'+self.current.index.pattern+
|
||||||
|
'</i> did not match any indices in your selected'+
|
||||||
|
' time range.','info',5000);
|
||||||
|
// Do not issue refresh if no indices match. This should be removed when panels
|
||||||
|
// properly understand when no indices are present
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$rootScope.$broadcast('refresh');
|
$rootScope.$broadcast('refresh');
|
||||||
});
|
});
|
||||||
@ -690,22 +744,25 @@ angular.module('kibana.services', [])
|
|||||||
self.dash_load(_dashboard);
|
self.dash_load(_dashboard);
|
||||||
return true;
|
return true;
|
||||||
},function(result) {
|
},function(result) {
|
||||||
|
alertSrv.set('Error',"Could not load <i>dashboards/"+file+"</i>. Please make sure it exists" ,'error');
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.elasticsearch_load = function(type,id) {
|
this.elasticsearch_load = function(type,id) {
|
||||||
var request = ejs.Request().indices(config.kibana_index).types(type);
|
var request = ejs.Request().indices(config.kibana_index).types(type);
|
||||||
var results = request.query(
|
return request.query(
|
||||||
ejs.IdsQuery(id)
|
ejs.IdsQuery(id)
|
||||||
).doSearch();
|
).doSearch(function(results) {
|
||||||
return results.then(function(results) {
|
|
||||||
if(_.isUndefined(results)) {
|
if(_.isUndefined(results)) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
self.dash_load(angular.fromJson(results.hits.hits[0]['_source']['dashboard']));
|
self.dash_load(angular.fromJson(results.hits.hits[0]['_source']['dashboard']));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
function(data,status) {
|
||||||
|
alertSrv.set('Error','Could not load '+config.elasticsearch+"/"+config.kibana_index+"/"+type+"/"+id,'error');
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('kibana.dashcontrol', [])
|
angular.module('kibana.dashcontrol', [])
|
||||||
.controller('dashcontrol', function($scope, $http, timer, dashboard) {
|
.controller('dashcontrol', function($scope, $http, timer, dashboard, alertSrv) {
|
||||||
|
|
||||||
$scope.panelMeta = {
|
$scope.panelMeta = {
|
||||||
status : "Stable",
|
status : "Stable",
|
||||||
@ -69,17 +69,17 @@ angular.module('kibana.dashcontrol', [])
|
|||||||
|
|
||||||
$scope.set_default = function() {
|
$scope.set_default = function() {
|
||||||
if(dashboard.set_default()) {
|
if(dashboard.set_default()) {
|
||||||
$scope.alert('Local Default Set',dashboard.current.title+' has been set as your local default','success',5000);
|
alertSrv.set('Local Default Set',dashboard.current.title+' has been set as your local default','success',5000);
|
||||||
} else {
|
} else {
|
||||||
$scope.alert('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
|
alertSrv.set('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.purge_default = function() {
|
$scope.purge_default = function() {
|
||||||
if(dashboard.purge_default()) {
|
if(dashboard.purge_default()) {
|
||||||
$scope.alert('Local Default Clear','Your local default dashboard has been cleared','success',5000);
|
alertSrv.set('Local Default Clear','Your local default dashboard has been cleared','success',5000);
|
||||||
} else {
|
} else {
|
||||||
$scope.alert('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
|
alertSrv.set('Incompatible Browser','Sorry, your browser is too old for this feature','error',5000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -91,13 +91,13 @@ angular.module('kibana.dashcontrol', [])
|
|||||||
).then(
|
).then(
|
||||||
function(result) {
|
function(result) {
|
||||||
if(!_.isUndefined(result._id)) {
|
if(!_.isUndefined(result._id)) {
|
||||||
$scope.alert('Dashboard Saved','This dashboard has been saved to Elasticsearch as "' +
|
alertSrv.set('Dashboard Saved','This dashboard has been saved to Elasticsearch as "' +
|
||||||
result._id + '"','success',5000);
|
result._id + '"','success',5000);
|
||||||
if(type === 'temp') {
|
if(type === 'temp') {
|
||||||
$scope.share = dashboard.share_link(dashboard.current.title,'temp',result._id);
|
$scope.share = dashboard.share_link(dashboard.current.title,'temp',result._id);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$scope.alert('Save failed','Dashboard could not be saved to Elasticsearch','error',5000);
|
alertSrv.set('Save failed','Dashboard could not be saved to Elasticsearch','error',5000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -107,15 +107,15 @@ angular.module('kibana.dashcontrol', [])
|
|||||||
function(result) {
|
function(result) {
|
||||||
if(!_.isUndefined(result)) {
|
if(!_.isUndefined(result)) {
|
||||||
if(result.found) {
|
if(result.found) {
|
||||||
$scope.alert('Dashboard Deleted',id+' has been deleted','success',5000);
|
alertSrv.set('Dashboard Deleted',id+' has been deleted','success',5000);
|
||||||
// Find the deleted dashboard in the cached list and remove it
|
// Find the deleted dashboard in the cached list and remove it
|
||||||
var toDelete = _.where($scope.elasticsearch.dashboards,{_id:id})[0];
|
var toDelete = _.where($scope.elasticsearch.dashboards,{_id:id})[0];
|
||||||
$scope.elasticsearch.dashboards = _.without($scope.elasticsearch.dashboards,toDelete);
|
$scope.elasticsearch.dashboards = _.without($scope.elasticsearch.dashboards,toDelete);
|
||||||
} else {
|
} else {
|
||||||
$scope.alert('Dashboard Not Found','Could not find '+id+' in Elasticsearch','warning',5000);
|
alertSrv.set('Dashboard Not Found','Could not find '+id+' in Elasticsearch','warning',5000);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$scope.alert('Dashboard Not Deleted','An error occurred deleting the dashboard','error',5000);
|
alertSrv.set('Dashboard Not Deleted','An error occurred deleting the dashboard','error',5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -137,10 +137,10 @@ angular.module('kibana.dashcontrol', [])
|
|||||||
function(link) {
|
function(link) {
|
||||||
if(!_.isUndefined(link)) {
|
if(!_.isUndefined(link)) {
|
||||||
$scope.gist.last = link;
|
$scope.gist.last = link;
|
||||||
$scope.alert('Gist saved','You will be able to access your exported dashboard file at '+
|
alertSrv.set('Gist saved','You will be able to access your exported dashboard file at '+
|
||||||
'<a href="'+link+'">'+link+'</a> in a moment','success');
|
'<a href="'+link+'">'+link+'</a> in a moment','success');
|
||||||
} else {
|
} else {
|
||||||
$scope.alert('Save failed','Gist could not be saved','error',5000);
|
alertSrv.set('Save failed','Gist could not be saved','error',5000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -151,12 +151,12 @@ angular.module('kibana.dashcontrol', [])
|
|||||||
if(files && files.length > 0) {
|
if(files && files.length > 0) {
|
||||||
$scope.gist.files = files;
|
$scope.gist.files = files;
|
||||||
} else {
|
} else {
|
||||||
$scope.alert('Gist Failed','Could not retrieve dashboard list from gist','error',5000);
|
alertSrv.set('Gist Failed','Could not retrieve dashboard list from gist','error',5000);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.directive('dashUpload', function(timer, dashboard){
|
.directive('dashUpload', function(timer, dashboard, alertSrv){
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
link: function(scope, elem, attrs) {
|
link: function(scope, elem, attrs) {
|
||||||
@ -183,7 +183,7 @@ angular.module('kibana.dashcontrol', [])
|
|||||||
// Something
|
// Something
|
||||||
document.getElementById('dashupload').addEventListener('change', file_selected, false);
|
document.getElementById('dashupload').addEventListener('change', file_selected, false);
|
||||||
} else {
|
} else {
|
||||||
alert('Sorry, the HTML5 File APIs are not fully supported in this browser.');
|
alertSrv.set('Oops','Sorry, the HTML5 File APIs are not fully supported in this browser.','error');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -40,14 +40,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-fluid">
|
<div class="row-fluid">
|
||||||
<div class="span3">
|
<div class="span2">
|
||||||
<h6>Timestamping</h6><select class="input-small" ng-model="dashboard.current.index.interval" ng-options='f for f in ["none","hour","day","week","month","year"]'></select>
|
<h6>Timestamping</h6><select class="input-small" ng-model="dashboard.current.index.interval" ng-options='f for f in ["none","hour","day","week","month","year"]'></select>
|
||||||
</div>
|
</div>
|
||||||
<div class="span5" ng-show="dashboard.current.index.interval != 'none'">
|
<div class="span4" ng-show="dashboard.current.index.interval != 'none'">
|
||||||
<h6>Index pattern <small>Absolutes in []</small></h6>
|
<h6>Index pattern <small>Absolutes in []</small></h6>
|
||||||
<input type="text" class="input-medium" ng-model="dashboard.current.index.pattern">
|
<input type="text" class="input-medium" ng-model="dashboard.current.index.pattern">
|
||||||
</div>
|
</div>
|
||||||
<div class="span4">
|
<div class="span2" ng-show="dashboard.current.index.interval != 'none'">
|
||||||
|
<h6>Failover <i class="icon-question-sign" bs-tooltip="'If no indices match the pattern, failover to default index *NOT RECOMMENDED*'"></i></h6>
|
||||||
|
<input type="checkbox" ng-model="dashboard.current.failover" ng-checked="dashboard.current.failover" />
|
||||||
|
</div>
|
||||||
|
<div class="span4" ng-show="dashboard.current.failover || dashboard.current.index.interval == 'none'">
|
||||||
<h6>Default Index <small ng-show="dashboard.current.index.interval != 'none'">If index not found</small></h6>
|
<h6>Default Index <small ng-show="dashboard.current.index.interval != 'none'">If index not found</small></h6>
|
||||||
<input type="text" class="input-medium" ng-model="dashboard.current.index.default">
|
<input type="text" class="input-medium" ng-model="dashboard.current.index.default">
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user