Commit 63a283b4 by Torkel Ödegaard

feat(alerting): working on alert state filters for alert list

parent da59d654
...@@ -13,12 +13,13 @@ const ( ...@@ -13,12 +13,13 @@ const (
AlertStatePending AlertStateType = "pending" AlertStatePending AlertStateType = "pending"
AlertStateExeuctionError AlertStateType = "exeuction_error" AlertStateExeuctionError AlertStateType = "exeuction_error"
AlertStatePaused AlertStateType = "paused" AlertStatePaused AlertStateType = "paused"
AlertStateFiring AlertStateType = "firing" AlertStateCritical AlertStateType = "critical"
AlertStateWarning AlertStateType = "warning"
AlertStateOK AlertStateType = "ok" AlertStateOK AlertStateType = "ok"
) )
func (s AlertStateType) IsValid() bool { func (s AlertStateType) IsValid() bool {
return s == AlertStatePending || s == AlertStateFiring || s == AlertStateOK return s == AlertStateOK || s == AlertStatePending || s == AlertStateExeuctionError || s == AlertStatePaused || s == AlertStateCritical || s == AlertStateWarning
} }
const ( const (
......
...@@ -35,7 +35,7 @@ func (handler *DefaultResultHandler) Handle(ctx *EvalContext) { ...@@ -35,7 +35,7 @@ func (handler *DefaultResultHandler) Handle(ctx *EvalContext) {
ctx.Rule.State = m.AlertStateExeuctionError ctx.Rule.State = m.AlertStateExeuctionError
exeuctionError = ctx.Error.Error() exeuctionError = ctx.Error.Error()
} else if ctx.Firing { } else if ctx.Firing {
ctx.Rule.State = m.AlertStateFiring ctx.Rule.State = m.AlertStateType(ctx.Rule.Severity)
} else { } else {
ctx.Rule.State = m.AlertStateOK ctx.Rule.State = m.AlertStateOK
} }
......
...@@ -3,7 +3,6 @@ package sqlstore ...@@ -3,7 +3,6 @@ package sqlstore
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"strings"
"time" "time"
"github.com/go-xorm/xorm" "github.com/go-xorm/xorm"
...@@ -76,18 +75,19 @@ func HandleAlertsQuery(query *m.GetAlertsQuery) error { ...@@ -76,18 +75,19 @@ func HandleAlertsQuery(query *m.GetAlertsQuery) error {
params = append(params, query.PanelId) params = append(params, query.PanelId)
} }
if len(query.State) > 0 { if len(query.State) > 0 && query.State[0] != "ALL" {
sql.WriteString(` AND (`) sql.WriteString(` AND (`)
for i, v := range query.State { for i, v := range query.State {
if i > 0 { if i > 0 {
sql.WriteString(" OR ") sql.WriteString(" OR ")
} }
sql.WriteString("state = ? ") sql.WriteString("state = ? ")
params = append(params, strings.ToUpper(v)) params = append(params, v)
} }
sql.WriteString(")") sql.WriteString(")")
} }
sqlog.Error(sql.String(), "params", params)
alerts := make([]*m.Alert, 0) alerts := make([]*m.Alert, 0)
if err := x.Sql(sql.String(), params...).Find(&alerts); err != nil { if err := x.Sql(sql.String(), params...).Find(&alerts); err != nil {
return err return err
......
...@@ -46,28 +46,44 @@ var severityLevels = { ...@@ -46,28 +46,44 @@ var severityLevels = {
'warning': {text: 'WARNING', iconClass: 'icon-gf icon-gf-warning', stateClass: 'alert-state-warning'}, 'warning': {text: 'WARNING', iconClass: 'icon-gf icon-gf-warning', stateClass: 'alert-state-warning'},
}; };
function getStateDisplayModel(state, severity) { function getStateDisplayModel(state) {
var model = { switch (state) {
case 'ok': {
return {
text: 'OK', text: 'OK',
iconClass: 'icon-gf icon-gf-online', iconClass: 'icon-gf icon-gf-online',
stateClass: 'alert-state-ok' stateClass: 'alert-state-ok'
}; };
if (state === 'firing') {
model.text = severityLevels[severity].text;
model.iconClass = severityLevels[severity].iconClass;
model.stateClass = severityLevels[severity].stateClass;
} else if (state === 'pending') {
model.text = "PENDING";
model.iconClass = "fa fa-question";
model.stateClass = "alert-state-pending";
} else if (state === 'paused') {
model.text = "PAUSED";
model.iconClass = "fa fa-pause";
model.stateClass = "alert-state-paused";
} }
case 'critical': {
return model; return {
text: 'CRITICAL',
iconClass: 'icon-gf icon-gf-critical',
stateClass: 'alert-state-critical'
};
}
case 'warning': {
return {
text: 'WARNING',
iconClass: 'icon-gf icon-gf-warning',
stateClass: 'alert-state-warning'
};
}
case 'pending': {
return {
text: 'PENDING',
iconClass: "fa fa-question",
stateClass: 'alert-state-warning'
};
}
case 'paused': {
return {
text: 'paused',
iconClass: "fa fa-pause",
stateClass: 'alert-state-paused'
};
}
}
} }
export default { export default {
......
...@@ -9,35 +9,34 @@ import alertDef from './alert_def'; ...@@ -9,35 +9,34 @@ import alertDef from './alert_def';
export class AlertListCtrl { export class AlertListCtrl {
alerts: any; alerts: any;
stateFilters = [
{text: 'All', value: null},
{text: 'OK', value: 'ok'},
{text: 'Pending', value: 'pending'},
{text: 'Warning', value: 'warning'},
{text: 'Critical', value: 'critical'},
{text: 'Execution Error', value: 'execution_error'},
];
filters = { filters = {
state: 'OK' state: 'ALL'
}; };
/** @ngInject */ /** @ngInject */
constructor(private backendSrv, private $route) { constructor(private backendSrv, private $location) {
_.each($route.current.params.state, state => { var params = $location.search();
this.filters[state.toLowerCase()] = true; this.filters.state = params.state || null;
});
this.loadAlerts(); this.loadAlerts();
} }
updateFilter() { filtersChanged() {
var stats = []; this.$location.search(this.filters);
this.$route.current.params.state = stats;
this.$route.updateParams();
} }
loadAlerts() { loadAlerts() {
var stats = []; this.backendSrv.get('/api/alerts', this.filters).then(result => {
var params = {
state: stats
};
this.backendSrv.get('/api/alerts', params).then(result => {
this.alerts = _.map(result, alert => { this.alerts = _.map(result, alert => {
alert.stateModel = alertDef.getStateDisplayModel(alert.state, alert.severity); alert.stateModel = alertDef.getStateDisplayModel(alert.state);
alert.newStateDateAgo = moment(alert.newStateDate).fromNow().replace(" ago", ""); alert.newStateDateAgo = moment(alert.newStateDate).fromNow().replace(" ago", "");
return alert; return alert;
}); });
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label">Filter by state</label> <label class="gf-form-label">Filter by state</label>
<div class="gf-form-select-wrapper width-13"> <div class="gf-form-select-wrapper width-13">
<select class="gf-form-input" ng-model="ctrl.filters.state" ng-options="f for f in ['OK', 'Warning', 'Critical']" ng-change="ctrl.severityChanged()"> <select class="gf-form-input" ng-model="ctrl.filters.state" ng-options="f.value as f.text for f in ctrl.stateFilters" ng-change="ctrl.filtersChanged()">
</select> </select>
</div> </div>
</div> </div>
......
...@@ -201,35 +201,36 @@ export class ThresholdManager { ...@@ -201,35 +201,36 @@ export class ThresholdManager {
} }
} }
var fillColor, lineColor;
switch (threshold.colorMode) { switch (threshold.colorMode) {
case 'critical': { case 'critical': {
threshold.fillColor = 'rgba(234, 112, 112, 0.12)'; fillColor = 'rgba(234, 112, 112, 0.12)';
threshold.lineColor = 'rgba(237, 46, 24, 0.60)'; lineColor = 'rgba(237, 46, 24, 0.60)';
break; break;
} }
case 'warning': { case 'warning': {
threshold.fillColor = 'rgba(235, 138, 14, 0.12)'; fillColor = 'rgba(235, 138, 14, 0.12)';
threshold.lineColor = 'rgba(247, 149, 32, 0.60)'; lineColor = 'rgba(247, 149, 32, 0.60)';
break; break;
} }
case 'ok': { case 'ok': {
threshold.fillColor = 'rgba(11, 237, 50, 0.090)'; fillColor = 'rgba(11, 237, 50, 0.090)';
threshold.lineColor = 'rgba(6,163,69, 0.60)'; lineColor = 'rgba(6,163,69, 0.60)';
break; break;
} }
case 'custom': { case 'custom': {
threshold.fillColor = threshold.fillColor; fillColor = threshold.fillColor;
threshold.lineColor = threshold.lineColor; lineColor = threshold.lineColor;
break; break;
} }
} }
// fill // fill
if (threshold.fill) { if (threshold.fill) {
options.grid.markings.push({yaxis: {from: threshold.value, to: limit}, color: threshold.fillColor}); options.grid.markings.push({yaxis: {from: threshold.value, to: limit}, color: fillColor});
} }
if (threshold.line) { if (threshold.line) {
options.grid.markings.push({yaxis: {from: threshold.value, to: threshold.value}, color: threshold.lineColor}); options.grid.markings.push({yaxis: {from: threshold.value, to: threshold.value}, color: lineColor});
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment