From 22820280c79c377191b48ac664d90ead508bb56b Mon Sep 17 00:00:00 2001 From: Eduard Zernaev Date: Sat, 20 Apr 2024 13:11:32 +0300 Subject: [PATCH] VM Backend for prom proxy --- Dockerfile | 4 ++-- Makefile | 3 ++- Makefile.common | 2 +- rules/alerting.go | 48 +++++++++++++++++++++++++++++++++++++++++++--- rules/recording.go | 35 +++++++++++++++++++++++++++++---- 5 files changed, 81 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index b47f77dcd69..d643cac1e30 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,9 +1,9 @@ -ARG ARCH="amd64" +ARG ARCH="arm64" ARG OS="linux" FROM quay.io/prometheus/busybox-${OS}-${ARCH}:latest LABEL maintainer="The Prometheus Authors " -ARG ARCH="amd64" +ARG ARCH="arm64" ARG OS="linux" COPY .build/${OS}-${ARCH}/prometheus /bin/prometheus COPY .build/${OS}-${ARCH}/promtool /bin/promtool diff --git a/Makefile b/Makefile index 61e8f4377cd..59a1f3a61c3 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,8 @@ # limitations under the License. # Needs to be defined before including Makefile.common to auto-generate targets -DOCKER_ARCHS ?= amd64 armv7 arm64 ppc64le s390x +#DOCKER_ARCHS ?= amd64 armv7 arm64 ppc64le s390x +DOCKER_ARCHS ?= arm64 UI_PATH = web/ui UI_NODE_MODULES_PATH = $(UI_PATH)/node_modules diff --git a/Makefile.common b/Makefile.common index 0acfb9d8063..c6c45c058c4 100644 --- a/Makefile.common +++ b/Makefile.common @@ -85,7 +85,7 @@ DOCKERFILE_PATH ?= ./Dockerfile DOCKERBUILD_CONTEXT ?= ./ DOCKER_REPO ?= prom -DOCKER_ARCHS ?= amd64 +DOCKER_ARCHS ?= arm64 BUILD_DOCKER_ARCHS = $(addprefix common-docker-,$(DOCKER_ARCHS)) PUBLISH_DOCKER_ARCHS = $(addprefix common-docker-publish-,$(DOCKER_ARCHS)) diff --git a/rules/alerting.go b/rules/alerting.go index 50c67fa2d92..08a34fc66c1 100644 --- a/rules/alerting.go +++ b/rules/alerting.go @@ -20,13 +20,14 @@ import ( "strings" "sync" "time" - + "os" "github.com/go-kit/log" "github.com/go-kit/log/level" "github.com/prometheus/common/model" "go.uber.org/atomic" "gopkg.in/yaml.v2" - + apic "github.com/prometheus/client_golang/api" + v1 "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/rulefmt" "github.com/prometheus/prometheus/model/timestamp" @@ -342,12 +343,53 @@ func (r *AlertingRule) NoDependencyRules() bool { // is kept in memory state and consequently repeatedly sent to the AlertManager. const resolvedRetention = 15 * time.Minute +func modelToPromql(mv model.Vector) promql.Vector { + var vec promql.Vector + var lbss labels.Labels + for _, m := range mv { + + lbs := labels.NewBuilder(lbss) + for n, v := range m.Metric { + lbs.Set(string(n), string(v)) + } + vec = append(vec, promql.Sample{Metric: lbs.Labels(), T: int64(m.Timestamp), F: float64(m.V +alue)}) + } + return vec +} + +func vmQueryAlerting(ctx context.Context, rule *AlertingRule, ts time.Time) (promql.Vector, error) { + vmURL, ok := os.LookupEnv("VMSELECT_URL") + if !ok { + level.Warn(rule.logger).Log("FATAL: evironment variable VMSELECT_URL doesn't exists") + os.Exit(-1) + } + client, err := apic.NewClient(apic.Config{Address: vmURL}) + if err != nil { + return nil, err + } + + //stime := time.Now() + queryAPI := v1.NewAPI(client) + //fmt.Println("Evaluating:", time.Since(stime), rule.vector.String()) + value, _, err := queryAPI.Query(context.Background(), rule.vector.String(), time.Now()) + if err != nil { + return nil, err + } + + if _, ok := value.(model.Vector); !ok { + err := fmt.Errorf("returned value is not a vector") + return nil, err + } + return modelToPromql(value.(model.Vector)), nil +} + // Eval evaluates the rule expression and then creates pending alerts and fires // or removes previously pending alerts accordingly. func (r *AlertingRule) Eval(ctx context.Context, ts time.Time, query QueryFunc, externalURL *url.URL, limit int) (promql.Vector, error) { ctx = NewOriginContext(ctx, NewRuleDetail(r)) - res, err := query(ctx, r.vector.String(), ts) + res, err := vmQueryAlerting(ctx, r, ts) if err != nil { return nil, err } diff --git a/rules/recording.go b/rules/recording.go index e2b0a31a032..b71b2911dbc 100644 --- a/rules/recording.go +++ b/rules/recording.go @@ -18,10 +18,12 @@ import ( "fmt" "net/url" "time" - + "os" "go.uber.org/atomic" "gopkg.in/yaml.v2" - + "github.com/prometheus/common/model" + apic "github.com/prometheus/client_golang/api" + v1 "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/model/rulefmt" "github.com/prometheus/prometheus/promql" @@ -76,11 +78,36 @@ func (rule *RecordingRule) Labels() labels.Labels { return rule.labels } +func vmQueryRecording(ctx context.Context, rule *RecordingRule, ts time.Time) (promql.Vector, error) { + vmURL, ok := os.LookupEnv("VMSELECT_URL") + if !ok { + fmt.Println("FATAL: please specify VMSELECT_URL to run rules against to") + os.Exit(-1) + } + client, err := apic.NewClient(apic.Config{Address: vmURL}) + if err != nil { + return nil, err + } + + //stime := time.Now() + queryAPI := v1.NewAPI(client) + //fmt.Println("Evaluating:", time.Since(stime), rule.vector.String()) + value, _, err := queryAPI.Query(context.Background(), rule.vector.String(), time.Now()) + if err != nil { + return nil, err + } + + if _, ok := value.(model.Vector); !ok { + err := fmt.Errorf("returned value is not a vector") + return nil, err + } + return modelToPromql(value.(model.Vector)), nil +} + // Eval evaluates the rule and then overrides the metric names and labels accordingly. func (rule *RecordingRule) Eval(ctx context.Context, ts time.Time, query QueryFunc, _ *url.URL, limit int) (promql.Vector, error) { ctx = NewOriginContext(ctx, NewRuleDetail(rule)) - - vector, err := query(ctx, rule.vector.String(), ts) + vector, err := vmQueryRecording(ctx, rule, ts) if err != nil { return nil, err }