feat(alerting): separate operator and level

This commit is contained in:
bergquist 2016-05-03 17:31:04 +02:00
parent 27c34745a6
commit 1624dc9dfd
11 changed files with 143 additions and 122 deletions

View File

@ -6,8 +6,10 @@ type AlertRuleDTO struct {
PanelId int64 `json:"panelId"`
Query string `json:"query"`
QueryRefId string `json:"queryRefId"`
WarnLevel string `json:"warnLevel"`
CritLevel string `json:"critLevel"`
WarnLevel int64 `json:"warnLevel"`
CritLevel int64 `json:"critLevel"`
WarnOperator string `json:"warnOperator"`
CritOperator string `json:"critOperator"`
Interval string `json:"interval"`
Title string `json:"title"`
Description string `json:"description"`

View File

@ -12,8 +12,10 @@ type AlertRule struct {
PanelId int64 `json:"panelId"`
Query string `json:"query"`
QueryRefId string `json:"queryRefId"`
WarnLevel string `json:"warnLevel"`
CritLevel string `json:"critLevel"`
WarnLevel int64 `json:"warnLevel"`
CritLevel int64 `json:"critLevel"`
WarnOperator string `json:"warnOperator"`
CritOperator string `json:"critOperator"`
Interval string `json:"interval"`
Title string `json:"title"`
Description string `json:"description"`
@ -45,8 +47,10 @@ func (cmd *SaveDashboardCommand) GetAlertModels() *[]AlertRule {
PanelId: panel.Get("id").MustInt64(),
Id: alerting.Get("id").MustInt64(),
QueryRefId: alerting.Get("queryRef").MustString(),
WarnLevel: alerting.Get("warnLevel").MustString(),
CritLevel: alerting.Get("critLevel").MustString(),
WarnLevel: alerting.Get("warnLevel").MustInt64(),
CritLevel: alerting.Get("critLevel").MustInt64(),
WarnOperator: alerting.Get("warnOperator").MustString(),
CritOperator: alerting.Get("critOperator").MustString(),
Interval: alerting.Get("interval").MustString(),
Title: alerting.Get("title").MustString(),
Description: alerting.Get("description").MustString(),

View File

@ -101,8 +101,10 @@ func TestAlertModel(t *testing.T) {
"seriesOverrides": [],
"alerting": {
"queryRef": "A",
"warnLevel": "> 30",
"critLevel": "> 50",
"warnLevel": 30,
"critLevel": 50,
"warnOperator": ">",
"critOperator": ">",
"aggregator": "sum",
"queryRange": "10m",
"interval": "10s",
@ -186,8 +188,10 @@ func TestAlertModel(t *testing.T) {
"seriesOverrides": [],
"alerting": {
"queryRef": "A",
"warnLevel": "> 300",
"critLevel": "> 500",
"warnOperator": ">",
"critOperator": ">",
"warnLevel": 300,
"critLevel": 500,
"aggregator": "avg",
"queryRange": "10m",
"interval": "10s",
@ -363,11 +367,16 @@ func TestAlertModel(t *testing.T) {
So(v.Description, ShouldNotBeEmpty)
}
So(alerts[0].WarnLevel, ShouldEqual, "> 30")
So(alerts[1].WarnLevel, ShouldEqual, "> 300")
So(alerts[0].WarnLevel, ShouldEqual, 30)
So(alerts[1].WarnLevel, ShouldEqual, 300)
So(alerts[0].CritLevel, ShouldEqual, "> 50")
So(alerts[1].CritLevel, ShouldEqual, "> 500")
So(alerts[0].CritLevel, ShouldEqual, 50)
So(alerts[1].CritLevel, ShouldEqual, 500)
So(alerts[0].CritOperator, ShouldEqual, ">")
So(alerts[1].CritOperator, ShouldEqual, ">")
So(alerts[0].WarnOperator, ShouldEqual, ">")
So(alerts[1].WarnOperator, ShouldEqual, ">")
So(alerts[0].Query, ShouldEqual, `{"refId":"A","target":"aliasByNode(statsd.fakesite.counters.session_start.desktop.count, 4)"}`)
So(alerts[1].Query, ShouldEqual, `{"refId":"A","target":"aliasByNode(statsd.fakesite.counters.session_start.mobile.count, 4)"}`)

View File

@ -75,6 +75,8 @@ func alertIsDifferent(rule1, rule2 m.AlertRule) bool {
result = result || rule1.Aggregator != rule2.Aggregator
result = result || rule1.CritLevel != rule2.CritLevel
result = result || rule1.WarnLevel != rule2.WarnLevel
result = result || rule1.WarnOperator != rule2.WarnOperator
result = result || rule1.CritOperator != rule2.CritOperator
result = result || rule1.Query != rule2.Query
result = result || rule1.QueryRefId != rule2.QueryRefId
result = result || rule1.Interval != rule2.Interval

View File

@ -26,8 +26,10 @@ func TestAlertRuleChangesDataAccess(t *testing.T) {
DashboardId: testDash.Id,
Query: "Query",
QueryRefId: "A",
WarnLevel: "> 30",
CritLevel: "> 50",
WarnLevel: 30,
CritLevel: 50,
WarnOperator: ">",
CritOperator: ">",
Interval: "10",
Title: "Alerting title",
Description: "Alerting description",

View File

@ -21,8 +21,10 @@ func TestAlertingDataAccess(t *testing.T) {
OrgId: testDash.OrgId,
Query: "Query",
QueryRefId: "A",
WarnLevel: "> 30",
CritLevel: "> 50",
WarnLevel: 30,
CritLevel: 50,
WarnOperator: ">",
CritOperator: ">",
Interval: "10",
Title: "Alerting title",
Description: "Alerting description",
@ -59,8 +61,10 @@ func TestAlertingDataAccess(t *testing.T) {
So(err2, ShouldBeNil)
So(query.Result.Interval, ShouldEqual, "10")
So(query.Result.WarnLevel, ShouldEqual, "> 30")
So(query.Result.CritLevel, ShouldEqual, "> 50")
So(query.Result.WarnLevel, ShouldEqual, 30)
So(query.Result.CritLevel, ShouldEqual, 50)
So(query.Result.WarnOperator, ShouldEqual, ">")
So(query.Result.CritOperator, ShouldEqual, ">")
So(query.Result.Query, ShouldEqual, "Query")
So(query.Result.QueryRefId, ShouldEqual, "A")
So(query.Result.Title, ShouldEqual, "Alerting title")
@ -181,8 +185,10 @@ func TestAlertingDataAccess(t *testing.T) {
DashboardId: testDash.Id,
Query: "Query",
QueryRefId: "A",
WarnLevel: "> 30",
CritLevel: "> 50",
WarnLevel: 30,
CritLevel: 50,
WarnOperator: ">",
CritOperator: ">",
Interval: "10",
Title: "Alerting title",
Description: "Alerting description",

View File

@ -20,8 +20,10 @@ func TestAlertingStateAccess(t *testing.T) {
OrgId: testDash.OrgId,
Query: "Query",
QueryRefId: "A",
WarnLevel: "> 30",
CritLevel: "> 50",
WarnLevel: 30,
CritLevel: 50,
WarnOperator: ">",
CritOperator: ">",
Interval: "10",
Title: "Alerting title",
Description: "Alerting description",

View File

@ -12,8 +12,10 @@ func addAlertMigrations(mg *Migrator) {
{Name: "org_id", Type: DB_BigInt, Nullable: false},
{Name: "query", Type: DB_Text, Nullable: false},
{Name: "query_ref_id", Type: DB_NVarchar, Length: 255, Nullable: false},
{Name: "warn_level", Type: DB_NVarchar, Length: 255, Nullable: false},
{Name: "crit_level", Type: DB_NVarchar, Length: 255, Nullable: false},
{Name: "warn_level", Type: DB_BigInt, Nullable: false},
{Name: "warn_operator", Type: DB_NVarchar, Length: 10, Nullable: false},
{Name: "crit_level", Type: DB_BigInt, Nullable: false},
{Name: "crit_operator", Type: DB_NVarchar, Length: 10, Nullable: false},
{Name: "interval", Type: DB_NVarchar, Length: 255, Nullable: false},
{Name: "title", Type: DB_NVarchar, Length: 255, Nullable: false},
{Name: "description", Type: DB_NVarchar, Length: 255, Nullable: false},

View File

@ -24,36 +24,25 @@ export class AlertTabCtrl {
convertThresholdsToAlertThresholds() {
if (this.panel.grid && this.panel.grid.threshold1) {
this.panel.alerting.warnLevel = '< ' + this.panel.grid.threshold1;
this.panel.alerting.warnOperator = '<';
this.panel.alerting.warnLevel = this.panel.grid.threshold1;
}
if (this.panel.grid && this.panel.grid.threshold2) {
this.panel.alerting.critLevel = '< ' + this.panel.grid.threshold2;
this.panel.alerting.critOperator = '<';
this.panel.alerting.critLevel = this.panel.grid.threshold2;
}
}
thresholdsUpdated() {
if (this.panel.alerting.warnLevel) {
var threshold = this.panel.alerting.warnLevel
.replace(' ', '')
.replace('>', '')
.replace('<', '')
.replace('>=', '')
.replace('<=', '');
this.panel.grid.threshold1 = parseInt(threshold);
this.panel.grid.threshold1 = parseInt(this.panel.alerting.warnLevel);
}
if (this.panel.alerting.critLevel) {
var threshold = this.panel.alerting.critLevel
.replace(' ', '')
.replace('>', '')
.replace('<', '')
.replace('>=', '')
.replace('<=', '');
this.panel.grid.threshold2 = parseInt(threshold);
this.panel.grid.threshold2 = parseInt(this.panel.alerting.critLevel);
}
this.panelCtrl.render();
}
}

View File

@ -16,14 +16,20 @@
<i class="icon-gf icon-gf-warn alert-state-warn"></i>
Warn level
</span>
<input class="gf-form-input max-width-7" type="text" ng-model="ctrl.panel.alerting.warnLevel" ng-change="alertTab.thresholdsUpdated()"></input>
<div class="gf-form-select-wrapper max-width-10">
<select class="gf-form-input" ng-model="ctrl.panel.alerting.warnOperator" ng-options="oper as oper for oper in ['>', '<', '<=', '>=']"></select>
</div>
<input class="gf-form-input max-width-7" type="number" ng-model="ctrl.panel.alerting.warnLevel" ng-change="alertTab.thresholdsUpdated()"></input>
</div>
<div class="gf-form">
<span class="gf-form-label width-9">
<i class="icon-gf icon-gf-critical alert-state-critical"></i>
Critical level
</span>
<input class="gf-form-input max-width-7" type="text" ng-model="ctrl.panel.alerting.critLevel" ng-change="alertTab.thresholdsUpdated()"></input>
<div class="gf-form-select-wrapper max-width-10">
<select class="gf-form-input" ng-model="ctrl.panel.alerting.critOperator" ng-options="oper as oper for oper in ['>', '<', '<=', '>=']"></select>
</div>
<input class="gf-form-input max-width-7" type="number" ng-model="ctrl.panel.alerting.critLevel" ng-change="alertTab.thresholdsUpdated()"></input>
</div>
</div>

View File

@ -8,17 +8,14 @@
.alert-state-online {
//background-image: url('/img/online.svg');
color: $online;
}
.alert-state-warn {
//background-image: url('/img/warn-tiny.svg');
color: $warn;
}
.alert-state-critical {
//background-image: url('/img/critical.svg');
color: $critical;
}