mirror of
https://github.com/prometheus/prometheus.git
synced 2026-05-05 04:16:15 +02:00
[BUGFIX] PromQL: fix more slice indexing bugs in info function (#17199)
* [BUGFIX] PromQL: fix more slice indexing bugs in info function --------- Signed-off-by: Linas Medziunas <linas.medziunas@gmail.com>
This commit is contained in:
parent
05612757b4
commit
20815562d2
@ -55,13 +55,13 @@ func (ev *evaluator) evalInfo(ctx context.Context, args parser.Expressions) (par
|
||||
}
|
||||
|
||||
// Don't try to enrich info series.
|
||||
ignoreSeries := map[int]struct{}{}
|
||||
ignoreSeries := map[uint64]struct{}{}
|
||||
loop:
|
||||
for i, s := range mat {
|
||||
for _, s := range mat {
|
||||
name := s.Metric.Get(labels.MetricName)
|
||||
for _, m := range infoNameMatchers {
|
||||
if m.Matches(name) {
|
||||
ignoreSeries[i] = struct{}{}
|
||||
ignoreSeries[s.Metric.Hash()] = struct{}{}
|
||||
continue loop
|
||||
}
|
||||
}
|
||||
@ -121,11 +121,11 @@ func (ev *evaluator) infoSelectHints(expr parser.Expr) storage.SelectHints {
|
||||
// fetchInfoSeries fetches info series given matching identifying labels in mat.
|
||||
// Series in ignoreSeries are not fetched.
|
||||
// dataLabelMatchers may be mutated.
|
||||
func (ev *evaluator) fetchInfoSeries(ctx context.Context, mat Matrix, ignoreSeries map[int]struct{}, dataLabelMatchers map[string][]*labels.Matcher, selectHints storage.SelectHints) (Matrix, annotations.Annotations, error) {
|
||||
func (ev *evaluator) fetchInfoSeries(ctx context.Context, mat Matrix, ignoreSeries map[uint64]struct{}, dataLabelMatchers map[string][]*labels.Matcher, selectHints storage.SelectHints) (Matrix, annotations.Annotations, error) {
|
||||
// A map of values for all identifying labels we are interested in.
|
||||
idLblValues := map[string]map[string]struct{}{}
|
||||
for i, s := range mat {
|
||||
if _, exists := ignoreSeries[i]; exists {
|
||||
for _, s := range mat {
|
||||
if _, exists := ignoreSeries[s.Metric.Hash()]; exists {
|
||||
continue
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ func (ev *evaluator) fetchInfoSeries(ctx context.Context, mat Matrix, ignoreSeri
|
||||
}
|
||||
|
||||
// combineWithInfoSeries combines mat with select data labels from infoMat.
|
||||
func (ev *evaluator) combineWithInfoSeries(ctx context.Context, mat, infoMat Matrix, ignoreSeries map[int]struct{}, dataLabelMatchers map[string][]*labels.Matcher) (Matrix, annotations.Annotations) {
|
||||
func (ev *evaluator) combineWithInfoSeries(ctx context.Context, mat, infoMat Matrix, ignoreSeries map[uint64]struct{}, dataLabelMatchers map[string][]*labels.Matcher) (Matrix, annotations.Annotations) {
|
||||
buf := make([]byte, 0, 1024)
|
||||
lb := labels.NewScratchBuilder(0)
|
||||
sigFunction := func(name string) func(labels.Labels) string {
|
||||
@ -249,13 +249,13 @@ func (ev *evaluator) combineWithInfoSeries(ctx context.Context, mat, infoMat Mat
|
||||
tempNumSamples := ev.currentSamples
|
||||
|
||||
// For every base series, compute signature per info metric.
|
||||
baseSigs := make([]map[string]string, 0, len(mat))
|
||||
baseSigs := make(map[uint64]map[string]string, len(mat))
|
||||
for _, s := range mat {
|
||||
sigs := make(map[string]string, len(infoMetrics))
|
||||
for infoName := range infoMetrics {
|
||||
sigs[infoName] = sigfs[infoName](s.Metric)
|
||||
}
|
||||
baseSigs = append(baseSigs, sigs)
|
||||
baseSigs[s.Metric.Hash()] = sigs
|
||||
}
|
||||
|
||||
infoSigs := make(map[uint64]string, len(infoMat))
|
||||
@ -331,7 +331,7 @@ func (ev *evaluator) combineWithInfoSeries(ctx context.Context, mat, infoMat Mat
|
||||
|
||||
// combineWithInfoVector combines base and info Vectors.
|
||||
// Base series in ignoreSeries are not combined.
|
||||
func (ev *evaluator) combineWithInfoVector(base, info Vector, ignoreSeries map[int]struct{}, baseSigs []map[string]string, infoSigs map[uint64]string, enh *EvalNodeHelper, dataLabelMatchers map[string][]*labels.Matcher) (Vector, error) {
|
||||
func (ev *evaluator) combineWithInfoVector(base, info Vector, ignoreSeries map[uint64]struct{}, baseSigs map[uint64]map[string]string, infoSigs map[uint64]string, enh *EvalNodeHelper, dataLabelMatchers map[string][]*labels.Matcher) (Vector, error) {
|
||||
if len(base) == 0 {
|
||||
return nil, nil // Short-circuit: nothing is going to match.
|
||||
}
|
||||
@ -370,8 +370,10 @@ func (ev *evaluator) combineWithInfoVector(base, info Vector, ignoreSeries map[i
|
||||
}
|
||||
}
|
||||
|
||||
for i, bs := range base {
|
||||
if _, exists := ignoreSeries[i]; exists {
|
||||
for _, bs := range base {
|
||||
hash := bs.Metric.Hash()
|
||||
|
||||
if _, exists := ignoreSeries[hash]; exists {
|
||||
// This series should not be enriched with info metric data labels.
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: bs.Metric,
|
||||
@ -386,7 +388,7 @@ func (ev *evaluator) combineWithInfoVector(base, info Vector, ignoreSeries map[i
|
||||
|
||||
// For every info metric name, try to find an info series with the same signature.
|
||||
seenInfoMetrics := map[string]struct{}{}
|
||||
for infoName, sig := range baseSigs[i] {
|
||||
for infoName, sig := range baseSigs[hash] {
|
||||
is, exists := enh.rightSigs[sig]
|
||||
if !exists {
|
||||
continue
|
||||
|
||||
25
promql/promqltest/testdata/info.test
vendored
25
promql/promqltest/testdata/info.test
vendored
@ -114,6 +114,8 @@ eval range from 1m to 4m step 1m info(metric offset 1m)
|
||||
|
||||
clear
|
||||
|
||||
# info_metric churn:
|
||||
|
||||
load 1m
|
||||
data_metric{instance="a", job="work"} 10 20 30
|
||||
data_metric{instance="b", job="work"} 11 21 31
|
||||
@ -125,3 +127,26 @@ eval range from 0 to 2m step 1m info(data_metric, {__name__="info_metric"})
|
||||
data_metric{instance="a", job="work", state="running"} 10 20 30
|
||||
data_metric{instance="b", job="work", state="stopped"} 11 21 _
|
||||
data_metric{instance="b", job="work", state="running"} _ _ 31
|
||||
|
||||
clear
|
||||
|
||||
# data_metric churn:
|
||||
|
||||
load 1m
|
||||
data_metric{instance="a", job="work"} 10 20 stale
|
||||
data_metric{instance="b", job="work"} 11 21 31
|
||||
data_metric{instance="a", job="work", label="new"} _ _ 30
|
||||
info_metric{instance="b", job="work", state="stopped"} 1 1 1
|
||||
info_metric{instance="a", job="work", state="running"} 1 1 1
|
||||
|
||||
eval range from 0 to 2m step 1m info(data_metric, {__name__="info_metric"})
|
||||
data_metric{instance="a", job="work", state="running"} 10 20 _
|
||||
data_metric{instance="b", job="work", state="stopped"} 11 21 31
|
||||
data_metric{instance="a", job="work", state="running", label="new"} _ _ 30
|
||||
|
||||
eval range from 0 to 2m step 1m info({job="work"}, {__name__="info_metric"})
|
||||
data_metric{instance="a", job="work", state="running"} 10 20 _
|
||||
data_metric{instance="b", job="work", state="stopped"} 11 21 31
|
||||
data_metric{instance="a", job="work", state="running", label="new"} _ _ 30
|
||||
info_metric{instance="b", job="work", state="stopped"} 1 1 1
|
||||
info_metric{instance="a", job="work", state="running"} 1 1 1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user