Merge pull request #368 from influxdata/add-kapa-relative-abs
Add relative comparison with absolutes changepull/372/head
commit
8833397c8a
|
@ -361,7 +361,7 @@ func TestRelative(t *testing.T) {
|
|||
Trigger: "relative",
|
||||
Alerts: []string{"slack", "victorops", "email"},
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Change: "change",
|
||||
Change: "% change",
|
||||
Period: "10m",
|
||||
Shift: "1m",
|
||||
Operator: "greater than",
|
||||
|
@ -516,6 +516,167 @@ trigger
|
|||
}
|
||||
}
|
||||
|
||||
func TestRelativeChange(t *testing.T) {
|
||||
alert := chronograf.AlertRule{
|
||||
Name: "name",
|
||||
Trigger: "relative",
|
||||
Alerts: []string{"slack", "victorops", "email"},
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Change: "change",
|
||||
Period: "10m",
|
||||
Shift: "1m",
|
||||
Operator: "greater than",
|
||||
Value: "90",
|
||||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
Fields: []struct {
|
||||
Field string `json:"field"`
|
||||
Funcs []string `json:"funcs"`
|
||||
}{
|
||||
{
|
||||
Field: "usage_user",
|
||||
Funcs: []string{"mean"},
|
||||
},
|
||||
},
|
||||
Tags: map[string][]string{
|
||||
"host": []string{
|
||||
"acc-0eabc309-eu-west-1-data-3",
|
||||
"prod",
|
||||
},
|
||||
"cpu": []string{
|
||||
"cpu_total",
|
||||
},
|
||||
},
|
||||
GroupBy: struct {
|
||||
Time string `json:"time"`
|
||||
Tags []string `json:"tags"`
|
||||
}{
|
||||
Time: "",
|
||||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
alert chronograf.AlertRule
|
||||
want chronograf.TICKScript
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "Test valid template alert",
|
||||
alert: alert,
|
||||
want: `var db = 'telegraf'
|
||||
|
||||
var rp = 'autogen'
|
||||
|
||||
var measurement = 'cpu'
|
||||
|
||||
var groupby = ['host', 'cluster_id']
|
||||
|
||||
var where_filter = lambda: ("cpu" == 'cpu_total') AND ("host" == 'acc-0eabc309-eu-west-1-data-3' OR "host" == 'prod')
|
||||
|
||||
var period = 10m
|
||||
|
||||
var name = 'name'
|
||||
|
||||
var idVar = name + ':{{.Group}}'
|
||||
|
||||
var message = 'message'
|
||||
|
||||
var idtag = 'alertID'
|
||||
|
||||
var leveltag = 'level'
|
||||
|
||||
var messagefield = 'message'
|
||||
|
||||
var durationfield = 'duration'
|
||||
|
||||
var output_db = 'chronograf'
|
||||
|
||||
var output_rp = 'autogen'
|
||||
|
||||
var output_mt = 'alerts'
|
||||
|
||||
var triggerType = 'relative'
|
||||
|
||||
var every = 30s
|
||||
|
||||
var shift = -1m
|
||||
|
||||
var crit = 90
|
||||
|
||||
var data = stream
|
||||
|from()
|
||||
.database(db)
|
||||
.retentionPolicy(rp)
|
||||
.measurement(measurement)
|
||||
.groupBy(groupby)
|
||||
.where(where_filter)
|
||||
|window()
|
||||
.period(period)
|
||||
.every(every)
|
||||
.align()
|
||||
|mean('usage_user')
|
||||
.as('value')
|
||||
|
||||
var past = data
|
||||
|shift(shift)
|
||||
|
||||
var current = data
|
||||
|
||||
var trigger = past
|
||||
|join(current)
|
||||
.as('past', 'current')
|
||||
|eval(lambda: float("current.value" - "past.value"))
|
||||
.keep()
|
||||
.as('value')
|
||||
|alert()
|
||||
.stateChangesOnly()
|
||||
.crit(lambda: "value" > crit)
|
||||
.message(message)
|
||||
.id(idVar)
|
||||
.idTag(idtag)
|
||||
.levelTag(leveltag)
|
||||
.messageField(messagefield)
|
||||
.durationField(durationfield)
|
||||
.slack()
|
||||
.victorOps()
|
||||
.email()
|
||||
|
||||
trigger
|
||||
|influxDBOut()
|
||||
.create()
|
||||
.database(output_db)
|
||||
.retentionPolicy(output_rp)
|
||||
.measurement(output_mt)
|
||||
.tag('alertName', name)
|
||||
.tag('triggerType', triggerType)
|
||||
`,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
gen := Alert{}
|
||||
got, err := gen.Generate(tt.alert)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("%q. Relative() error = %v, wantErr %v", tt.name, err, tt.wantErr)
|
||||
continue
|
||||
}
|
||||
if got != tt.want {
|
||||
fmt.Printf("%s", got)
|
||||
t.Errorf("%q. Relative() = %v, want %v", tt.name, got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeadman(t *testing.T) {
|
||||
alert := chronograf.AlertRule{
|
||||
Name: "name",
|
||||
|
|
|
@ -17,8 +17,32 @@ var ThresholdTrigger = `
|
|||
.durationField(durationfield)
|
||||
`
|
||||
|
||||
// RelativeTrigger compares one window of data versus another.
|
||||
var RelativeTrigger = `
|
||||
// RelativeAbsoluteTrigger compares one window of data versus another (current - past)
|
||||
var RelativeAbsoluteTrigger = `
|
||||
var past = data
|
||||
|shift(shift)
|
||||
|
||||
var current = data
|
||||
|
||||
var trigger = past
|
||||
|join(current)
|
||||
.as('past', 'current')
|
||||
|eval(lambda: float("current.value" - "past.value"))
|
||||
.keep()
|
||||
.as('value')
|
||||
|alert()
|
||||
.stateChangesOnly()
|
||||
.crit(lambda: "value" %s crit)
|
||||
.message(message)
|
||||
.id(idVar)
|
||||
.idTag(idtag)
|
||||
.levelTag(leveltag)
|
||||
.messageField(messagefield)
|
||||
.durationField(durationfield)
|
||||
`
|
||||
|
||||
// RelativePercentTrigger compares one window of data versus another as a percent change.
|
||||
var RelativePercentTrigger = `
|
||||
var past = data
|
||||
|shift(shift)
|
||||
|
||||
|
@ -63,7 +87,13 @@ func Trigger(rule chronograf.AlertRule) (string, error) {
|
|||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf(RelativeTrigger, op), nil
|
||||
if rule.TriggerValues.Change == "% change" {
|
||||
return fmt.Sprintf(RelativePercentTrigger, op), nil
|
||||
} else if rule.TriggerValues.Change == "change" {
|
||||
return fmt.Sprintf(RelativeAbsoluteTrigger, op), nil
|
||||
} else {
|
||||
return "", fmt.Errorf("Unknown change type %s", rule.TriggerValues.Change)
|
||||
}
|
||||
case "threshold":
|
||||
op, err := kapaOperator(rule.TriggerValues.Operator)
|
||||
if err != nil {
|
||||
|
|
|
@ -36,6 +36,7 @@ func TestTrigger(t *testing.T) {
|
|||
Trigger: "relative",
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Operator: "greater than",
|
||||
Change: "% change",
|
||||
},
|
||||
},
|
||||
want: `var past = data
|
||||
|
@ -58,6 +59,38 @@ var trigger = past
|
|||
.levelTag(leveltag)
|
||||
.messageField(messagefield)
|
||||
.durationField(durationfield)
|
||||
`,
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "Test Relative percent change",
|
||||
rule: chronograf.AlertRule{
|
||||
Trigger: "relative",
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Operator: "greater than",
|
||||
Change: "change",
|
||||
},
|
||||
},
|
||||
want: `var past = data
|
||||
|shift(shift)
|
||||
|
||||
var current = data
|
||||
|
||||
var trigger = past
|
||||
|join(current)
|
||||
.as('past', 'current')
|
||||
|eval(lambda: float("current.value" - "past.value"))
|
||||
.keep()
|
||||
.as('value')
|
||||
|alert()
|
||||
.stateChangesOnly()
|
||||
.crit(lambda: "value" > crit)
|
||||
.message(message)
|
||||
.id(idVar)
|
||||
.idTag(idtag)
|
||||
.levelTag(leveltag)
|
||||
.messageField(messagefield)
|
||||
.durationField(durationfield)
|
||||
`,
|
||||
wantErr: false,
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue