mirror of
https://github.com/prometheus/prometheus.git
synced 2025-01-26 13:11:11 -08:00
Ensure metric name is present on histogram_quantile annotations (#15828)
Some checks are pending
buf.build / lint and publish (push) Waiting to run
CI / Go tests (push) Waiting to run
CI / More Go tests (push) Waiting to run
CI / Go tests with previous Go version (push) Waiting to run
CI / UI tests (push) Waiting to run
CI / Go tests on Windows (push) Waiting to run
CI / Mixins tests (push) Waiting to run
CI / Build Prometheus for common architectures (0) (push) Waiting to run
CI / Build Prometheus for common architectures (1) (push) Waiting to run
CI / Build Prometheus for common architectures (2) (push) Waiting to run
CI / Build Prometheus for all architectures (0) (push) Waiting to run
CI / Build Prometheus for all architectures (1) (push) Waiting to run
CI / Build Prometheus for all architectures (10) (push) Waiting to run
CI / Build Prometheus for all architectures (11) (push) Waiting to run
CI / Build Prometheus for all architectures (2) (push) Waiting to run
CI / Build Prometheus for all architectures (3) (push) Waiting to run
CI / Build Prometheus for all architectures (4) (push) Waiting to run
CI / Build Prometheus for all architectures (5) (push) Waiting to run
CI / Build Prometheus for all architectures (6) (push) Waiting to run
CI / Build Prometheus for all architectures (7) (push) Waiting to run
CI / Build Prometheus for all architectures (8) (push) Waiting to run
CI / Build Prometheus for all architectures (9) (push) Waiting to run
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
CI / Check generated parser (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / fuzzing (push) Waiting to run
CI / codeql (push) Waiting to run
CI / Publish main branch artifacts (push) Blocked by required conditions
CI / Publish release artefacts (push) Blocked by required conditions
CI / Publish UI on npm Registry (push) Blocked by required conditions
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Some checks are pending
buf.build / lint and publish (push) Waiting to run
CI / Go tests (push) Waiting to run
CI / More Go tests (push) Waiting to run
CI / Go tests with previous Go version (push) Waiting to run
CI / UI tests (push) Waiting to run
CI / Go tests on Windows (push) Waiting to run
CI / Mixins tests (push) Waiting to run
CI / Build Prometheus for common architectures (0) (push) Waiting to run
CI / Build Prometheus for common architectures (1) (push) Waiting to run
CI / Build Prometheus for common architectures (2) (push) Waiting to run
CI / Build Prometheus for all architectures (0) (push) Waiting to run
CI / Build Prometheus for all architectures (1) (push) Waiting to run
CI / Build Prometheus for all architectures (10) (push) Waiting to run
CI / Build Prometheus for all architectures (11) (push) Waiting to run
CI / Build Prometheus for all architectures (2) (push) Waiting to run
CI / Build Prometheus for all architectures (3) (push) Waiting to run
CI / Build Prometheus for all architectures (4) (push) Waiting to run
CI / Build Prometheus for all architectures (5) (push) Waiting to run
CI / Build Prometheus for all architectures (6) (push) Waiting to run
CI / Build Prometheus for all architectures (7) (push) Waiting to run
CI / Build Prometheus for all architectures (8) (push) Waiting to run
CI / Build Prometheus for all architectures (9) (push) Waiting to run
CI / Report status of build Prometheus for all architectures (push) Blocked by required conditions
CI / Check generated parser (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / fuzzing (push) Waiting to run
CI / codeql (push) Waiting to run
CI / Publish main branch artifacts (push) Blocked by required conditions
CI / Publish release artefacts (push) Blocked by required conditions
CI / Publish UI on npm Registry (push) Blocked by required conditions
Scorecards supply-chain security / Scorecards analysis (push) Waiting to run
Ensure metric name is present on histogram_quantile annotations Previously the series __name__ label was dropped before the annotation was emitted causing the annotation message to have a blank value. This fix also allows delayed name removal for classic histograms. This also adds a test for malformed le label This annotation could be split into two to be clearer for the user (one for missing, and one for malformed). This is outside of the scope of this change. Fixes: #15411 --------- Signed-off-by: Joshua Hesketh <josh@nitrotech.org> Signed-off-by: Björn Rabenstein <github@rabenste.in> Co-authored-by: Björn Rabenstein <github@rabenste.in>
This commit is contained in:
parent
e8fab32ca2
commit
665d1ba0cc
|
@ -3482,6 +3482,81 @@ func TestRateAnnotations(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestHistogramQuantileAnnotations(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
data string
|
||||
expr string
|
||||
expectedWarningAnnotations []string
|
||||
expectedInfoAnnotations []string
|
||||
}{
|
||||
"info annotation for nonmonotonic buckets": {
|
||||
data: `
|
||||
nonmonotonic_bucket{le="0.1"} 0+2x10
|
||||
nonmonotonic_bucket{le="1"} 0+1x10
|
||||
nonmonotonic_bucket{le="10"} 0+5x10
|
||||
nonmonotonic_bucket{le="100"} 0+4x10
|
||||
nonmonotonic_bucket{le="1000"} 0+9x10
|
||||
nonmonotonic_bucket{le="+Inf"} 0+8x10
|
||||
`,
|
||||
expr: "histogram_quantile(0.5, nonmonotonic_bucket)",
|
||||
expectedWarningAnnotations: []string{},
|
||||
expectedInfoAnnotations: []string{
|
||||
`PromQL info: input to histogram_quantile needed to be fixed for monotonicity (see https://prometheus.io/docs/prometheus/latest/querying/functions/#histogram_quantile) for metric name "nonmonotonic_bucket" (1:25)`,
|
||||
},
|
||||
},
|
||||
"warning annotation for missing le label": {
|
||||
data: `
|
||||
myHistogram{abe="0.1"} 0+2x10
|
||||
`,
|
||||
expr: "histogram_quantile(0.5, myHistogram)",
|
||||
expectedWarningAnnotations: []string{
|
||||
`PromQL warning: bucket label "le" is missing or has a malformed value of "" for metric name "myHistogram" (1:25)`,
|
||||
},
|
||||
expectedInfoAnnotations: []string{},
|
||||
},
|
||||
"warning annotation for malformed le label": {
|
||||
data: `
|
||||
myHistogram{le="Hello World"} 0+2x10
|
||||
`,
|
||||
expr: "histogram_quantile(0.5, myHistogram)",
|
||||
expectedWarningAnnotations: []string{
|
||||
`PromQL warning: bucket label "le" is missing or has a malformed value of "Hello World" for metric name "myHistogram" (1:25)`,
|
||||
},
|
||||
expectedInfoAnnotations: []string{},
|
||||
},
|
||||
"warning annotation for mixed histograms": {
|
||||
data: `
|
||||
mixedHistogram{le="0.1"} 0+2x10
|
||||
mixedHistogram{le="1"} 0+3x10
|
||||
mixedHistogram{} {{schema:0 count:10 sum:50 buckets:[1 2 3]}}
|
||||
`,
|
||||
expr: "histogram_quantile(0.5, mixedHistogram)",
|
||||
expectedWarningAnnotations: []string{
|
||||
`PromQL warning: vector contains a mix of classic and native histograms for metric name "mixedHistogram" (1:25)`,
|
||||
},
|
||||
expectedInfoAnnotations: []string{},
|
||||
},
|
||||
}
|
||||
for name, testCase := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
store := promqltest.LoadedStorage(t, "load 1m\n"+strings.TrimSpace(testCase.data))
|
||||
t.Cleanup(func() { _ = store.Close() })
|
||||
|
||||
engine := newTestEngine(t)
|
||||
query, err := engine.NewInstantQuery(context.Background(), store, nil, testCase.expr, timestamp.Time(0).Add(1*time.Minute))
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(query.Close)
|
||||
|
||||
res := query.Exec(context.Background())
|
||||
require.NoError(t, res.Err)
|
||||
|
||||
warnings, infos := res.Warnings.AsStrings(testCase.expr, 0, 0)
|
||||
testutil.RequireEqual(t, testCase.expectedWarningAnnotations, warnings)
|
||||
testutil.RequireEqual(t, testCase.expectedInfoAnnotations, infos)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHistogramRateWithFloatStaleness(t *testing.T) {
|
||||
// Make a chunk with two normal histograms of the same value.
|
||||
h1 := histogram.Histogram{
|
||||
|
|
|
@ -1387,14 +1387,13 @@ func funcHistogramQuantile(vals []parser.Value, args parser.Expressions, enh *Ev
|
|||
sample.Metric = labels.NewBuilder(sample.Metric).
|
||||
Del(excludedLabels...).
|
||||
Labels()
|
||||
|
||||
mb = &metricWithBuckets{sample.Metric, nil}
|
||||
enh.signatureToMetricWithBuckets[string(enh.lblBuf)] = mb
|
||||
}
|
||||
mb.buckets = append(mb.buckets, Bucket{upperBound, sample.F})
|
||||
}
|
||||
|
||||
// Now deal with the histograms.
|
||||
// Now deal with the native histograms.
|
||||
for _, sample := range histogramSamples {
|
||||
// We have to reconstruct the exact same signature as above for
|
||||
// a classic histogram, just ignoring any le label.
|
||||
|
@ -1418,16 +1417,23 @@ func funcHistogramQuantile(vals []parser.Value, args parser.Expressions, enh *Ev
|
|||
})
|
||||
}
|
||||
|
||||
// Now do classic histograms that have already been filtered for conflicting native histograms.
|
||||
for _, mb := range enh.signatureToMetricWithBuckets {
|
||||
if len(mb.buckets) > 0 {
|
||||
res, forcedMonotonicity, _ := BucketQuantile(q, mb.buckets)
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: mb.metric,
|
||||
F: res,
|
||||
})
|
||||
if forcedMonotonicity {
|
||||
annos.Add(annotations.NewHistogramQuantileForcedMonotonicityInfo(mb.metric.Get(labels.MetricName), args[1].PositionRange()))
|
||||
}
|
||||
|
||||
if !enh.enableDelayedNameRemoval {
|
||||
mb.metric = mb.metric.DropMetricName()
|
||||
}
|
||||
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: mb.metric,
|
||||
F: res,
|
||||
DropName: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ const smallDeltaTolerance = 1e-12
|
|||
// excludedLabels are the labels to exclude from signature calculation for
|
||||
// quantiles.
|
||||
var excludedLabels = []string{
|
||||
labels.MetricName,
|
||||
labels.BucketLabel,
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue