mirror of https://github.com/prometheus/prometheus
Support expansion of native histogram values in alert templates
Co-authored-by: Aleks Fazlieva <britishrum@users.noreply.github.com> Signed-off-by: suntala <arati.rana@grafana.com>pull/13731/head
parent
25a8d57671
commit
44f385fd51
|
@ -27,6 +27,7 @@ import (
|
||||||
"gopkg.in/yaml.v3"
|
"gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/prometheus/prometheus/model/timestamp"
|
"github.com/prometheus/prometheus/model/timestamp"
|
||||||
|
"github.com/prometheus/prometheus/promql"
|
||||||
"github.com/prometheus/prometheus/promql/parser"
|
"github.com/prometheus/prometheus/promql/parser"
|
||||||
"github.com/prometheus/prometheus/template"
|
"github.com/prometheus/prometheus/template"
|
||||||
)
|
)
|
||||||
|
@ -256,7 +257,7 @@ func testTemplateParsing(rl *RuleNode) (errs []error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trying to parse templates.
|
// Trying to parse templates.
|
||||||
tmplData := template.AlertTemplateData(map[string]string{}, map[string]string{}, "", 0)
|
tmplData := template.AlertTemplateData(map[string]string{}, map[string]string{}, "", promql.Sample{})
|
||||||
defs := []string{
|
defs := []string{
|
||||||
"{{$labels := .Labels}}",
|
"{{$labels := .Labels}}",
|
||||||
"{{$externalLabels := .ExternalLabels}}",
|
"{{$externalLabels := .ExternalLabels}}",
|
||||||
|
|
|
@ -364,7 +364,7 @@ func (r *AlertingRule) Eval(ctx context.Context, ts time.Time, query QueryFunc,
|
||||||
// Provide the alert information to the template.
|
// Provide the alert information to the template.
|
||||||
l := smpl.Metric.Map()
|
l := smpl.Metric.Map()
|
||||||
|
|
||||||
tmplData := template.AlertTemplateData(l, r.externalLabels, r.externalURL, smpl.F)
|
tmplData := template.AlertTemplateData(l, r.externalLabels, r.externalURL, smpl)
|
||||||
// Inject some convenience variables that are easier to remember for users
|
// Inject some convenience variables that are easier to remember for users
|
||||||
// who are not used to Go's templating system.
|
// who are not used to Go's templating system.
|
||||||
defs := []string{
|
defs := []string{
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"github.com/prometheus/common/model"
|
"github.com/prometheus/common/model"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/prometheus/prometheus/model/histogram"
|
||||||
"github.com/prometheus/prometheus/model/labels"
|
"github.com/prometheus/prometheus/model/labels"
|
||||||
"github.com/prometheus/prometheus/model/relabel"
|
"github.com/prometheus/prometheus/model/relabel"
|
||||||
"github.com/prometheus/prometheus/model/timestamp"
|
"github.com/prometheus/prometheus/model/timestamp"
|
||||||
|
@ -85,6 +86,67 @@ func TestAlertingRuleState(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAlertingRuleTemplateWithHistogram(t *testing.T) {
|
||||||
|
h := histogram.FloatHistogram{
|
||||||
|
Schema: 0,
|
||||||
|
Count: 30,
|
||||||
|
Sum: 1111.1,
|
||||||
|
ZeroThreshold: 0.001,
|
||||||
|
ZeroCount: 2,
|
||||||
|
PositiveSpans: []histogram.Span{
|
||||||
|
{Offset: 0, Length: 1},
|
||||||
|
{Offset: 1, Length: 5},
|
||||||
|
},
|
||||||
|
PositiveBuckets: []float64{1, 1, 2, 1, 1, 1},
|
||||||
|
NegativeSpans: []histogram.Span{
|
||||||
|
{Offset: 1, Length: 4},
|
||||||
|
{Offset: 4, Length: 3},
|
||||||
|
},
|
||||||
|
NegativeBuckets: []float64{-2, 2, 2, 7, 5, 5, 2},
|
||||||
|
}
|
||||||
|
|
||||||
|
q := func(ctx context.Context, qs string, t time.Time) (promql.Vector, error) {
|
||||||
|
return []promql.Sample{{H: &h}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
expr, err := parser.ParseExpr("foo")
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rule := NewAlertingRule(
|
||||||
|
"HistogramAsValue",
|
||||||
|
expr,
|
||||||
|
time.Minute,
|
||||||
|
0,
|
||||||
|
labels.FromStrings("histogram", "{{ $value }}"),
|
||||||
|
labels.EmptyLabels(), labels.EmptyLabels(), "", true, nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
evalTime := time.Now()
|
||||||
|
res, err := rule.Eval(context.TODO(), evalTime, q, nil, 0)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Len(t, res, 2)
|
||||||
|
for _, smpl := range res {
|
||||||
|
smplName := smpl.Metric.Get("__name__")
|
||||||
|
if smplName == "ALERTS" {
|
||||||
|
result := promql.Sample{
|
||||||
|
Metric: labels.FromStrings(
|
||||||
|
"__name__", "ALERTS",
|
||||||
|
"alertname", "HistogramAsValue",
|
||||||
|
"alertstate", "pending",
|
||||||
|
"histogram", h.String(),
|
||||||
|
),
|
||||||
|
T: timestamp.FromTime(evalTime),
|
||||||
|
F: 1,
|
||||||
|
}
|
||||||
|
testutil.RequireEqual(t, result, smpl)
|
||||||
|
} else {
|
||||||
|
// If not 'ALERTS', it has to be 'ALERTS_FOR_STATE'.
|
||||||
|
require.Equal(t, "ALERTS_FOR_STATE", smplName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAlertingRuleLabelsUpdate(t *testing.T) {
|
func TestAlertingRuleLabelsUpdate(t *testing.T) {
|
||||||
storage := promql.LoadedStorage(t, `
|
storage := promql.LoadedStorage(t, `
|
||||||
load 1m
|
load 1m
|
||||||
|
|
|
@ -355,18 +355,24 @@ func NewTemplateExpander(
|
||||||
}
|
}
|
||||||
|
|
||||||
// AlertTemplateData returns the interface to be used in expanding the template.
|
// AlertTemplateData returns the interface to be used in expanding the template.
|
||||||
func AlertTemplateData(labels, externalLabels map[string]string, externalURL string, value float64) interface{} {
|
func AlertTemplateData(labels, externalLabels map[string]string, externalURL string, smpl promql.Sample) interface{} {
|
||||||
return struct {
|
res := struct {
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
ExternalLabels map[string]string
|
ExternalLabels map[string]string
|
||||||
ExternalURL string
|
ExternalURL string
|
||||||
Value float64
|
Value interface{}
|
||||||
}{
|
}{
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
ExternalLabels: externalLabels,
|
ExternalLabels: externalLabels,
|
||||||
ExternalURL: externalURL,
|
ExternalURL: externalURL,
|
||||||
Value: value,
|
Value: smpl.F,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if smpl.H != nil {
|
||||||
|
res.Value = smpl.H
|
||||||
|
}
|
||||||
|
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
// Funcs adds the functions in fm to the Expander's function map.
|
// Funcs adds the functions in fm to the Expander's function map.
|
||||||
|
|
Loading…
Reference in New Issue