influxdb/chronograf/.kapacitor/ast_test.go

1570 lines
32 KiB
Go

package kapacitor
import (
"reflect"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/influxdata/influxdb/chronograf"
)
func TestReverse(t *testing.T) {
tests := []struct {
name string
script chronograf.TICKScript
want chronograf.AlertRule
wantErr bool
}{
{
name: "simple stream tickscript",
script: chronograf.TICKScript(`
var name = 'name'
var triggerType = 'threshold'
var every = 30s
var period = 10m
var groupBy = ['host', 'cluster_id']
var db = 'telegraf'
var rp = 'autogen'
var measurement = 'cpu'
var message = 'message'
var details = 'details'
var crit = 90
var idVar = name + ':{{.Group}}'
var idTag = 'alertID'
var levelTag = 'level'
var messageField = 'message'
var durationField = 'duration'
var whereFilter = lambda: ("cpu" == 'cpu_total') AND ("host" == 'acc-0eabc309-eu-west-1-data-3' OR "host" == 'prod')
var data = stream
|from()
.database(db)
.retentionPolicy(rp)
.measurement(measurement)
|window()
.period(period)
.every(every)
.align()
|mean('usage_user')
.as('value')
var trigger = data
|alert()
.crit(lambda: "value" > crit)
.stateChangesOnly()
.message(message)
.id(idVar)
.idTag(idTag)
.levelTag(levelTag)
.messageField(messageField)
.durationField(durationField)
.slack()
.victorOps()
.email('howdy@howdy.com', 'doody@doody.com')
.log('/tmp/alerts.log')
.post('http://backin.tm')
.endpoint('myendpoint')
.header('key', 'value')
`),
want: chronograf.AlertRule{
Name: "name",
Trigger: "threshold",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{
To: []string{"howdy@howdy.com", "doody@doody.com"},
},
},
Log: []*chronograf.Log{
{
FilePath: "/tmp/alerts.log",
},
},
Posts: []*chronograf.Post{
{
URL: "http://backin.tm",
Headers: map[string]string{"key": "value"},
},
},
},
TriggerValues: chronograf.TriggerValues{
Operator: "greater than",
Value: "90",
},
Every: "30s",
Message: "message",
Details: "details",
Query: &chronograf.QueryConfig{
Database: "telegraf",
RetentionPolicy: "autogen",
Measurement: "cpu",
Fields: []chronograf.Field{
{
Value: "mean",
Args: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Type: "func",
},
},
GroupBy: chronograf.GroupBy{
Time: "10m0s",
Tags: []string{"host", "cluster_id"},
},
Tags: map[string][]string{
"cpu": []string{
"cpu_total",
},
"host": []string{
"acc-0eabc309-eu-west-1-data-3",
"prod",
},
},
AreTagsAccepted: true,
},
},
},
{
name: "Test Threshold",
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 = 'threshold'
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 trigger = data
|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{
Query: &chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
{
Value: "mean",
Args: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Type: "func",
},
},
Tags: map[string][]string{
"cpu": []string{"cpu_total"},
"host": []string{"acc-0eabc309-eu-west-1-data-3", "prod"},
},
GroupBy: chronograf.GroupBy{
Time: "10m0s",
Tags: []string{"host", "cluster_id"},
},
AreTagsAccepted: true,
},
Every: "30s",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{
To: []string{},
},
},
},
Message: "message",
Trigger: "threshold",
TriggerValues: chronograf.TriggerValues{
Operator: "greater than",
Value: "90",
},
Name: "name",
},
},
{
name: "Test haproxy string comparison",
script: `var db = 'influxdb'
var rp = 'autogen'
var measurement = 'haproxy'
var groupBy = ['pxname']
var whereFilter = lambda: TRUE
var period = 10s
var every = 10s
var name = 'haproxy'
var idVar = name + ':{{.Group}}'
var message = 'Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} '
var idTag = 'alertID'
var levelTag = 'level'
var messageField = 'message'
var durationField = 'duration'
var outputDB = 'chronograf'
var outputRP = 'autogen'
var outputMeasurement = 'alerts'
var triggerType = 'threshold'
var details = 'Email template'
var crit = 'DOWN'
var data = stream
|from()
.database(db)
.retentionPolicy(rp)
.measurement(measurement)
.groupBy(groupBy)
.where(whereFilter)
|window()
.period(period)
.every(every)
.align()
|last('status')
.as('value')
var trigger = data
|alert()
.crit(lambda: "value" == crit)
.stateChangesOnly()
.message(message)
.id(idVar)
.idTag(idTag)
.levelTag(levelTag)
.messageField(messageField)
.durationField(durationField)
.details(details)
.email()
trigger
|influxDBOut()
.create()
.database(outputDB)
.retentionPolicy(outputRP)
.measurement(outputMeasurement)
.tag('alertName', name)
.tag('triggerType', triggerType)
trigger
|httpOut('output')
`,
want: chronograf.AlertRule{
Name: "haproxy",
Trigger: "threshold",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Email: []*chronograf.Email{
{To: []string{}},
},
},
TriggerValues: chronograf.TriggerValues{
Operator: "equal to",
Value: "DOWN",
},
Every: "10s",
Message: `Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} `,
Details: "Email template",
Query: &chronograf.QueryConfig{
Database: "influxdb",
RetentionPolicy: "autogen",
Measurement: "haproxy",
Fields: []chronograf.Field{
{
Value: "last",
Args: []chronograf.Field{
{
Value: "status",
Type: "field",
},
},
Type: "func",
},
},
GroupBy: chronograf.GroupBy{
Time: "10s",
Tags: []string{"pxname"},
},
AreTagsAccepted: false,
},
},
},
{
name: "Test haproxy",
script: `var db = 'influxdb'
var rp = 'autogen'
var measurement = 'haproxy'
var groupBy = ['pxname']
var whereFilter = lambda: TRUE
var period = 10s
var every = 10s
var name = 'haproxy'
var idVar = name + ':{{.Group}}'
var message = 'Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} '
var idTag = 'alertID'
var levelTag = 'level'
var messageField = 'message'
var durationField = 'duration'
var outputDB = 'chronograf'
var outputRP = 'autogen'
var outputMeasurement = 'alerts'
var triggerType = 'threshold'
var details = 'Email template'
var crit = 'DOWN'
var data = stream
|from()
.database(db)
.retentionPolicy(rp)
.measurement(measurement)
.groupBy(groupBy)
.where(whereFilter)
|window()
.period(period)
.every(every)
.align()
|last('status')
.as('value')
var trigger = data
|alert()
.crit(lambda: "value" > crit)
.stateChangesOnly()
.message(message)
.id(idVar)
.idTag(idTag)
.levelTag(levelTag)
.messageField(messageField)
.durationField(durationField)
.details(details)
.email()
trigger
|influxDBOut()
.create()
.database(outputDB)
.retentionPolicy(outputRP)
.measurement(outputMeasurement)
.tag('alertName', name)
.tag('triggerType', triggerType)
trigger
|httpOut('output')
`,
want: chronograf.AlertRule{
Name: "haproxy",
Trigger: "threshold",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Email: []*chronograf.Email{
{To: []string{}},
},
},
TriggerValues: chronograf.TriggerValues{
Operator: "greater than",
Value: "DOWN",
},
Every: "10s",
Message: `Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} `,
Details: "Email template",
Query: &chronograf.QueryConfig{
Database: "influxdb",
RetentionPolicy: "autogen",
Measurement: "haproxy",
Fields: []chronograf.Field{
{
Value: "last",
Args: []chronograf.Field{
{
Value: "status",
Type: "field",
},
},
Type: "func",
},
},
GroupBy: chronograf.GroupBy{
Time: "10s",
Tags: []string{"pxname"},
},
AreTagsAccepted: false,
},
},
},
{
name: "Test valid template alert with detail",
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 = 'threshold'
var details = 'details'
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 trigger = data
|alert()
.crit(lambda: "value" > crit)
.stateChangesOnly()
.message(message)
.id(idVar)
.idTag(idTag)
.levelTag(levelTag)
.messageField(messageField)
.durationField(durationField)
.details(details)
.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: "threshold",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{To: []string{}},
},
},
TriggerValues: chronograf.TriggerValues{
Operator: "greater than",
Value: "90",
},
Every: "30s",
Message: "message",
Details: "details",
Query: &chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
{
Value: "mean",
Args: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Type: "func",
},
},
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,
},
},
},
{
name: "Test valid threshold inside range",
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 = 'threshold'
var lower = 90
var upper = 100
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 trigger = data
|alert()
.crit(lambda: "value" >= lower AND "value" <= upper)
.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: "threshold",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{To: []string{}},
},
},
TriggerValues: chronograf.TriggerValues{
Operator: "inside range",
Value: "90",
RangeValue: "100",
},
Every: "30s",
Message: "message",
Query: &chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
{
Value: "mean",
Args: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Type: "func",
},
},
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,
},
},
},
{
name: "Test valid threshold outside range",
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 = 'threshold'
var lower = 90
var upper = 100
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 trigger = data
|alert()
.crit(lambda: "value" < lower OR "value" > upper)
.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: "threshold",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{To: []string{}},
},
},
TriggerValues: chronograf.TriggerValues{
Operator: "outside range",
Value: "90",
RangeValue: "100",
},
Every: "30s",
Message: "message",
Query: &chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
{
Value: "mean",
Args: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Type: "func",
},
},
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,
},
},
},
{
name: "Test threshold no aggregate",
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 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 = 'threshold'
var crit = 90
var data = stream
|from()
.database(db)
.retentionPolicy(rp)
.measurement(measurement)
.groupBy(groupBy)
.where(whereFilter)
|eval(lambda: "usage_user")
.as('value')
var trigger = data
|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: "threshold",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{To: []string{}},
},
},
TriggerValues: chronograf.TriggerValues{
Operator: "greater than",
Value: "90",
},
Message: "message",
Query: &chronograf.QueryConfig{
Database: "telegraf",
Measurement: "cpu",
RetentionPolicy: "autogen",
Fields: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Tags: map[string][]string{
"host": []string{
"acc-0eabc309-eu-west-1-data-3",
"prod",
},
"cpu": []string{
"cpu_total",
},
},
GroupBy: chronograf.GroupBy{
Tags: []string{"host", "cluster_id"},
},
AreTagsAccepted: true,
},
},
},
{
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",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{To: []string{}},
},
},
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{
{
Value: "mean",
Args: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Type: "func",
},
},
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,
},
},
},
{
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",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{To: []string{}},
},
},
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{
{
Value: "mean",
Args: []chronograf.Field{
{
Value: "usage_user",
Type: "field",
},
},
Type: "func",
},
},
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,
},
},
},
{
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",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
Slack: []*chronograf.Slack{
{},
},
VictorOps: []*chronograf.VictorOps{
{},
},
Email: []*chronograf.Email{
{To: []string{}},
},
},
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,
},
},
},
{
name: "Test threshold lambda",
script: `var db = '_internal'
var rp = 'monitor'
var measurement = 'cq'
var groupBy = []
var whereFilter = lambda: TRUE
var name = 'rule 1'
var idVar = name + ':{{.Group}}'
var message = ''
var idTag = 'alertID'
var levelTag = 'level'
var messageField = 'message'
var durationField = 'duration'
var outputDB = 'chronograf'
var outputRP = 'autogen'
var outputMeasurement = 'alerts'
var triggerType = 'threshold'
var crit = 90000
var data = stream
|from()
.database(db)
.retentionPolicy(rp)
.measurement(measurement)
.groupBy(groupBy)
.where(whereFilter)
|eval(lambda: "queryOk")
.as('value')
var trigger = data
|alert()
.crit(lambda: "value" > crit)
.stateChangesOnly()
.message(message)
.id(idVar)
.idTag(idTag)
.levelTag(levelTag)
.messageField(messageField)
.durationField(durationField)
trigger
|influxDBOut()
.create()
.database(outputDB)
.retentionPolicy(outputRP)
.measurement(outputMeasurement)
.tag('alertName', name)
.tag('triggerType', triggerType)
trigger
|httpOut('output')
`,
want: chronograf.AlertRule{
Name: "rule 1",
Trigger: "threshold",
TriggerValues: chronograf.TriggerValues{
Operator: "greater than",
Value: "90000",
},
Every: "",
Message: "",
Details: "",
AlertNodes: chronograf.AlertNodes{
IsStateChangesOnly: true,
},
Query: &chronograf.QueryConfig{
Database: "_internal",
RetentionPolicy: "monitor",
Measurement: "cq",
Fields: []chronograf.Field{
{
Value: "queryOk",
Type: "field",
},
},
GroupBy: chronograf.GroupBy{
Tags: []string{},
},
AreTagsAccepted: false,
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := Reverse(tt.script)
if (err != nil) != tt.wantErr {
t.Errorf("reverse error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("reverse = %s", cmp.Diff(got, tt.want))
if tt.want.Query != nil {
if got.Query == nil {
t.Errorf("reverse = got nil QueryConfig")
} else if !cmp.Equal(*got.Query, *tt.want.Query) {
t.Errorf("reverse = QueryConfig not equal %s", cmp.Diff(*got.Query, *tt.want.Query))
}
}
}
})
}
}