mirror of
https://github.com/prometheus/prometheus.git
synced 2026-05-28 04:02:21 -04:00
PromQL: Add experimental histogram_quantiles variadic function (#17285)
Some checks failed
buf.build / lint and publish (push) Has been cancelled
CI / Go tests (push) Has been cancelled
CI / More Go tests (push) Has been cancelled
CI / Go tests with previous Go version (push) Has been cancelled
CI / UI tests (push) Has been cancelled
CI / Go tests on Windows (push) Has been cancelled
CI / Mixins tests (push) Has been cancelled
CI / Build Prometheus for common architectures (push) Has been cancelled
CI / Build Prometheus for all architectures (push) Has been cancelled
CI / Check generated parser (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
CI / fuzzing (push) Has been cancelled
CI / codeql (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CI / Report status of build Prometheus for all architectures (push) Has been cancelled
CI / Publish main branch artifacts (push) Has been cancelled
CI / Publish release artefacts (push) Has been cancelled
CI / Publish UI on npm Registry (push) Has been cancelled
Some checks failed
buf.build / lint and publish (push) Has been cancelled
CI / Go tests (push) Has been cancelled
CI / More Go tests (push) Has been cancelled
CI / Go tests with previous Go version (push) Has been cancelled
CI / UI tests (push) Has been cancelled
CI / Go tests on Windows (push) Has been cancelled
CI / Mixins tests (push) Has been cancelled
CI / Build Prometheus for common architectures (push) Has been cancelled
CI / Build Prometheus for all architectures (push) Has been cancelled
CI / Check generated parser (push) Has been cancelled
CI / golangci-lint (push) Has been cancelled
CI / fuzzing (push) Has been cancelled
CI / codeql (push) Has been cancelled
Scorecards supply-chain security / Scorecards analysis (push) Has been cancelled
CI / Report status of build Prometheus for all architectures (push) Has been cancelled
CI / Publish main branch artifacts (push) Has been cancelled
CI / Publish release artefacts (push) Has been cancelled
CI / Publish UI on npm Registry (push) Has been cancelled
Signed-off-by: Linas Medziunas <linas.medziunas@gmail.com> Signed-off-by: Björn Rabenstein <github@rabenste.in> Signed-off-by: beorn7 <beorn@grafana.com> Co-authored-by: Björn Rabenstein <github@rabenste.in> Co-authored-by: beorn7 <beorn@grafana.com>
This commit is contained in:
parent
ece9437624
commit
5bd0d00f8c
12 changed files with 292 additions and 4 deletions
1
cmd/prometheus/testdata/features.json
vendored
1
cmd/prometheus/testdata/features.json
vendored
|
|
@ -80,6 +80,7 @@
|
|||
"histogram_count": true,
|
||||
"histogram_fraction": true,
|
||||
"histogram_quantile": true,
|
||||
"histogram_quantiles": false,
|
||||
"histogram_stddev": true,
|
||||
"histogram_stdvar": true,
|
||||
"histogram_sum": true,
|
||||
|
|
|
|||
|
|
@ -433,6 +433,23 @@ and is therefore flagged by an info-level annotation reading `input to
|
|||
histogram_quantile needed to be fixed for monotonicity`. If you encounter this
|
||||
annotation, you should find and remove the source of the invalid data.
|
||||
|
||||
## `histogram_quantiles()`
|
||||
|
||||
**This function has to be enabled via the [feature
|
||||
flag](../feature_flags.md#experimental-promql-functions)
|
||||
`--enable-feature=promql-experimental-functions`.**
|
||||
|
||||
`histogram_quantiles(v instant-vector, quantile_label string, φ_1 scalar, φ_2 scalar, ...)` calculates multiple (between 1 and 10) φ-quantiles (0 ≤
|
||||
φ ≤ 1) from a [classic
|
||||
histogram](https://prometheus.io/docs/concepts/metric_types/#histogram) or from
|
||||
a native histogram. Quantile calculation works the same way as in `histogram_quantile()`.
|
||||
The second argument (a string) specifies the label name that is used to identify different quantiles in the query result.
|
||||
```
|
||||
histogram_quantiles(sum(rate(foo[1m])), "quantile", 0.9, 0.99)
|
||||
# => {quantile="0.9"} 123
|
||||
{quantile="0.99"} 128
|
||||
```
|
||||
|
||||
## `histogram_stddev()` and `histogram_stdvar()`
|
||||
|
||||
`histogram_stddev(v instant-vector)` returns the estimated standard deviation
|
||||
|
|
|
|||
|
|
@ -1214,6 +1214,9 @@ type EvalNodeHelper struct {
|
|||
// funcHistogramQuantile and funcHistogramFraction for classic histograms.
|
||||
signatureToMetricWithBuckets map[string]*metricWithBuckets
|
||||
nativeHistogramSamples []Sample
|
||||
// funcHistogramQuantiles for histograms.
|
||||
quantileStrs map[float64]string
|
||||
signatureToLabelsWithQuantile map[string]map[float64]labels.Labels
|
||||
|
||||
lb *labels.Builder
|
||||
lblBuf []byte
|
||||
|
|
@ -1305,6 +1308,35 @@ func (enh *EvalNodeHelper) resetHistograms(inVec Vector, arg parser.Expr) annota
|
|||
return annos
|
||||
}
|
||||
|
||||
func (enh *EvalNodeHelper) getOrCreateLblsWithQuantile(lbls labels.Labels, quantileLabel string, q float64) labels.Labels {
|
||||
if enh.signatureToLabelsWithQuantile == nil {
|
||||
enh.signatureToLabelsWithQuantile = make(map[string]map[float64]labels.Labels)
|
||||
}
|
||||
|
||||
enh.lblBuf = lbls.Bytes(enh.lblBuf)
|
||||
cachedLbls, ok := enh.signatureToLabelsWithQuantile[string(enh.lblBuf)]
|
||||
if !ok {
|
||||
cachedLbls = make(map[float64]labels.Labels, len(enh.quantileStrs))
|
||||
enh.signatureToLabelsWithQuantile[string(enh.lblBuf)] = cachedLbls
|
||||
}
|
||||
|
||||
cachedLblsWithQuantile, ok := cachedLbls[q]
|
||||
if !ok {
|
||||
quantileStr := "NaN"
|
||||
if !math.IsNaN(q) {
|
||||
// Cannot do map lookup by NaN key.
|
||||
quantileStr = enh.quantileStrs[q]
|
||||
}
|
||||
cachedLblsWithQuantile = labels.NewBuilder(lbls).
|
||||
Set(quantileLabel, quantileStr).
|
||||
Labels()
|
||||
|
||||
cachedLbls[q] = cachedLblsWithQuantile
|
||||
}
|
||||
|
||||
return cachedLblsWithQuantile
|
||||
}
|
||||
|
||||
// rangeEval evaluates the given expressions, and then for each step calls
|
||||
// the given funcCall with the values computed for each expression at that
|
||||
// step. The return value is the combination into time series of all the
|
||||
|
|
@ -4320,7 +4352,7 @@ func detectHistogramStatsDecoding(expr parser.Expr) {
|
|||
// further up (the latter wouldn't make sense,
|
||||
// but no harm in detecting it).
|
||||
n.SkipHistogramBuckets = true
|
||||
case "histogram_quantile", "histogram_fraction":
|
||||
case "histogram_quantile", "histogram_quantiles", "histogram_fraction":
|
||||
// If we ever see a function that needs the
|
||||
// whole histogram, we will not skip the
|
||||
// buckets.
|
||||
|
|
|
|||
|
|
@ -1720,8 +1720,8 @@ func funcHistogramQuantile(vectorVals []Vector, _ Matrix, args parser.Expression
|
|||
inVec := vectorVals[1]
|
||||
var annos annotations.Annotations
|
||||
|
||||
if math.IsNaN(q) || q < 0 || q > 1 {
|
||||
annos.Add(annotations.NewInvalidQuantileWarning(q, args[0].PositionRange()))
|
||||
if err := validateQuantile(q, args[0]); err != nil {
|
||||
annos.Add(err)
|
||||
}
|
||||
annos.Merge(enh.resetHistograms(inVec, args[1]))
|
||||
|
||||
|
|
@ -1770,6 +1770,89 @@ func funcHistogramQuantile(vectorVals []Vector, _ Matrix, args parser.Expression
|
|||
return enh.Out, annos
|
||||
}
|
||||
|
||||
func validateQuantile(q float64, arg parser.Expr) error {
|
||||
if math.IsNaN(q) || q < 0 || q > 1 {
|
||||
return annotations.NewInvalidQuantileWarning(q, arg.PositionRange())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// === histogram_quantiles(Vector parser.ValueTypeVector, label parser.ValueTypeString, q0 parser.ValueTypeScalar, qs parser.ValueTypeScalar...) (Vector, Annotations) ===
|
||||
func funcHistogramQuantiles(vectorVals []Vector, _ Matrix, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
var (
|
||||
inVec = vectorVals[0]
|
||||
quantileLabel = args[1].(*parser.StringLiteral).Val
|
||||
numQuantiles = len(vectorVals[2:])
|
||||
qs = make([]float64, 0, numQuantiles)
|
||||
|
||||
annos annotations.Annotations
|
||||
)
|
||||
|
||||
if enh.quantileStrs == nil {
|
||||
enh.quantileStrs = make(map[float64]string, numQuantiles)
|
||||
}
|
||||
for i := 2; i < len(vectorVals); i++ {
|
||||
q := vectorVals[i][0].F
|
||||
|
||||
if err := validateQuantile(q, args[i]); err != nil {
|
||||
annos.Add(err)
|
||||
}
|
||||
|
||||
if _, ok := enh.quantileStrs[q]; !ok {
|
||||
enh.quantileStrs[q] = labels.FormatOpenMetricsFloat(q)
|
||||
}
|
||||
qs = append(qs, q)
|
||||
}
|
||||
|
||||
annos.Merge(enh.resetHistograms(inVec, args[0]))
|
||||
|
||||
for _, q := range qs {
|
||||
// Deal with the native histograms.
|
||||
for _, sample := range enh.nativeHistogramSamples {
|
||||
if sample.H == nil {
|
||||
// Native histogram conflicts with classic histogram at the same timestamp, ignore.
|
||||
continue
|
||||
}
|
||||
if !enh.enableDelayedNameRemoval {
|
||||
sample.Metric = sample.Metric.DropReserved(schema.IsMetadataLabel)
|
||||
}
|
||||
hq, hqAnnos := HistogramQuantile(q, sample.H, sample.Metric.Get(model.MetricNameLabel), args[0].PositionRange())
|
||||
annos.Merge(hqAnnos)
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.getOrCreateLblsWithQuantile(sample.Metric, quantileLabel, q),
|
||||
F: hq,
|
||||
DropName: true,
|
||||
})
|
||||
}
|
||||
|
||||
// Deal with classic histograms that have already been filtered for conflicting native histograms.
|
||||
for _, mb := range enh.signatureToMetricWithBuckets {
|
||||
if len(mb.buckets) > 0 {
|
||||
hq, forcedMonotonicity, _, minBucket, maxBucket, maxDiff := BucketQuantile(q, mb.buckets)
|
||||
if forcedMonotonicity {
|
||||
metricName := ""
|
||||
if enh.enableDelayedNameRemoval {
|
||||
metricName = getMetricName(mb.metric)
|
||||
}
|
||||
annos.Add(annotations.NewHistogramQuantileForcedMonotonicityInfo(metricName, args[1].PositionRange(), enh.Ts, minBucket, maxBucket, maxDiff))
|
||||
}
|
||||
|
||||
if !enh.enableDelayedNameRemoval {
|
||||
mb.metric = mb.metric.DropReserved(schema.IsMetadataLabel)
|
||||
}
|
||||
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: enh.getOrCreateLblsWithQuantile(mb.metric, quantileLabel, q),
|
||||
F: hq,
|
||||
DropName: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return enh.Out, annos
|
||||
}
|
||||
|
||||
// pickFirstSampleIndex returns the index of the last sample before
|
||||
// or at the range start, or 0 if none exist before the range start.
|
||||
// If the vector selector is not anchored, it always returns 0, true.
|
||||
|
|
@ -2100,6 +2183,7 @@ var FunctionCalls = map[string]FunctionCall{
|
|||
"histogram_count": funcHistogramCount,
|
||||
"histogram_fraction": funcHistogramFraction,
|
||||
"histogram_quantile": funcHistogramQuantile,
|
||||
"histogram_quantiles": funcHistogramQuantiles,
|
||||
"histogram_sum": funcHistogramSum,
|
||||
"histogram_stddev": funcHistogramStdDev,
|
||||
"histogram_stdvar": funcHistogramStdVar,
|
||||
|
|
|
|||
|
|
@ -205,6 +205,13 @@ var Functions = map[string]*Function{
|
|||
ArgTypes: []ValueType{ValueTypeScalar, ValueTypeVector},
|
||||
ReturnType: ValueTypeVector,
|
||||
},
|
||||
"histogram_quantiles": {
|
||||
Name: "histogram_quantiles",
|
||||
ArgTypes: []ValueType{ValueTypeVector, ValueTypeString, ValueTypeScalar, ValueTypeScalar},
|
||||
Variadic: 9,
|
||||
ReturnType: ValueTypeVector,
|
||||
Experimental: true,
|
||||
},
|
||||
"double_exponential_smoothing": {
|
||||
Name: "double_exponential_smoothing",
|
||||
ArgTypes: []ValueType{ValueTypeMatrix, ValueTypeScalar, ValueTypeScalar},
|
||||
|
|
|
|||
86
promql/promqltest/testdata/histograms.test
vendored
86
promql/promqltest/testdata/histograms.test
vendored
|
|
@ -598,6 +598,40 @@ eval instant at 50m histogram_quantile(1, testhistogram3_bucket)
|
|||
{start="positive"} 1
|
||||
{start="negative"} -0.1
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram3, "q", 0, 0.25, 0.5, 0.75, 1)
|
||||
expect no_warn
|
||||
{q="0.0", start="positive"} 0
|
||||
{q="0.0", start="negative"} -0.25
|
||||
{q="0.25", start="positive"} 0.055
|
||||
{q="0.25", start="negative"} -0.225
|
||||
{q="0.5", start="positive"} 0.125
|
||||
{q="0.5", start="negative"} -0.2
|
||||
{q="0.75", start="positive"} 0.45
|
||||
{q="0.75", start="negative"} -0.15
|
||||
{q="1.0", start="positive"} 1
|
||||
{q="1.0", start="negative"} -0.1
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram3_bucket, "q", 0, 0.25, 0.5, 0.75, 1)
|
||||
expect no_warn
|
||||
{q="0.0", start="positive"} 0
|
||||
{q="0.0", start="negative"} -0.25
|
||||
{q="0.25", start="positive"} 0.055
|
||||
{q="0.25", start="negative"} -0.225
|
||||
{q="0.5", start="positive"} 0.125
|
||||
{q="0.5", start="negative"} -0.2
|
||||
{q="0.75", start="positive"} 0.45
|
||||
{q="0.75", start="negative"} -0.15
|
||||
{q="1.0", start="positive"} 1
|
||||
{q="1.0", start="negative"} -0.1
|
||||
|
||||
# Break label set uniqueness.
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram3, "start", 0, 0.25, 0.5, 0.75, 1)
|
||||
expect fail
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram3_bucket, "start", 0, 0.25, 0.5, 0.75, 1)
|
||||
expect fail
|
||||
|
||||
# Quantile too low.
|
||||
|
||||
eval instant at 50m histogram_quantile(-0.1, testhistogram)
|
||||
|
|
@ -610,6 +644,16 @@ eval instant at 50m histogram_quantile(-0.1, testhistogram_bucket)
|
|||
{start="positive"} -Inf
|
||||
{start="negative"} -Inf
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram, "q", -0.1)
|
||||
expect warn
|
||||
{q="-0.1", start="positive"} -Inf
|
||||
{q="-0.1", start="negative"} -Inf
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram_bucket, "q", -0.1)
|
||||
expect warn
|
||||
{q="-0.1", start="positive"} -Inf
|
||||
{q="-0.1", start="negative"} -Inf
|
||||
|
||||
# Quantile too high.
|
||||
|
||||
eval instant at 50m histogram_quantile(1.01, testhistogram)
|
||||
|
|
@ -622,6 +666,16 @@ eval instant at 50m histogram_quantile(1.01, testhistogram_bucket)
|
|||
{start="positive"} +Inf
|
||||
{start="negative"} +Inf
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram, "q", 1.01)
|
||||
expect warn
|
||||
{q="1.01", start="positive"} +Inf
|
||||
{q="1.01", start="negative"} +Inf
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram_bucket, "q", 1.01)
|
||||
expect warn
|
||||
{q="1.01", start="positive"} +Inf
|
||||
{q="1.01", start="negative"} +Inf
|
||||
|
||||
# Quantile invalid.
|
||||
|
||||
eval instant at 50m histogram_quantile(NaN, testhistogram)
|
||||
|
|
@ -634,9 +688,22 @@ eval instant at 50m histogram_quantile(NaN, testhistogram_bucket)
|
|||
{start="positive"} NaN
|
||||
{start="negative"} NaN
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram, "q", NaN)
|
||||
expect warn
|
||||
{q="NaN", start="positive"} NaN
|
||||
{q="NaN", start="negative"} NaN
|
||||
|
||||
eval instant at 50m histogram_quantiles(testhistogram_bucket, "q", NaN)
|
||||
expect warn
|
||||
{q="NaN", start="positive"} NaN
|
||||
{q="NaN", start="negative"} NaN
|
||||
|
||||
eval instant at 50m histogram_quantile(NaN, non_existent)
|
||||
expect warn msg: PromQL warning: quantile value should be between 0 and 1, got NaN
|
||||
|
||||
eval instant at 50m histogram_quantiles(non_existent, "q", NaN)
|
||||
expect warn msg: PromQL warning: quantile value should be between 0 and 1, got NaN
|
||||
|
||||
# Quantile value in lowest bucket.
|
||||
|
||||
eval instant at 50m histogram_quantile(0, testhistogram)
|
||||
|
|
@ -967,6 +1034,12 @@ eval instant at 50m histogram_quantile(0.99, nonmonotonic_bucket)
|
|||
expect info
|
||||
{} 979.75
|
||||
|
||||
eval instant at 50m histogram_quantiles(nonmonotonic_bucket, "q", 0.01, 0.5, 0.99)
|
||||
expect info
|
||||
{q="0.01"} 0.0045
|
||||
{q="0.5"} 8.5
|
||||
{q="0.99"} 979.75
|
||||
|
||||
# Buckets with different representations of the same upper bound.
|
||||
eval instant at 50m histogram_quantile(0.5, rate(mixed_bucket[10m]))
|
||||
{instance="ins1", job="job1"} 0.15
|
||||
|
|
@ -1002,9 +1075,15 @@ load_with_nhcb 5m
|
|||
eval instant at 50m histogram_quantile(0.99, {__name__=~"request_duration_seconds\\d*_bucket"})
|
||||
expect fail
|
||||
|
||||
eval instant at 50m histogram_quantiles({__name__=~"request_duration_seconds\\d*_bucket"}, "q", 0.99)
|
||||
expect fail
|
||||
|
||||
eval instant at 50m histogram_quantile(0.99, {__name__=~"request_duration_seconds\\d*"})
|
||||
expect fail
|
||||
|
||||
eval instant at 50m histogram_quantiles({__name__=~"request_duration_seconds\\d*"}, "q", 0.99)
|
||||
expect fail
|
||||
|
||||
# Histogram with constant buckets.
|
||||
load_with_nhcb 1m
|
||||
const_histogram_bucket{le="0.0"} 1 1 1 1 1
|
||||
|
|
@ -1066,7 +1145,7 @@ eval instant at 10m histogram_sum(increase(histogram_with_reset[15m]))
|
|||
|
||||
clear
|
||||
|
||||
# Test histogram_quantile and histogram_fraction with conflicting classic and native histograms.
|
||||
# Test histogram_quantile(s) and histogram_fraction with conflicting classic and native histograms.
|
||||
load 1m
|
||||
series{host="a"} {{schema:0 sum:5 count:4 buckets:[9 2 1]}}
|
||||
series{host="a", le="0.1"} 2
|
||||
|
|
@ -1081,6 +1160,11 @@ eval instant at 0 histogram_quantile(0.8, series)
|
|||
expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "series"
|
||||
# Should return no results.
|
||||
|
||||
eval instant at 0 histogram_quantiles(series, "q", 0.1, 0.2)
|
||||
expect no_info
|
||||
expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "series"
|
||||
# Should return no results.
|
||||
|
||||
eval instant at 0 histogram_fraction(-Inf, 1, series)
|
||||
expect no_info
|
||||
expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "series"
|
||||
|
|
|
|||
|
|
@ -55,6 +55,10 @@ eval instant at 1m histogram_quantile(0.5, single_histogram)
|
|||
expect no_info
|
||||
{} 1.414213562373095
|
||||
|
||||
eval instant at 1m histogram_quantiles(single_histogram, "q", 0.5)
|
||||
expect no_info
|
||||
{q="0.5"} 1.414213562373095
|
||||
|
||||
clear
|
||||
|
||||
# Repeat the same histogram 10 times.
|
||||
|
|
@ -1605,6 +1609,11 @@ eval instant at 1m histogram_quantile(0.81, histogram_nan)
|
|||
{case="100% NaNs"} NaN
|
||||
{case="20% NaNs"} NaN
|
||||
|
||||
eval instant at 1m histogram_quantiles(histogram_nan, "q", 0.81)
|
||||
expect info msg: PromQL info: input to histogram_quantile has NaN observations, result is NaN for metric name "histogram_nan"
|
||||
{case="100% NaNs", q="0.81"} NaN
|
||||
{case="20% NaNs", q="0.81"} NaN
|
||||
|
||||
eval instant at 1m histogram_quantile(0.8, histogram_nan{case="100% NaNs"})
|
||||
expect info msg: PromQL info: input to histogram_quantile has NaN observations, result is NaN for metric name "histogram_nan"
|
||||
{case="100% NaNs"} NaN
|
||||
|
|
@ -1891,6 +1900,9 @@ eval instant at 1m histogram_quantile(0.5, myHistogram2)
|
|||
eval instant at 1m histogram_quantile(0.5, mixedHistogram)
|
||||
expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "mixedHistogram"
|
||||
|
||||
eval instant at 1m histogram_quantiles(mixedHistogram, "q", 0.5)
|
||||
expect warn msg: PromQL warning: vector contains a mix of classic and native histograms for metric name "mixedHistogram"
|
||||
|
||||
clear
|
||||
|
||||
# A counter reset only in a bucket. Sub-queries still need to detect
|
||||
|
|
@ -1960,6 +1972,9 @@ eval instant at 1m histogram_count(histogram unless histogram_quantile(0.5, hist
|
|||
eval instant at 1m histogram_quantile(0.5, histogram unless histogram_count(histogram) == 0)
|
||||
{} 3.1748021039363987
|
||||
|
||||
eval instant at 1m histogram_quantiles(histogram unless histogram_count(histogram) == 0, "q", 0.5)
|
||||
{q="0.5"} 3.1748021039363987
|
||||
|
||||
clear
|
||||
|
||||
# Regression test for:
|
||||
|
|
|
|||
|
|
@ -1543,6 +1543,33 @@ const funcDocs: Record<string, React.ReactNode> = {
|
|||
</p>
|
||||
</>
|
||||
),
|
||||
histogram_quantiles: (
|
||||
<>
|
||||
<p>
|
||||
<strong>
|
||||
This function has to be enabled via the{" "}
|
||||
<a href="../feature_flags.md#experimental-promql-functions">feature flag</a>
|
||||
<code>--enable-feature=promql-experimental-functions</code>.
|
||||
</strong>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>histogram_quantiles(v instant-vector, quantile_label string, φ_1 scalar, φ_2 scalar, ...)</code>{" "}
|
||||
calculates multiple (between 1 and 10) φ-quantiles (0 ≤ φ ≤ 1) from a{" "}
|
||||
<a href="https://prometheus.io/docs/concepts/metric_types/#histogram">classic histogram</a> or from a native
|
||||
histogram. Quantile calculation works the same way as in <code>histogram_quantile()</code>. The second argument
|
||||
(a string) specifies the label name that is used to identify different quantiles in the query result.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
<code>
|
||||
histogram_quantiles(sum(rate(foo[1m])), "quantile", 0.9, 0.99) # => {"{"}quantile="0.9"
|
||||
{"}"} 123
|
||||
{"{"}quantile="0.99"{"}"} 128
|
||||
</code>
|
||||
</pre>
|
||||
</>
|
||||
),
|
||||
histogram_stddev: (
|
||||
<>
|
||||
<p>
|
||||
|
|
|
|||
|
|
@ -69,6 +69,12 @@ export const functionSignatures: Record<string, Func> = {
|
|||
variadic: 0,
|
||||
returnType: valueType.vector,
|
||||
},
|
||||
histogram_quantiles: {
|
||||
name: "histogram_quantiles",
|
||||
argTypes: [valueType.vector, valueType.string, valueType.scalar, valueType.scalar],
|
||||
variadic: 9,
|
||||
returnType: valueType.vector,
|
||||
},
|
||||
histogram_stddev: {
|
||||
name: "histogram_stddev",
|
||||
argTypes: [valueType.vector],
|
||||
|
|
|
|||
|
|
@ -243,6 +243,12 @@ export const functionIdentifierTerms = [
|
|||
info: 'Calculate quantiles from native histograms and from conventional histogram buckets',
|
||||
type: 'function',
|
||||
},
|
||||
{
|
||||
label: 'histogram_quantiles',
|
||||
detail: 'function',
|
||||
info: 'Calculate multiple quantiles from native histograms and from conventional histogram buckets',
|
||||
type: 'function',
|
||||
},
|
||||
{
|
||||
label: 'histogram_sum',
|
||||
detail: 'function',
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ import {
|
|||
HistogramCount,
|
||||
HistogramFraction,
|
||||
HistogramQuantile,
|
||||
HistogramQuantiles,
|
||||
HistogramStdDev,
|
||||
HistogramStdVar,
|
||||
HistogramSum,
|
||||
|
|
@ -306,6 +307,12 @@ const promqlFunctions: { [key: number]: PromQLFunction } = {
|
|||
variadic: 0,
|
||||
returnType: ValueType.vector,
|
||||
},
|
||||
[HistogramQuantiles]: {
|
||||
name: 'histogram_quantiles',
|
||||
argTypes: [ValueType.vector, ValueType.string, ValueType.scalar, ValueType.scalar],
|
||||
variadic: 10,
|
||||
returnType: ValueType.vector,
|
||||
},
|
||||
[HistogramStdDev]: {
|
||||
name: 'histogram_stddev',
|
||||
argTypes: [ValueType.vector],
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ FunctionIdentifier {
|
|||
HistogramCount |
|
||||
HistogramFraction |
|
||||
HistogramQuantile |
|
||||
HistogramQuantiles |
|
||||
HistogramStdDev |
|
||||
HistogramStdVar |
|
||||
HistogramSum |
|
||||
|
|
@ -426,6 +427,7 @@ NumberDurationLiteralInDurationContext {
|
|||
HistogramCount { condFn<"histogram_count"> }
|
||||
HistogramFraction { condFn<"histogram_fraction"> }
|
||||
HistogramQuantile { condFn<"histogram_quantile"> }
|
||||
HistogramQuantiles { condFn<"histogram_quantiles"> }
|
||||
HistogramStdDev { condFn<"histogram_stddev"> }
|
||||
HistogramStdVar { condFn<"histogram_stdvar"> }
|
||||
HistogramSum { condFn<"histogram_sum"> }
|
||||
|
|
|
|||
Loading…
Reference in a new issue