Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Slo filter metrics #405

Merged
merged 10 commits into from
Jul 27, 2022
50 changes: 25 additions & 25 deletions pkg/apis/management/v1/management.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions pkg/slo/query/def.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func init() {
GoodQuery(
NewQueryBuilder().
Query(`
sum(rate({{.MetricIdGood}}{job="{{.JobId}},"le="0.3",verb!="WATCH"} [{{"{{window}}"}}]))
sum(rate({{.MetricIdGood}}{job="{{.JobId}},"le="0.3",verb!="WATCH"}[{{"{{.window}}"}}]))
`).
MetricFilter(`.*http_request_duration_seconds_bucket`).
BuildHistogram()).
Expand Down Expand Up @@ -133,7 +133,7 @@ type MetricQuery interface {
Description() string
// Each metric has a unique opni datasource (monitoring vs logging) by which it is filtered by
Datasource() string
Construct(*api.Service) (*SLOQueryResult, error)
Construct(*api.ServiceInfo) (*SLOQueryResult, error)
// Some metrics will have different labels for metrics, so handle them independently
GetGoodQuery() Query
GetTotalQuery() Query
Expand All @@ -152,7 +152,7 @@ type Query interface {
IsRatio() bool
BestMatch([]string) string
IsHistogram() bool
Construct(*api.Service) (string, error)
Construct(*api.ServiceInfo) (string, error)
}

type QueryBuilder interface {
Expand Down
2 changes: 1 addition & 1 deletion pkg/slo/query/histogram.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (h HistogramQuery) IsHistogram() bool {
return true
}

func (h HistogramQuery) Construct(serv *api.Service) (string, error) {
func (h HistogramQuery) Construct(serv *api.ServiceInfo) (string, error) {
return h.FillQueryTemplate(templateExecutor{
MetricIdGood: serv.MetricIdGood,
MetricIdTotal: serv.MetricIdTotal,
Expand Down
2 changes: 1 addition & 1 deletion pkg/slo/query/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type PrometheusQueryImpl struct {
}

// The actual metricId and window are only known at SLO creation time
func (p *PrometheusQueryImpl) Construct(service *api.Service) (*SLOQueryResult, error) {
func (p *PrometheusQueryImpl) Construct(service *api.ServiceInfo) (*SLOQueryResult, error) {
goodQueryStr, err := p.GoodQuery.Construct(service)
if err != nil {
return nil, err
Expand Down
30 changes: 22 additions & 8 deletions pkg/slo/query/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import (
api "github.com/rancher/opni/plugins/slo/pkg/apis/slo"
)

func constructionShouldSucceed(q *query.SLOQueryResult, err error) {
Expect(err).To(Succeed())
Expect(q).To(Not(BeNil()))
Expect(q.GoodQuery).To(Not(BeNil()))
Expect(q.TotalQuery).To(Not(BeNil()))
}

var _ = Describe("Converting ServiceLevelObjective Messages to Prometheus Rules", Ordered, Label(test.Unit, test.Slow), func() {
// ctx := context.Background()

Expand Down Expand Up @@ -42,20 +49,27 @@ var _ = Describe("Converting ServiceLevelObjective Messages to Prometheus Rules"
It("Should fill in the templates & return a response struct", func() {
uptime, ok := query.AvailableQueries["uptime"]
Expect(ok).To(BeTrue())
service := &api.Service{
service := &api.ServiceInfo{
JobId: "prometheus",
MetricName: "uptime",
MetricIdGood: "up",
MetricIdTotal: "up",
ClusterId: "agent",
}
resp, err := uptime.Construct(service)
Expect(err).To(Succeed())
Expect(resp).To(Not(BeNil()))
Expect(resp.GoodQuery).To(Not(BeNil()))
Expect(resp.TotalQuery).To(Not(BeNil()))
Expect(resp.GoodQuery).To(Equal("(sum(rate(up{job=\"prometheus\"} == 1)))[{{.window}}]"))
Expect(resp.TotalQuery).To(Equal("(sum(rate(up{job=\"prometheus\"})))[{{.window}}]"))
respUp, err := uptime.Construct(service)
constructionShouldSucceed(respUp, err)
Expect(respUp.GoodQuery).To(Equal("(sum(rate(up{job=\"prometheus\"} == 1)))[{{.window}}]"))
Expect(respUp.TotalQuery).To(Equal("(sum(rate(up{job=\"prometheus\"})))[{{.window}}]"))

latency, ok := query.AvailableQueries["http-latency"]
Expect(ok).To(BeTrue())
respLa, err := latency.Construct(service)
constructionShouldSucceed(respLa, err)

availability, ok := query.AvailableQueries["http-availability"]
Expect(ok).To(BeTrue())
respAv, err := availability.Construct(service)
constructionShouldSucceed(respAv, err)

})
})
Expand Down
2 changes: 1 addition & 1 deletion pkg/slo/query/ratio.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (r RatioQuery) IsHistogram() bool {
return false
}

func (r RatioQuery) Construct(serv *api.Service) (string, error) {
func (r RatioQuery) Construct(serv *api.ServiceInfo) (string, error) {
return r.FillQueryTemplate(templateExecutor{
MetricIdGood: serv.MetricIdGood,
MetricIdTotal: serv.MetricIdTotal,
Expand Down
7 changes: 5 additions & 2 deletions pkg/slo/shared/shared.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ import (
var (
lengthConstraint = func(i int) string { return fmt.Sprintf("must be between 1-%d characters in length", i) }
ErrMissingServices = validation.Error("Service definitions are required to create an SLO")
ErrInvalidMonitorWindow = validation.Error("Invalid monitor window")
ErrInvalidBudgetingInterval = validation.Error("Invalid budgeting interval")
ErrInvalidMonitorWindow = validation.Error("Invalid `monitorWindow` in the body of the request")
ErrInvalidTarget = validation.Error("Invalid `target` in the body of the request")
ErrInvalidBudgetingInterval = validation.Error("Invalid `budgetingInterval` in the body of the request : Must be between 1m & 1h")
ErrInvalidMetricName = validation.Error("Invalid `metricName` in the body of the request")
ErrInvalidDescription = validation.Errorf("Description %s", lengthConstraint(1050))
ErrInvalidMetric = validation.Error("Invalid preconfigured metric")
ErrInvalidAlertType = validation.Error("Invalid alert type")
ErrInvalidAlertCondition = validation.Error("Invalid Alert Condition")
ErrInvalidAlertThreshold = validation.Error("Invalid Alert Threshold")
ErrInvalidAlertTarget = validation.Error("Invalid Alert Target")
ErrMissingServiceInfo = validation.Error("Service job & cluster id are required to create an SLO")
ErrNonNullId = WithInternalServerError("Slo Create requests must not have a set id")
ErrPrometheusGenerator = WithInternalServerError("Prometheus generator failed to start")
ErrInvalidDatasource = WithNotFoundError("Invalid required datasource value")
Expand Down
Loading