Add kapacitor AST tests for relative and deadman
parent
02b371741f
commit
870ae7913b
|
@ -1,7 +1,6 @@
|
|||
package kapacitor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -477,19 +476,6 @@ func Reverse(script chronograf.TICKScript) (chronograf.AlertRule, error) {
|
|||
return rule, err
|
||||
}
|
||||
|
||||
func valueStr(key string, value *string, vars map[string]tick.Var) error {
|
||||
v, ok := vars[key]
|
||||
if !ok {
|
||||
return fmt.Errorf("No %s", key)
|
||||
}
|
||||
val, ok := v.Value.(string)
|
||||
if !ok {
|
||||
return fmt.Errorf("No %s", key)
|
||||
}
|
||||
value = &val
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractAlertNodes(p *pipeline.Pipeline, rule *chronograf.AlertRule) {
|
||||
p.Walk(func(n pipeline.Node) error {
|
||||
switch t := n.(type) {
|
||||
|
|
|
@ -240,7 +240,7 @@ trigger
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "Test valid template alert",
|
||||
name: "Test haproxy string comparison",
|
||||
script: `var db = 'influxdb'
|
||||
|
||||
var rp = 'autogen'
|
||||
|
@ -351,7 +351,7 @@ trigger
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "Test valid template alert",
|
||||
name: "Test haproxy",
|
||||
script: `var db = 'influxdb'
|
||||
|
||||
var rp = 'autogen'
|
||||
|
@ -957,6 +957,389 @@ trigger
|
|||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test relative alert",
|
||||
script: `var db = 'telegraf'
|
||||
|
||||
var rp = 'autogen'
|
||||
|
||||
var measurement = 'cpu'
|
||||
|
||||
var groupBy = ['host', 'cluster_id']
|
||||
|
||||
var whereFilter = lambda: ("cpu" == 'cpu_total') AND ("host" == 'acc-0eabc309-eu-west-1-data-3' OR "host" == 'prod')
|
||||
|
||||
var period = 10m
|
||||
|
||||
var every = 30s
|
||||
|
||||
var name = 'name'
|
||||
|
||||
var idVar = name + ':{{.Group}}'
|
||||
|
||||
var message = 'message'
|
||||
|
||||
var idTag = 'alertID'
|
||||
|
||||
var levelTag = 'level'
|
||||
|
||||
var messageField = 'message'
|
||||
|
||||
var durationField = 'duration'
|
||||
|
||||
var outputDB = 'chronograf'
|
||||
|
||||
var outputRP = 'autogen'
|
||||
|
||||
var outputMeasurement = 'alerts'
|
||||
|
||||
var triggerType = 'relative'
|
||||
|
||||
var shift = 1m
|
||||
|
||||
var crit = 90
|
||||
|
||||
var data = stream
|
||||
|from()
|
||||
.database(db)
|
||||
.retentionPolicy(rp)
|
||||
.measurement(measurement)
|
||||
.groupBy(groupBy)
|
||||
.where(whereFilter)
|
||||
|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: abs(float("current.value" - "past.value")) / float("past.value") * 100.0)
|
||||
.keep()
|
||||
.as('value')
|
||||
|alert()
|
||||
.crit(lambda: "value" > crit)
|
||||
.stateChangesOnly()
|
||||
.message(message)
|
||||
.id(idVar)
|
||||
.idTag(idTag)
|
||||
.levelTag(levelTag)
|
||||
.messageField(messageField)
|
||||
.durationField(durationField)
|
||||
.slack()
|
||||
.victorOps()
|
||||
.email()
|
||||
|
||||
trigger
|
||||
|influxDBOut()
|
||||
.create()
|
||||
.database(outputDB)
|
||||
.retentionPolicy(outputRP)
|
||||
.measurement(outputMeasurement)
|
||||
.tag('alertName', name)
|
||||
.tag('triggerType', triggerType)
|
||||
|
||||
trigger
|
||||
|httpOut('output')
|
||||
`,
|
||||
want: chronograf.AlertRule{
|
||||
Name: "name",
|
||||
Trigger: "relative",
|
||||
Alerts: []string{"victorops", "smtp", "slack"},
|
||||
AlertNodes: []chronograf.KapacitorNode{
|
||||
{Name: "victorops"},
|
||||
{Name: "smtp"},
|
||||
{Name: "slack"},
|
||||
},
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Change: "% change",
|
||||
Shift: "1m0s",
|
||||
Operator: "greater than",
|
||||
Value: "90",
|
||||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
Fields: []chronograf.Field{
|
||||
{
|
||||
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: chronograf.GroupBy{
|
||||
Time: "10m0s",
|
||||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test relative change",
|
||||
script: `var db = 'telegraf'
|
||||
|
||||
var rp = 'autogen'
|
||||
|
||||
var measurement = 'cpu'
|
||||
|
||||
var groupBy = ['host', 'cluster_id']
|
||||
|
||||
var whereFilter = lambda: ("cpu" == 'cpu_total') AND ("host" == 'acc-0eabc309-eu-west-1-data-3' OR "host" == 'prod')
|
||||
|
||||
var period = 10m
|
||||
|
||||
var every = 30s
|
||||
|
||||
var name = 'name'
|
||||
|
||||
var idVar = name + ':{{.Group}}'
|
||||
|
||||
var message = 'message'
|
||||
|
||||
var idTag = 'alertID'
|
||||
|
||||
var levelTag = 'level'
|
||||
|
||||
var messageField = 'message'
|
||||
|
||||
var durationField = 'duration'
|
||||
|
||||
var outputDB = 'chronograf'
|
||||
|
||||
var outputRP = 'autogen'
|
||||
|
||||
var outputMeasurement = 'alerts'
|
||||
|
||||
var triggerType = 'relative'
|
||||
|
||||
var shift = 1m
|
||||
|
||||
var crit = 90
|
||||
|
||||
var data = stream
|
||||
|from()
|
||||
.database(db)
|
||||
.retentionPolicy(rp)
|
||||
.measurement(measurement)
|
||||
.groupBy(groupBy)
|
||||
.where(whereFilter)
|
||||
|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()
|
||||
.crit(lambda: "value" > crit)
|
||||
.stateChangesOnly()
|
||||
.message(message)
|
||||
.id(idVar)
|
||||
.idTag(idTag)
|
||||
.levelTag(levelTag)
|
||||
.messageField(messageField)
|
||||
.durationField(durationField)
|
||||
.slack()
|
||||
.victorOps()
|
||||
.email()
|
||||
|
||||
trigger
|
||||
|influxDBOut()
|
||||
.create()
|
||||
.database(outputDB)
|
||||
.retentionPolicy(outputRP)
|
||||
.measurement(outputMeasurement)
|
||||
.tag('alertName', name)
|
||||
.tag('triggerType', triggerType)
|
||||
|
||||
trigger
|
||||
|httpOut('output')
|
||||
`,
|
||||
want: chronograf.AlertRule{
|
||||
Name: "name",
|
||||
Trigger: "relative",
|
||||
Alerts: []string{"victorops", "smtp", "slack"},
|
||||
AlertNodes: []chronograf.KapacitorNode{
|
||||
{Name: "victorops"},
|
||||
{Name: "smtp"},
|
||||
{Name: "slack"},
|
||||
},
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Change: "change",
|
||||
Shift: "1m0s",
|
||||
Operator: "greater than",
|
||||
Value: "90",
|
||||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
Fields: []chronograf.Field{
|
||||
{
|
||||
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: chronograf.GroupBy{
|
||||
Time: "10m0s",
|
||||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Test deadman",
|
||||
script: `var db = 'telegraf'
|
||||
|
||||
var rp = 'autogen'
|
||||
|
||||
var measurement = 'cpu'
|
||||
|
||||
var groupBy = ['host', 'cluster_id']
|
||||
|
||||
var whereFilter = 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 outputDB = 'chronograf'
|
||||
|
||||
var outputRP = 'autogen'
|
||||
|
||||
var outputMeasurement = 'alerts'
|
||||
|
||||
var triggerType = 'deadman'
|
||||
|
||||
var threshold = 0.0
|
||||
|
||||
var data = stream
|
||||
|from()
|
||||
.database(db)
|
||||
.retentionPolicy(rp)
|
||||
.measurement(measurement)
|
||||
.groupBy(groupBy)
|
||||
.where(whereFilter)
|
||||
|
||||
var trigger = data
|
||||
|deadman(threshold, period)
|
||||
.stateChangesOnly()
|
||||
.message(message)
|
||||
.id(idVar)
|
||||
.idTag(idTag)
|
||||
.levelTag(levelTag)
|
||||
.messageField(messageField)
|
||||
.durationField(durationField)
|
||||
.slack()
|
||||
.victorOps()
|
||||
.email()
|
||||
|
||||
trigger
|
||||
|eval(lambda: "emitted")
|
||||
.as('value')
|
||||
.keep('value', messageField, durationField)
|
||||
|influxDBOut()
|
||||
.create()
|
||||
.database(outputDB)
|
||||
.retentionPolicy(outputRP)
|
||||
.measurement(outputMeasurement)
|
||||
.tag('alertName', name)
|
||||
.tag('triggerType', triggerType)
|
||||
|
||||
trigger
|
||||
|httpOut('output')
|
||||
`,
|
||||
want: chronograf.AlertRule{
|
||||
Name: "name",
|
||||
Trigger: "deadman",
|
||||
Alerts: []string{"victorops", "smtp", "slack"},
|
||||
AlertNodes: []chronograf.KapacitorNode{
|
||||
{Name: "victorops"},
|
||||
{Name: "smtp"},
|
||||
{Name: "slack"},
|
||||
},
|
||||
TriggerValues: chronograf.TriggerValues{
|
||||
Period: "10m0s",
|
||||
},
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
Tags: map[string][]string{
|
||||
"host": []string{
|
||||
"acc-0eabc309-eu-west-1-data-3",
|
||||
"prod",
|
||||
},
|
||||
"cpu": []string{
|
||||
"cpu_total",
|
||||
},
|
||||
},
|
||||
GroupBy: chronograf.GroupBy{
|
||||
Time: "",
|
||||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
|
Loading…
Reference in New Issue