Skip to content

Commit 754c104

Browse files
authored
Merge pull request prometheus#15173 from prometheus/merge-2.55-into-main-3
Merge release-2.55 into main (interim)
2 parents 763cbdf + a846bf9 commit 754c104

File tree

3 files changed

+56
-57
lines changed

3 files changed

+56
-57
lines changed

CHANGELOG.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@ As is traditional with a beta release, we do **not** recommend users install 3.0
5151
* [CHANGE] Remove deprecated `remote-write-receiver`,`promql-at-modifier`, and `promql-negative-offset` feature flags. #13456, #14526
5252
* [CHANGE] Remove deprecated `storage.tsdb.allow-overlapping-blocks`, `alertmanager.timeout`, and `storage.tsdb.retention` flags. #14640, #14643
5353
* [ENHANCEMENT] Move AM discovery page from "Monitoring status" to "Server status". #14875
54+
* [FEATURE] Support config reload automatically - feature flag `auto-reload-config`. #14769
5455
* [BUGFIX] Scrape: Do not override target parameter labels with config params. #11029
5556

5657
## 2.55.0-rc.0 / 2024-09-20
5758

5859
* [FEATURE] Support UTF-8 characters in label names - feature flag `utf8-names`. #14482, #14880, #14736, #14727
59-
* [FEATURE] Support config reload automatically - feature flag `auto-reload-config`. #14769
6060
* [FEATURE] Scraping: Add the ability to set custom `http_headers` in config. #14817
6161
* [FEATURE] Scraping: Support feature flag `created-timestamp-zero-ingestion` in OpenMetrics. #14356, #14815
6262
* [FEATURE] Scraping: `scrape_failure_log_file` option to log failures to a file. #14734
@@ -69,7 +69,7 @@ As is traditional with a beta release, we do **not** recommend users install 3.0
6969
* [ENHANCEMENT] Remote Read client: Enable streaming remote read if the server supports it. #11379
7070
* [ENHANCEMENT] Remote-Write: Don't reshard if we haven't successfully sent a sample since last update. #14450
7171
* [ENHANCEMENT] PromQL: Delay deletion of `__name__` label to the end of the query evaluation. This is **experimental** and enabled under the feature-flag `promql-delayed-name-removal`. #14477
72-
* [ENHANCEMENT] PromQL: Experimental `sort_by_label` and `sort_by_label_desc` sort by all labels when label is equal. #14655
72+
* [ENHANCEMENT] PromQL: Experimental `sort_by_label` and `sort_by_label_desc` sort by all labels when label is equal. #14655, #14985
7373
* [ENHANCEMENT] PromQL: Clarify error message logged when Go runtime panic occurs during query evaluation. #14621
7474
* [ENHANCEMENT] PromQL: Use Kahan summation for better accuracy in `avg` and `avg_over_time`. #14413
7575
* [ENHANCEMENT] Tracing: Improve PromQL tracing, including showing the operation performed for aggregates, operators, and calls. #14816

promql/engine.go

+46-29
Original file line numberDiff line numberDiff line change
@@ -1230,38 +1230,17 @@ func (ev *evaluator) rangeEval(ctx context.Context, prepSeries func(labels.Label
12301230
ev.currentSamples = tempNumSamples
12311231
// Gather input vectors for this timestamp.
12321232
for i := range exprs {
1233-
vectors[i] = vectors[i][:0]
1234-
1233+
var bh []EvalSeriesHelper
1234+
var sh []EvalSeriesHelper
12351235
if prepSeries != nil {
1236-
bufHelpers[i] = bufHelpers[i][:0]
1237-
}
1238-
1239-
for si, series := range matrixes[i] {
1240-
switch {
1241-
case len(series.Floats) > 0 && series.Floats[0].T == ts:
1242-
vectors[i] = append(vectors[i], Sample{Metric: series.Metric, F: series.Floats[0].F, T: ts, DropName: series.DropName})
1243-
// Move input vectors forward so we don't have to re-scan the same
1244-
// past points at the next step.
1245-
matrixes[i][si].Floats = series.Floats[1:]
1246-
case len(series.Histograms) > 0 && series.Histograms[0].T == ts:
1247-
vectors[i] = append(vectors[i], Sample{Metric: series.Metric, H: series.Histograms[0].H, T: ts, DropName: series.DropName})
1248-
matrixes[i][si].Histograms = series.Histograms[1:]
1249-
default:
1250-
continue
1251-
}
1252-
if prepSeries != nil {
1253-
bufHelpers[i] = append(bufHelpers[i], seriesHelpers[i][si])
1254-
}
1255-
// Don't add histogram size here because we only
1256-
// copy the pointer above, not the whole
1257-
// histogram.
1258-
ev.currentSamples++
1259-
if ev.currentSamples > ev.maxSamples {
1260-
ev.error(ErrTooManySamples(env))
1261-
}
1236+
bh = bufHelpers[i][:0]
1237+
sh = seriesHelpers[i]
12621238
}
1239+
vectors[i], bh = ev.gatherVector(ts, matrixes[i], vectors[i], bh, sh)
12631240
args[i] = vectors[i]
1264-
ev.samplesStats.UpdatePeak(ev.currentSamples)
1241+
if prepSeries != nil {
1242+
bufHelpers[i] = bh
1243+
}
12651244
}
12661245

12671246
// Make the function call.
@@ -3724,3 +3703,41 @@ func newHistogramStatsSeries(series storage.Series) *histogramStatsSeries {
37243703
func (s histogramStatsSeries) Iterator(it chunkenc.Iterator) chunkenc.Iterator {
37253704
return NewHistogramStatsIterator(s.Series.Iterator(it))
37263705
}
3706+
3707+
// gatherVector gathers a Vector for ts from the series in input.
3708+
// output is used as a buffer.
3709+
// If bufHelpers and seriesHelpers are provided, seriesHelpers[i] is appended to bufHelpers for every input index i.
3710+
// The gathered Vector and bufHelper are returned.
3711+
func (ev *evaluator) gatherVector(ts int64, input Matrix, output Vector, bufHelpers, seriesHelpers []EvalSeriesHelper) (Vector, []EvalSeriesHelper) {
3712+
output = output[:0]
3713+
for i, series := range input {
3714+
switch {
3715+
case len(series.Floats) > 0 && series.Floats[0].T == ts:
3716+
s := series.Floats[0]
3717+
output = append(output, Sample{Metric: series.Metric, F: s.F, T: ts, DropName: series.DropName})
3718+
// Move input vectors forward so we don't have to re-scan the same
3719+
// past points at the next step.
3720+
input[i].Floats = series.Floats[1:]
3721+
case len(series.Histograms) > 0 && series.Histograms[0].T == ts:
3722+
s := series.Histograms[0]
3723+
output = append(output, Sample{Metric: series.Metric, H: s.H, T: ts, DropName: series.DropName})
3724+
input[i].Histograms = series.Histograms[1:]
3725+
default:
3726+
continue
3727+
}
3728+
if len(seriesHelpers) > 0 {
3729+
bufHelpers = append(bufHelpers, seriesHelpers[i])
3730+
}
3731+
3732+
// Don't add histogram size here because we only
3733+
// copy the pointer above, not the whole
3734+
// histogram.
3735+
ev.currentSamples++
3736+
if ev.currentSamples > ev.maxSamples {
3737+
ev.error(ErrTooManySamples(env))
3738+
}
3739+
}
3740+
ev.samplesStats.UpdatePeak(ev.currentSamples)
3741+
3742+
return output, bufHelpers
3743+
}

promql/functions.go

+8-26
Original file line numberDiff line numberDiff line change
@@ -415,22 +415,12 @@ func funcSortDesc(vals []parser.Value, args parser.Expressions, enh *EvalNodeHel
415415

416416
// === sort_by_label(vector parser.ValueTypeVector, label parser.ValueTypeString...) (Vector, Annotations) ===
417417
func funcSortByLabel(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
418-
// First, sort by the full label set. This ensures a consistent ordering in case sorting by the
419-
// labels provided as arguments is not conclusive.
418+
lbls := stringSliceFromArgs(args[1:])
420419
slices.SortFunc(vals[0].(Vector), func(a, b Sample) int {
421-
return labels.Compare(a.Metric, b.Metric)
422-
})
423-
424-
labels := stringSliceFromArgs(args[1:])
425-
// Next, sort by the labels provided as arguments.
426-
slices.SortFunc(vals[0].(Vector), func(a, b Sample) int {
427-
// Iterate over each given label.
428-
for _, label := range labels {
420+
for _, label := range lbls {
429421
lv1 := a.Metric.Get(label)
430422
lv2 := b.Metric.Get(label)
431423

432-
// If we encounter multiple samples with the same label values, the sorting which was
433-
// performed in the first step will act as a "tie breaker".
434424
if lv1 == lv2 {
435425
continue
436426
}
@@ -442,30 +432,21 @@ func funcSortByLabel(vals []parser.Value, args parser.Expressions, enh *EvalNode
442432
return +1
443433
}
444434

445-
return 0
435+
// If all labels provided as arguments were equal, sort by the full label set. This ensures a consistent ordering.
436+
return labels.Compare(a.Metric, b.Metric)
446437
})
447438

448439
return vals[0].(Vector), nil
449440
}
450441

451442
// === sort_by_label_desc(vector parser.ValueTypeVector, label parser.ValueTypeString...) (Vector, Annotations) ===
452443
func funcSortByLabelDesc(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
453-
// First, sort by the full label set. This ensures a consistent ordering in case sorting by the
454-
// labels provided as arguments is not conclusive.
455-
slices.SortFunc(vals[0].(Vector), func(a, b Sample) int {
456-
return labels.Compare(b.Metric, a.Metric)
457-
})
458-
459-
labels := stringSliceFromArgs(args[1:])
460-
// Next, sort by the labels provided as arguments.
444+
lbls := stringSliceFromArgs(args[1:])
461445
slices.SortFunc(vals[0].(Vector), func(a, b Sample) int {
462-
// Iterate over each given label.
463-
for _, label := range labels {
446+
for _, label := range lbls {
464447
lv1 := a.Metric.Get(label)
465448
lv2 := b.Metric.Get(label)
466449

467-
// If we encounter multiple samples with the same label values, the sorting which was
468-
// performed in the first step will act as a "tie breaker".
469450
if lv1 == lv2 {
470451
continue
471452
}
@@ -477,7 +458,8 @@ func funcSortByLabelDesc(vals []parser.Value, args parser.Expressions, enh *Eval
477458
return -1
478459
}
479460

480-
return 0
461+
// If all labels provided as arguments were equal, sort by the full label set. This ensures a consistent ordering.
462+
return -labels.Compare(a.Metric, b.Metric)
481463
})
482464

483465
return vals[0].(Vector), nil

0 commit comments

Comments
 (0)