Update Kapacitor alerts to set queryConfig to null if not parsable.
parent
315ca27b67
commit
3821b1ccff
|
@ -234,7 +234,7 @@ type SourcesStore interface {
|
|||
type AlertRule struct {
|
||||
ID string `json:"id,omitempty"` // ID is the unique ID of the alert
|
||||
TICKScript TICKScript `json:"tickscript"` // TICKScript is the raw tickscript associated with this Alert
|
||||
Query QueryConfig `json:"query"` // Query is the filter of data for the alert.
|
||||
Query *QueryConfig `json:"query"` // Query is the filter of data for the alert.
|
||||
Every string `json:"every"` // Every how often to check for the alerting criteria
|
||||
Alerts []string `json:"alerts"` // Alerts name all the services to notify (e.g. pagerduty)
|
||||
AlertNodes []KapacitorNode `json:"alertNodes,omitempty"` // AlertNodes define additional arguments to alerts
|
||||
|
|
|
@ -368,6 +368,7 @@ func alertType(script chronograf.TICKScript) (string, error) {
|
|||
func Reverse(script chronograf.TICKScript) (chronograf.AlertRule, error) {
|
||||
rule := chronograf.AlertRule{
|
||||
Alerts: []string{},
|
||||
Query: &chronograf.QueryConfig{},
|
||||
}
|
||||
t, err := alertType(script)
|
||||
if err != nil {
|
||||
|
|
|
@ -84,7 +84,7 @@ func TestReverse(t *testing.T) {
|
|||
Every: "30s",
|
||||
Message: "message",
|
||||
Details: "details",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
RetentionPolicy: "autogen",
|
||||
Measurement: "cpu",
|
||||
|
@ -193,7 +193,7 @@ func TestReverse(t *testing.T) {
|
|||
trigger
|
||||
|httpOut('output')`,
|
||||
want: chronograf.AlertRule{
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -332,7 +332,7 @@ func TestReverse(t *testing.T) {
|
|||
Every: "10s",
|
||||
Message: `Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} `,
|
||||
Details: "Email template",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "influxdb",
|
||||
RetentionPolicy: "autogen",
|
||||
Measurement: "haproxy",
|
||||
|
@ -447,7 +447,7 @@ func TestReverse(t *testing.T) {
|
|||
Every: "10s",
|
||||
Message: `Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} `,
|
||||
Details: "Email template",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "influxdb",
|
||||
RetentionPolicy: "autogen",
|
||||
Measurement: "haproxy",
|
||||
|
@ -564,7 +564,7 @@ func TestReverse(t *testing.T) {
|
|||
Every: "30s",
|
||||
Message: "message",
|
||||
Details: "details",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -588,7 +588,6 @@ func TestReverse(t *testing.T) {
|
|||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -690,7 +689,7 @@ func TestReverse(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -714,7 +713,6 @@ func TestReverse(t *testing.T) {
|
|||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -816,7 +814,7 @@ func TestReverse(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -840,7 +838,6 @@ func TestReverse(t *testing.T) {
|
|||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -930,7 +927,7 @@ func TestReverse(t *testing.T) {
|
|||
Value: "90",
|
||||
},
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -953,7 +950,6 @@ func TestReverse(t *testing.T) {
|
|||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1066,7 +1062,7 @@ trigger
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -1090,7 +1086,6 @@ trigger
|
|||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1203,7 +1198,7 @@ trigger
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -1227,7 +1222,6 @@ trigger
|
|||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -1318,7 +1312,7 @@ trigger
|
|||
Period: "10m0s",
|
||||
},
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -1336,7 +1330,6 @@ trigger
|
|||
Tags: []string{"host", "cluster_id"},
|
||||
},
|
||||
AreTagsAccepted: true,
|
||||
RawText: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -185,6 +185,7 @@ func (c *Client) All(ctx context.Context) (map[string]chronograf.AlertRule, erro
|
|||
}
|
||||
} else {
|
||||
rule.ID = task.ID
|
||||
rule.Query = nil
|
||||
rule.TICKScript = script
|
||||
alerts[task.ID] = rule
|
||||
}
|
||||
|
@ -210,6 +211,7 @@ func (c *Client) Get(ctx context.Context, id string) (chronograf.AlertRule, erro
|
|||
return chronograf.AlertRule{
|
||||
ID: task.ID,
|
||||
Name: task.ID,
|
||||
Query: nil,
|
||||
TICKScript: script,
|
||||
}, nil
|
||||
}
|
||||
|
@ -278,8 +280,8 @@ func (c *Client) kapaClient(ctx context.Context) (*client.Client, error) {
|
|||
})
|
||||
}
|
||||
|
||||
func toTask(q chronograf.QueryConfig) client.TaskType {
|
||||
if q.RawText == nil || *q.RawText == "" {
|
||||
func toTask(q *chronograf.QueryConfig) client.TaskType {
|
||||
if q == nil || q.RawText == nil || *q.RawText == "" {
|
||||
return client.StreamTask
|
||||
}
|
||||
return client.BatchTask
|
||||
|
|
|
@ -45,7 +45,7 @@ func TestData(t *testing.T) {
|
|||
}
|
||||
alert := chronograf.AlertRule{
|
||||
Trigger: "deadman",
|
||||
Query: q,
|
||||
Query: &q,
|
||||
}
|
||||
if tick, err := Data(alert); err != nil {
|
||||
t.Errorf("Error creating tick %v", err)
|
||||
|
|
|
@ -28,7 +28,7 @@ func TestInfluxOut(t *testing.T) {
|
|||
got, err := InfluxOut(chronograf.AlertRule{
|
||||
Name: "name",
|
||||
Trigger: "deadman",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Fields: []chronograf.Field{
|
||||
{
|
||||
Field: "usage_user",
|
||||
|
|
|
@ -20,7 +20,7 @@ func TestGenerate(t *testing.T) {
|
|||
Value: "90",
|
||||
},
|
||||
Every: "30s",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -65,7 +65,7 @@ func TestThreshold(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -209,7 +209,7 @@ func TestThresholdStringCrit(t *testing.T) {
|
|||
Every: "10s",
|
||||
Message: `Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} `,
|
||||
Details: "Email template",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "influxdb",
|
||||
RetentionPolicy: "autogen",
|
||||
Measurement: "haproxy",
|
||||
|
@ -347,7 +347,7 @@ func TestThresholdStringCritGreater(t *testing.T) {
|
|||
Every: "10s",
|
||||
Message: `Haproxy monitor : {{.ID}} : {{ index .Tags "server" }} : {{ index .Tags "pxname" }} is {{ .Level }} `,
|
||||
Details: "Email template",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "influxdb",
|
||||
RetentionPolicy: "autogen",
|
||||
Measurement: "haproxy",
|
||||
|
@ -483,7 +483,7 @@ func TestThresholdDetail(t *testing.T) {
|
|||
Every: "30s",
|
||||
Message: "message",
|
||||
Details: "details",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -630,7 +630,7 @@ func TestThresholdInsideRange(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -776,7 +776,7 @@ func TestThresholdOutsideRange(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -921,7 +921,7 @@ func TestThresholdNoAggregate(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -1058,7 +1058,7 @@ func TestRelative(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -1215,7 +1215,7 @@ func TestRelativeChange(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
@ -1369,7 +1369,7 @@ func TestDeadman(t *testing.T) {
|
|||
},
|
||||
Every: "30s",
|
||||
Message: "message",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "cpu",
|
||||
RetentionPolicy: "autogen",
|
||||
|
|
|
@ -140,40 +140,45 @@ func window(rule chronograf.AlertRule) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func groupBy(q chronograf.QueryConfig) string {
|
||||
func groupBy(q *chronograf.QueryConfig) string {
|
||||
groups := []string{}
|
||||
for _, tag := range q.GroupBy.Tags {
|
||||
groups = append(groups, fmt.Sprintf("'%s'", tag))
|
||||
if q != nil {
|
||||
for _, tag := range q.GroupBy.Tags {
|
||||
groups = append(groups, fmt.Sprintf("'%s'", tag))
|
||||
}
|
||||
}
|
||||
return "[" + strings.Join(groups, ",") + "]"
|
||||
}
|
||||
|
||||
func field(q chronograf.QueryConfig) (string, error) {
|
||||
for _, field := range q.Fields {
|
||||
return field.Field, nil
|
||||
func field(q *chronograf.QueryConfig) (string, error) {
|
||||
if q != nil {
|
||||
for _, field := range q.Fields {
|
||||
return field.Field, nil
|
||||
}
|
||||
}
|
||||
return "", fmt.Errorf("No fields set in query")
|
||||
}
|
||||
|
||||
func whereFilter(q chronograf.QueryConfig) string {
|
||||
operator := "=="
|
||||
if !q.AreTagsAccepted {
|
||||
operator = "!="
|
||||
}
|
||||
|
||||
outer := []string{}
|
||||
for tag, values := range q.Tags {
|
||||
inner := []string{}
|
||||
for _, value := range values {
|
||||
inner = append(inner, fmt.Sprintf(`"%s" %s '%s'`, tag, operator, value))
|
||||
func whereFilter(q *chronograf.QueryConfig) string {
|
||||
if q != nil {
|
||||
operator := "=="
|
||||
if !q.AreTagsAccepted {
|
||||
operator = "!="
|
||||
}
|
||||
outer = append(outer, "("+strings.Join(inner, " OR ")+")")
|
||||
}
|
||||
if len(outer) > 0 {
|
||||
sort.Strings(outer)
|
||||
return "lambda: " + strings.Join(outer, " AND ")
|
||||
}
|
||||
|
||||
outer := []string{}
|
||||
for tag, values := range q.Tags {
|
||||
inner := []string{}
|
||||
for _, value := range values {
|
||||
inner = append(inner, fmt.Sprintf(`"%s" %s '%s'`, tag, operator, value))
|
||||
}
|
||||
outer = append(outer, "("+strings.Join(inner, " OR ")+")")
|
||||
}
|
||||
if len(outer) > 0 {
|
||||
sort.Strings(outer)
|
||||
return "lambda: " + strings.Join(outer, " AND ")
|
||||
}
|
||||
}
|
||||
return "lambda: TRUE"
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ func TestVarsCritStringEqual(t *testing.T) {
|
|||
Value: "DOWN",
|
||||
},
|
||||
Every: "30s",
|
||||
Query: chronograf.QueryConfig{
|
||||
Query: &chronograf.QueryConfig{
|
||||
Database: "telegraf",
|
||||
Measurement: "haproxy",
|
||||
RetentionPolicy: "autogen",
|
||||
|
|
|
@ -357,19 +357,15 @@ func newAlertResponse(rule chronograf.AlertRule, tickScript chronograf.TICKScrip
|
|||
Status: status,
|
||||
}
|
||||
|
||||
if res.Query.ID == "" {
|
||||
res.Query.ID = res.ID
|
||||
if res.Alerts == nil {
|
||||
res.Alerts = make([]string, 0)
|
||||
}
|
||||
|
||||
if res.AlertRule.Alerts == nil {
|
||||
res.AlertRule.Alerts = make([]string, 0)
|
||||
if res.AlertNodes == nil {
|
||||
res.AlertNodes = make([]chronograf.KapacitorNode, 0)
|
||||
}
|
||||
|
||||
if res.AlertRule.AlertNodes == nil {
|
||||
res.AlertRule.AlertNodes = make([]chronograf.KapacitorNode, 0)
|
||||
}
|
||||
|
||||
for _, n := range res.AlertRule.AlertNodes {
|
||||
for _, n := range res.AlertNodes {
|
||||
if n.Args == nil {
|
||||
n.Args = make([]string, 0)
|
||||
}
|
||||
|
@ -383,22 +379,28 @@ func newAlertResponse(rule chronograf.AlertRule, tickScript chronograf.TICKScrip
|
|||
}
|
||||
}
|
||||
|
||||
if res.AlertRule.Query.Fields == nil {
|
||||
res.AlertRule.Query.Fields = make([]chronograf.Field, 0)
|
||||
|
||||
}
|
||||
for _, f := range res.AlertRule.Query.Fields {
|
||||
if f.Funcs == nil {
|
||||
f.Funcs = make([]string, 0)
|
||||
if res.Query != nil {
|
||||
if res.Query.ID == "" {
|
||||
res.Query.ID = res.ID
|
||||
}
|
||||
}
|
||||
|
||||
if res.AlertRule.Query.GroupBy.Tags == nil {
|
||||
res.AlertRule.Query.GroupBy.Tags = make([]string, 0)
|
||||
}
|
||||
if res.Query.Fields == nil {
|
||||
res.Query.Fields = make([]chronograf.Field, 0)
|
||||
}
|
||||
|
||||
if res.AlertRule.Query.Tags == nil {
|
||||
res.AlertRule.Query.Tags = make(map[string][]string)
|
||||
for _, f := range res.Query.Fields {
|
||||
if f.Funcs == nil {
|
||||
f.Funcs = make([]string, 0)
|
||||
}
|
||||
}
|
||||
|
||||
if res.Query.GroupBy.Tags == nil {
|
||||
res.Query.GroupBy.Tags = make([]string, 0)
|
||||
}
|
||||
|
||||
if res.Query.Tags == nil {
|
||||
res.Query.Tags = make(map[string][]string)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue