Support for (non)deterministic alarms
Adding possibility of marking alarm as deterministic or non-deterministic. Expression widget was extended with checkbox. If checkbox's state is changed, underlying expression is modified to reflect the change. By default checkbox is not checked - all expressions are non-deterministic by default. Deterministic property of alarm's expression is displayed in alarm definition details. Value is computed at server side. Depends-On: I506fcd0b9861e902a2bfcfa768d402c568b85cea Change-Id: I480afe3259b6063e99a96798f14e646f830fcbd8
This commit is contained in:
@@ -18,6 +18,10 @@
|
||||
<p>{% blocktrans %}
|
||||
The Notifications field contains the list of Notifications that should be sent when transitioning to another ALARM state.
|
||||
{% endblocktrans %}</p>
|
||||
<p>{% blocktrans %}
|
||||
The deterministic alarms never enter UNDETERMINED state.
|
||||
Use them for metrics that are received sporadically.
|
||||
{% endblocktrans %}</p>
|
||||
<fieldset>
|
||||
<div ng-controller="alarmEditController" ng-init="init('{{ service }}')">
|
||||
{% include "horizon/common/_form_fields.html" %}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
<dd>{{ alarm.description }}</dd>
|
||||
<dt>{% trans "Expression" %}</dt>
|
||||
<dd>{{ alarm.expression }}</dd>
|
||||
<dt>{% trans "Deterministic" %}</dt>
|
||||
<dd>{{ alarm.deterministic }}</dd>
|
||||
<dt>{% trans "Severity" %}</dt>
|
||||
<dd>{{ alarm.severity }}</dd>
|
||||
<dt>{% trans "Notifications Enabled" %}</dt>
|
||||
|
||||
@@ -1,17 +1,43 @@
|
||||
{% load i18n %}
|
||||
<div>
|
||||
<input type="hidden" name="{{ name }}" id="dimension"/>
|
||||
<div class="alarm-expression">
|
||||
<input type="hidden" name="{{ name }}" id="expression"/>
|
||||
<div style="margin-bottom:5px;">
|
||||
<select id="function" class="form-control"
|
||||
ng-model="currentFunction" ng-options="f[0] as f[1] for f in {{func}}" ng-change="saveExpression()"></select>
|
||||
<select id="metric-chooser" class="form-control"
|
||||
<select id="function"
|
||||
class="form-control"
|
||||
ng-model="currentFunction"
|
||||
ng-options="f[0] as f[1] for f in {{func}}"
|
||||
ng-change="saveExpression()"></select>
|
||||
<select id="metric-chooser"
|
||||
class="form-control"
|
||||
ng-model="currentMetric"
|
||||
ng-options="metric for metric in metricNames"
|
||||
ng-change="metricChanged()">
|
||||
</select>
|
||||
<select id="comparators" class="form-control"
|
||||
ng-model="currentComparator" ng-options="f[0] as f[1] for f in {{comparators}}" ng-change="saveExpression()"></select>
|
||||
<input type="number" step="any" id="threshold" class="form-control" ng-model="currentThreshold" ng-change="saveExpression()"/>
|
||||
ng-change="metricChanged()"></select>
|
||||
<div class="expression-details">
|
||||
<select class="form-control"
|
||||
ng-model="currentComparator"
|
||||
aria-label="{% trans 'Comparator' %}"
|
||||
ng-options="f[0] as f[1] for f in {{comparators}}"
|
||||
ng-change="saveExpression()"></select>
|
||||
<input type="number"
|
||||
step="any"
|
||||
class="form-control"
|
||||
aria-label="{% trans 'Threshold' %}"
|
||||
ng-model="currentThreshold"
|
||||
ng-change="saveExpression()"/>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox"
|
||||
data-toggle="tooltip"
|
||||
data-placement="left"
|
||||
title="{% trans 'Deterministic' %}"
|
||||
data-original-title="{% trans 'Deterministic' %}"
|
||||
aria-label="{% trans 'Deterministic' %}"
|
||||
ng-model="currentIsDeterministic"
|
||||
ng-change="saveExpression()">
|
||||
<span>{% trans 'Deterministic' %}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<tags-input id="dimension-chooser" ng-model="tags"
|
||||
placeholder="{% trans 'Add a dimension' %}"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
<input type="hidden" name="ok_actions" value="{$ notify.id $}" ng-if="notify.ok"/>
|
||||
</td>
|
||||
<td class="undetermined">
|
||||
<input type="checkbox" ng-model="notify.undetermined">
|
||||
<input type="checkbox" ng-model="notify.undetermined" ng-disabled="ctrl.isDeterministic">
|
||||
<input type="hidden" name="undetermined_actions" value="{$ notify.id $}" ng-if="notify.undetermined"/>
|
||||
</td>
|
||||
<td>
|
||||
|
||||
@@ -6,16 +6,30 @@
|
||||
white-space: normal;
|
||||
word-wrap:break-word;
|
||||
}
|
||||
#comparators {
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
#threshold {
|
||||
width: 100%
|
||||
}
|
||||
#notification_table td.address{
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
max-width:100px;
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-expression .expression-details {
|
||||
display: inline-flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.alarm-expression .expression-details > * {
|
||||
float: left;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.alarm-expression .expression-details .checkbox {
|
||||
margin-left: 10px;
|
||||
font-weight: bold;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.alarm-expression .expression-details .checkbox span {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
@@ -152,6 +152,7 @@ angular.module('monitoring.controllers', [])
|
||||
$scope.currentFunction = "max";
|
||||
$scope.currentComparator = ">";
|
||||
$scope.currentThreshold = 0;
|
||||
$scope.currentIsDeterministic = false;
|
||||
$scope.matchingMetrics= [];
|
||||
$scope.tags = [];
|
||||
$scope.matchByTags = [];
|
||||
@@ -197,7 +198,7 @@ angular.module('monitoring.controllers', [])
|
||||
$scope.saveDimension();
|
||||
}
|
||||
$scope.saveExpression = function() {
|
||||
$('#dimension').val($scope.formatDimension());
|
||||
$('#expression').val($scope.formatDimension());
|
||||
}
|
||||
$scope.saveDimension = function() {
|
||||
$scope.saveExpression();
|
||||
@@ -230,14 +231,22 @@ angular.module('monitoring.controllers', [])
|
||||
$('#id_match_by').val(matchByTags.join(','));
|
||||
}
|
||||
$scope.formatDimension = function() {
|
||||
var dim = ''
|
||||
var dim = '';
|
||||
angular.forEach($scope.tags, function(value, key) {
|
||||
if (dim.length) {
|
||||
dim += ','
|
||||
dim += ',';
|
||||
}
|
||||
dim += value['text']
|
||||
dim += value['text'];
|
||||
})
|
||||
return $scope.currentFunction + '(' + $scope.currentMetric + '{' + dim + '}) ' + $scope.currentComparator + ' ' + $scope.currentThreshold;
|
||||
return $scope.currentFunction
|
||||
+ '('
|
||||
+ $scope.currentMetric
|
||||
+ '{' + dim + '}'
|
||||
+ ($scope.currentIsDeterministic ? ',deterministic' : '')
|
||||
+ ') '
|
||||
+ $scope.currentComparator
|
||||
+ ' '
|
||||
+ $scope.currentThreshold;
|
||||
}
|
||||
$scope.formatMatchBy = function() {
|
||||
var dimNames = {}
|
||||
@@ -256,6 +265,18 @@ angular.module('monitoring.controllers', [])
|
||||
$scope.saveDimension();
|
||||
}
|
||||
|
||||
$scope.$on('$destroy', (function() {
|
||||
var detWatcher = $scope.$watch('currentIsDeterministic', function detWatcher(newValue, oldValue) {
|
||||
if(newValue != oldValue){
|
||||
$scope.$emit('mon_deterministic_changed', newValue);
|
||||
}
|
||||
});
|
||||
return function() {
|
||||
// destroy watchers
|
||||
detWatcher();
|
||||
}
|
||||
}()));
|
||||
|
||||
function uniqueNames(input, key) {
|
||||
var unique = {};
|
||||
var uniqueList = [];
|
||||
@@ -270,10 +291,11 @@ angular.module('monitoring.controllers', [])
|
||||
}])
|
||||
.controller('alarmNotificationFieldController', NotificationField);
|
||||
|
||||
function NotificationField(){
|
||||
function NotificationField($rootScope) {
|
||||
|
||||
var vm = this;
|
||||
var allOptions = {};
|
||||
var oldUndetermined = {};
|
||||
|
||||
vm.empty = true;
|
||||
vm.list = [];
|
||||
@@ -281,6 +303,7 @@ function NotificationField(){
|
||||
model:null,
|
||||
options:[]
|
||||
};
|
||||
vm.isDeterministic = false;
|
||||
|
||||
|
||||
vm.init = function(data){
|
||||
@@ -305,8 +328,13 @@ function NotificationField(){
|
||||
}
|
||||
}
|
||||
vm.select.model = null;
|
||||
if (id in oldUndetermined) {
|
||||
delete oldUndetermined[id];
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.$on('mon_deterministic_changed', onDeterministicChange)
|
||||
|
||||
function prepareNotify(item){
|
||||
var selected = item[7]
|
||||
var notify = {
|
||||
@@ -336,9 +364,33 @@ function NotificationField(){
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onDeterministicChange(event, isDeterministic) {
|
||||
|
||||
if (!(vm.list && vm.list.length)) {
|
||||
return;
|
||||
} else if (isDeterministic === vm.isDeterministic) {
|
||||
return;
|
||||
}
|
||||
|
||||
vm.isDeterministic = isDeterministic;
|
||||
|
||||
angular.forEach(vm.list, function(item) {
|
||||
if(!(item.id in oldUndetermined)){
|
||||
oldUndetermined[item.id] = [];
|
||||
}
|
||||
if (isDeterministic) {
|
||||
oldUndetermined[item.id] = item.undetermined;
|
||||
item.undetermined = !isDeterministic;
|
||||
} else {
|
||||
item.undetermined = oldUndetermined[item.id];
|
||||
delete oldUndetermined[item.id];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
NotificationField.$inject = [];
|
||||
NotificationField.$inject = ['$rootScope'];
|
||||
|
||||
angular.module('monitoring.filters', [])
|
||||
.filter('spacedim', function () {
|
||||
|
||||
Reference in New Issue
Block a user