|
|
|
@ -19,7 +19,9 @@ import (
|
|
|
|
|
"encoding/json" |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"github.com/go-kit/kit/log" |
|
|
|
|
"io/ioutil" |
|
|
|
|
stdlog "log" |
|
|
|
|
"math" |
|
|
|
|
"net/http" |
|
|
|
|
"net/http/httptest" |
|
|
|
@ -41,9 +43,11 @@ import (
|
|
|
|
|
"github.com/prometheus/prometheus/pkg/timestamp" |
|
|
|
|
"github.com/prometheus/prometheus/prompb" |
|
|
|
|
"github.com/prometheus/prometheus/promql" |
|
|
|
|
"github.com/prometheus/prometheus/rules" |
|
|
|
|
"github.com/prometheus/prometheus/scrape" |
|
|
|
|
"github.com/prometheus/prometheus/storage" |
|
|
|
|
"github.com/prometheus/prometheus/storage/remote" |
|
|
|
|
"github.com/prometheus/prometheus/util/testutil" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
type testTargetRetriever struct{} |
|
|
|
@ -98,6 +102,68 @@ func (t testAlertmanagerRetriever) DroppedAlertmanagers() []*url.URL {
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
type testalertsrulesfunc struct { |
|
|
|
|
test *testing.T |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (t testalertsrulesfunc) AlertingRules() []*rules.AlertingRule { |
|
|
|
|
expr1, err := promql.ParseExpr(`absent(test_metric3) != 1`) |
|
|
|
|
if err != nil { |
|
|
|
|
stdlog.Fatalf("Unable to parse alert expression: %s", err) |
|
|
|
|
} |
|
|
|
|
expr2, err := promql.ParseExpr(`up == 1`) |
|
|
|
|
if err != nil { |
|
|
|
|
stdlog.Fatalf("Unable to parse alert expression: %s", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
rule1 := rules.NewAlertingRule( |
|
|
|
|
"test_metric3", |
|
|
|
|
expr1, |
|
|
|
|
time.Second, |
|
|
|
|
labels.Labels{}, |
|
|
|
|
labels.Labels{}, |
|
|
|
|
log.NewNopLogger(), |
|
|
|
|
) |
|
|
|
|
rule2 := rules.NewAlertingRule( |
|
|
|
|
"test_metric4", |
|
|
|
|
expr2, |
|
|
|
|
time.Second, |
|
|
|
|
labels.Labels{}, |
|
|
|
|
labels.Labels{}, |
|
|
|
|
log.NewNopLogger(), |
|
|
|
|
) |
|
|
|
|
var r []*rules.AlertingRule |
|
|
|
|
r = append(r, rule1) |
|
|
|
|
r = append(r, rule2) |
|
|
|
|
return r |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (t testalertsrulesfunc) RuleGroups() []*rules.Group { |
|
|
|
|
var ar testalertsrulesfunc |
|
|
|
|
arules := ar.AlertingRules() |
|
|
|
|
storage := testutil.NewStorage(t.test) |
|
|
|
|
defer storage.Close() |
|
|
|
|
|
|
|
|
|
engine := promql.NewEngine(nil, nil, 10, 10*time.Second) |
|
|
|
|
opts := &rules.ManagerOptions{ |
|
|
|
|
QueryFunc: rules.EngineQueryFunc(engine, storage), |
|
|
|
|
Appendable: storage, |
|
|
|
|
Context: context.Background(), |
|
|
|
|
Logger: log.NewNopLogger(), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var r []rules.Rule |
|
|
|
|
|
|
|
|
|
for _, alertrule := range arules { |
|
|
|
|
r = append(r, alertrule) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
group := rules.NewGroup("grp", "/path/to/file", time.Second, r, opts) |
|
|
|
|
fmt.Println(group) |
|
|
|
|
return []*rules.Group{group} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var samplePrometheusCfg = config.Config{ |
|
|
|
|
GlobalConfig: config.GlobalConfig{}, |
|
|
|
|
AlertingConfig: config.AlertingConfig{}, |
|
|
|
@ -131,15 +197,24 @@ func TestEndpoints(t *testing.T) {
|
|
|
|
|
now := time.Now() |
|
|
|
|
|
|
|
|
|
t.Run("local", func(t *testing.T) { |
|
|
|
|
|
|
|
|
|
var algr testalertsrulesfunc |
|
|
|
|
algr.test = t |
|
|
|
|
|
|
|
|
|
algr.AlertingRules() |
|
|
|
|
|
|
|
|
|
algr.RuleGroups() |
|
|
|
|
|
|
|
|
|
api := &API{ |
|
|
|
|
Queryable: suite.Storage(), |
|
|
|
|
QueryEngine: suite.QueryEngine(), |
|
|
|
|
targetRetriever: testTargetRetriever{}, |
|
|
|
|
alertmanagerRetriever: testAlertmanagerRetriever{}, |
|
|
|
|
now: func() time.Time { return now }, |
|
|
|
|
config: func() config.Config { return samplePrometheusCfg }, |
|
|
|
|
flagsMap: sampleFlagMap, |
|
|
|
|
ready: func(f http.HandlerFunc) http.HandlerFunc { return f }, |
|
|
|
|
now: func() time.Time { return now }, |
|
|
|
|
config: func() config.Config { return samplePrometheusCfg }, |
|
|
|
|
flagsMap: sampleFlagMap, |
|
|
|
|
ready: func(f http.HandlerFunc) http.HandlerFunc { return f }, |
|
|
|
|
alertsrulesRetreiver: algr, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
testEndpoints(t, api, true) |
|
|
|
@ -176,15 +251,23 @@ func TestEndpoints(t *testing.T) {
|
|
|
|
|
t.Fatal(err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var algr testalertsrulesfunc |
|
|
|
|
algr.test = t |
|
|
|
|
|
|
|
|
|
algr.AlertingRules() |
|
|
|
|
|
|
|
|
|
algr.RuleGroups() |
|
|
|
|
|
|
|
|
|
api := &API{ |
|
|
|
|
Queryable: remote, |
|
|
|
|
QueryEngine: suite.QueryEngine(), |
|
|
|
|
targetRetriever: testTargetRetriever{}, |
|
|
|
|
alertmanagerRetriever: testAlertmanagerRetriever{}, |
|
|
|
|
now: func() time.Time { return now }, |
|
|
|
|
config: func() config.Config { return samplePrometheusCfg }, |
|
|
|
|
flagsMap: sampleFlagMap, |
|
|
|
|
ready: func(f http.HandlerFunc) http.HandlerFunc { return f }, |
|
|
|
|
now: func() time.Time { return now }, |
|
|
|
|
config: func() config.Config { return samplePrometheusCfg }, |
|
|
|
|
flagsMap: sampleFlagMap, |
|
|
|
|
ready: func(f http.HandlerFunc) http.HandlerFunc { return f }, |
|
|
|
|
alertsrulesRetreiver: algr, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
testEndpoints(t, api, false) |
|
|
|
@ -237,7 +320,6 @@ func setupRemote(s storage.Storage) *httptest.Server {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func testEndpoints(t *testing.T, api *API, testLabelAPI bool) { |
|
|
|
|
|
|
|
|
|
start := time.Unix(0, 0) |
|
|
|
|
|
|
|
|
|
type test struct { |
|
|
|
@ -567,6 +649,46 @@ func testEndpoints(t *testing.T, api *API, testLabelAPI bool) {
|
|
|
|
|
endpoint: api.serveFlags, |
|
|
|
|
response: sampleFlagMap, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
endpoint: api.alerts, |
|
|
|
|
response: &AlertDiscovery{ |
|
|
|
|
Alertgrps: []*Alertgrp{ |
|
|
|
|
{ |
|
|
|
|
Name: "test_metric3", |
|
|
|
|
Query: "absent(test_metric3) != 1", |
|
|
|
|
Duration: "1s", |
|
|
|
|
Alerts: nil, |
|
|
|
|
Annotations: labels.Labels{}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
Name: "test_metric4", |
|
|
|
|
Query: "up == 1", |
|
|
|
|
Duration: "1s", |
|
|
|
|
Alerts: nil, |
|
|
|
|
Annotations: labels.Labels{}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
endpoint: api.rules, |
|
|
|
|
response: &GroupDiscovery{ |
|
|
|
|
Rulegrps: []*Rulegrp{ |
|
|
|
|
{ |
|
|
|
|
Name: "grp", |
|
|
|
|
File: "/path/to/file", |
|
|
|
|
Rules: []*Ruleinfo{ |
|
|
|
|
{ |
|
|
|
|
Rule: "alert: test_metric3\nexpr: absent(test_metric3) != 1\nfor: 1s\n", |
|
|
|
|
}, |
|
|
|
|
{ |
|
|
|
|
Rule: "alert: test_metric4\nexpr: up == 1\nfor: 1s\n", |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if testLabelAPI { |
|
|
|
|