vmalert - add expr to variables, add escape functions (#495)

* vmalert - add expr to variables, add escape functions

Co-authored-by: kreedom
This commit is contained in:
kreedom 2020-05-18 11:55:16 +03:00 committed by Aliaksandr Valialkin
parent c7f3e58032
commit 27911ae179
6 changed files with 36 additions and 6 deletions

View File

@ -121,7 +121,7 @@ func main() {
}() }()
rh := &requestHandler{m: manager} rh := &requestHandler{m: manager}
go httpserver.Serve(*httpListenAddr, (rh).handler) go httpserver.Serve(*httpListenAddr, rh.handler)
sig := procutil.WaitForSigterm() sig := procutil.WaitForSigterm()
logger.Infof("service received signal %s", sig) logger.Infof("service received signal %s", sig)

View File

@ -18,6 +18,7 @@ type Alert struct {
Annotations map[string]string Annotations map[string]string
State AlertState State AlertState
Expr string
Start time.Time Start time.Time
End time.Time End time.Time
Value float64 Value float64
@ -52,14 +53,15 @@ func (as AlertState) String() string {
type alertTplData struct { type alertTplData struct {
Labels map[string]string Labels map[string]string
Value float64 Value float64
Expr string
} }
const tplHeader = `{{ $value := .Value }}{{ $labels := .Labels }}` const tplHeader = `{{ $value := .Value }}{{ $labels := .Labels }}{{ $expr := .Expr }}`
// ExecTemplate executes the Alert template for give // ExecTemplate executes the Alert template for give
// map of annotations. // map of annotations.
func (a *Alert) ExecTemplate(annotations map[string]string) (map[string]string, error) { func (a *Alert) ExecTemplate(annotations map[string]string) (map[string]string, error) {
tplData := alertTplData{Value: a.Value, Labels: a.Labels} tplData := alertTplData{Value: a.Value, Labels: a.Labels, Expr: a.Expr}
return templateAnnotations(annotations, tplHeader, tplData) return templateAnnotations(annotations, tplHeader, tplData)
} }

View File

@ -1,22 +1,27 @@
package notifier package notifier
import ( import (
"fmt" "net/url"
"testing" "testing"
) )
func TestAlert_ExecTemplate(t *testing.T) { func TestAlert_ExecTemplate(t *testing.T) {
u, _ := url.Parse("https://victoriametrics.com/path")
InitTemplateFunc(u)
testCases := []struct { testCases := []struct {
name string
alert *Alert alert *Alert
annotations map[string]string annotations map[string]string
expTpl map[string]string expTpl map[string]string
}{ }{
{ {
name: "empty-alert",
alert: &Alert{}, alert: &Alert{},
annotations: map[string]string{}, annotations: map[string]string{},
expTpl: map[string]string{}, expTpl: map[string]string{},
}, },
{ {
name: "no-template",
alert: &Alert{ alert: &Alert{
Value: 1e4, Value: 1e4,
Labels: map[string]string{ Labels: map[string]string{
@ -27,6 +32,7 @@ func TestAlert_ExecTemplate(t *testing.T) {
expTpl: map[string]string{}, expTpl: map[string]string{},
}, },
{ {
name: "label-template",
alert: &Alert{ alert: &Alert{
Value: 1e4, Value: 1e4,
Labels: map[string]string{ Labels: map[string]string{
@ -43,10 +49,24 @@ func TestAlert_ExecTemplate(t *testing.T) {
"description": "It is 10000 connections for localhost", "description": "It is 10000 connections for localhost",
}, },
}, },
{
name: "expression-template",
alert: &Alert{
Expr: "vm_rows>0",
},
annotations: map[string]string{
"exprEscapedQuery": "{{ $expr|queryEscape }}",
"exprEscapedPath": "{{ $expr|pathEscape }}",
},
expTpl: map[string]string{
"exprEscapedQuery": "vm_rows%3E0",
"exprEscapedPath": "vm_rows%3E0",
},
},
} }
for i, tc := range testCases { for _, tc := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
tpl, err := tc.alert.ExecTemplate(tc.annotations) tpl, err := tc.alert.ExecTemplate(tc.annotations)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)

View File

@ -142,6 +142,12 @@ func InitTemplateFunc(externalURL *url.URL) {
"externalURL": func() string { "externalURL": func() string {
return externalURL.String() return externalURL.String()
}, },
"pathEscape": func(u string) string {
return url.PathEscape(u)
},
"queryEscape": func(q string) string {
return url.QueryEscape(q)
},
} }
} }

View File

@ -152,6 +152,7 @@ func (r *Rule) newAlert(m datasource.Metric) (*notifier.Alert, error) {
Labels: map[string]string{}, Labels: map[string]string{},
Value: m.Value, Value: m.Value,
Start: time.Now(), Start: time.Now(),
Expr: r.Expr,
// TODO: support End time // TODO: support End time
} }
for _, l := range m.Labels { for _, l := range m.Labels {

View File

@ -6,6 +6,7 @@ groups:
expr: vm_rows > 0 expr: vm_rows > 0
labels: labels:
label: bar label: bar
expr: "{{ $expr|queryEscape }}"
annotations: annotations:
summary: "{{ $value|humanize }}" summary: "{{ $value|humanize }}"
description: "{{$labels}}" description: "{{$labels}}"