mirror of
https://github.com/prometheus/prometheus.git
synced 2024-11-09 23:24:05 -08:00
promql: add histogram_avg function (#13467)
Add histogram_avg function --------- Signed-off-by: Faustas Butkus <faustas.butkus@gmail.com> Signed-off-by: Björn Rabenstein <github@rabenste.in> Co-authored-by: Björn Rabenstein <github@rabenste.in>
This commit is contained in:
parent
c006c57efc
commit
6feffeb92e
|
@ -175,6 +175,27 @@ Special cases are:
|
|||
`floor(v instant-vector)` rounds the sample values of all elements in `v` down
|
||||
to the nearest integer.
|
||||
|
||||
## `histogram_avg()`
|
||||
|
||||
_This function only acts on native histograms, which are an experimental
|
||||
feature. The behavior of this function may change in future versions of
|
||||
Prometheus, including its removal from PromQL._
|
||||
|
||||
`histogram_avg(v instant-vector)` returns the arithmetic average of observed values stored in
|
||||
a native histogram. Samples that are not native histograms are ignored and do
|
||||
not show up in the returned vector.
|
||||
|
||||
Use `histogram_avg` as demonstrated below to compute the average request duration
|
||||
over a 5-minute window from a native histogram:
|
||||
|
||||
histogram_avg(rate(http_request_duration_seconds[5m]))
|
||||
|
||||
Which is equivalent to the following query:
|
||||
|
||||
histogram_sum(rate(http_request_duration_seconds[5m]))
|
||||
/
|
||||
histogram_count(rate(http_request_duration_seconds[5m]))
|
||||
|
||||
## `histogram_count()` and `histogram_sum()`
|
||||
|
||||
_Both functions only act on native histograms, which are an experimental
|
||||
|
@ -193,13 +214,6 @@ Use `histogram_count` in the following way to calculate a rate of observations
|
|||
|
||||
histogram_count(rate(http_request_duration_seconds[10m]))
|
||||
|
||||
The additional use of `histogram_sum` enables the calculation of the average of
|
||||
observed values (in this case corresponding to “average request duration”):
|
||||
|
||||
histogram_sum(rate(http_request_duration_seconds[10m]))
|
||||
/
|
||||
histogram_count(rate(http_request_duration_seconds[10m]))
|
||||
|
||||
## `histogram_fraction()`
|
||||
|
||||
_This function only acts on native histograms, which are an experimental
|
||||
|
|
|
@ -1081,6 +1081,23 @@ func funcHistogramSum(vals []parser.Value, args parser.Expressions, enh *EvalNod
|
|||
return enh.Out, nil
|
||||
}
|
||||
|
||||
// === histogram_avg(Vector parser.ValueTypeVector) (Vector, Annotations) ===
|
||||
func funcHistogramAvg(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
inVec := vals[0].(Vector)
|
||||
|
||||
for _, sample := range inVec {
|
||||
// Skip non-histogram samples.
|
||||
if sample.H == nil {
|
||||
continue
|
||||
}
|
||||
enh.Out = append(enh.Out, Sample{
|
||||
Metric: sample.Metric.DropMetricName(),
|
||||
F: sample.H.Sum / sample.H.Count,
|
||||
})
|
||||
}
|
||||
return enh.Out, nil
|
||||
}
|
||||
|
||||
// === histogram_stddev(Vector parser.ValueTypeVector) (Vector, Annotations) ===
|
||||
func funcHistogramStdDev(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) (Vector, annotations.Annotations) {
|
||||
inVec := vals[0].(Vector)
|
||||
|
@ -1532,6 +1549,7 @@ var FunctionCalls = map[string]FunctionCall{
|
|||
"deriv": funcDeriv,
|
||||
"exp": funcExp,
|
||||
"floor": funcFloor,
|
||||
"histogram_avg": funcHistogramAvg,
|
||||
"histogram_count": funcHistogramCount,
|
||||
"histogram_fraction": funcHistogramFraction,
|
||||
"histogram_quantile": funcHistogramQuantile,
|
||||
|
|
|
@ -167,6 +167,11 @@ var Functions = map[string]*Function{
|
|||
ArgTypes: []ValueType{ValueTypeVector},
|
||||
ReturnType: ValueTypeVector,
|
||||
},
|
||||
"histogram_avg": {
|
||||
Name: "histogram_avg",
|
||||
ArgTypes: []ValueType{ValueTypeVector},
|
||||
ReturnType: ValueTypeVector,
|
||||
},
|
||||
"histogram_count": {
|
||||
Name: "histogram_count",
|
||||
ArgTypes: []ValueType{ValueTypeVector},
|
||||
|
|
34
promql/testdata/native_histograms.test
vendored
34
promql/testdata/native_histograms.test
vendored
|
@ -11,6 +11,9 @@ eval instant at 5m histogram_count(empty_histogram)
|
|||
eval instant at 5m histogram_sum(empty_histogram)
|
||||
{} 0
|
||||
|
||||
eval instant at 5m histogram_avg(empty_histogram)
|
||||
{} NaN
|
||||
|
||||
eval instant at 5m histogram_fraction(-Inf, +Inf, empty_histogram)
|
||||
{} NaN
|
||||
|
||||
|
@ -31,6 +34,10 @@ eval instant at 5m histogram_count(single_histogram)
|
|||
eval instant at 5m histogram_sum(single_histogram)
|
||||
{} 5
|
||||
|
||||
# histogram_avg calculates the average from sum and count properties.
|
||||
eval instant at 5m histogram_avg(single_histogram)
|
||||
{} 1.25
|
||||
|
||||
# We expect half of the values to fall in the range 1 < x <= 2.
|
||||
eval instant at 5m histogram_fraction(1, 2, single_histogram)
|
||||
{} 0.5
|
||||
|
@ -55,6 +62,9 @@ eval instant at 5m histogram_count(multi_histogram)
|
|||
eval instant at 5m histogram_sum(multi_histogram)
|
||||
{} 5
|
||||
|
||||
eval instant at 5m histogram_avg(multi_histogram)
|
||||
{} 1.25
|
||||
|
||||
eval instant at 5m histogram_fraction(1, 2, multi_histogram)
|
||||
{} 0.5
|
||||
|
||||
|
@ -69,6 +79,9 @@ eval instant at 50m histogram_count(multi_histogram)
|
|||
eval instant at 50m histogram_sum(multi_histogram)
|
||||
{} 5
|
||||
|
||||
eval instant at 50m histogram_avg(multi_histogram)
|
||||
{} 1.25
|
||||
|
||||
eval instant at 50m histogram_fraction(1, 2, multi_histogram)
|
||||
{} 0.5
|
||||
|
||||
|
@ -89,6 +102,9 @@ eval instant at 5m histogram_count(incr_histogram)
|
|||
eval instant at 5m histogram_sum(incr_histogram)
|
||||
{} 6
|
||||
|
||||
eval instant at 5m histogram_avg(incr_histogram)
|
||||
{} 1.2
|
||||
|
||||
# We expect 3/5ths of the values to fall in the range 1 < x <= 2.
|
||||
eval instant at 5m histogram_fraction(1, 2, incr_histogram)
|
||||
{} 0.6
|
||||
|
@ -106,6 +122,9 @@ eval instant at 50m histogram_count(incr_histogram)
|
|||
eval instant at 50m histogram_sum(incr_histogram)
|
||||
{} 24
|
||||
|
||||
eval instant at 50m histogram_avg(incr_histogram)
|
||||
{} 1.7142857142857142
|
||||
|
||||
# We expect 12/14ths of the values to fall in the range 1 < x <= 2.
|
||||
eval instant at 50m histogram_fraction(1, 2, incr_histogram)
|
||||
{} 0.8571428571428571
|
||||
|
@ -140,6 +159,9 @@ eval instant at 5m histogram_count(low_res_histogram)
|
|||
eval instant at 5m histogram_sum(low_res_histogram)
|
||||
{} 8
|
||||
|
||||
eval instant at 5m histogram_avg(low_res_histogram)
|
||||
{} 1.6
|
||||
|
||||
# We expect all values to fall into the lower-resolution bucket with the range 1 < x <= 4.
|
||||
eval instant at 5m histogram_fraction(1, 4, low_res_histogram)
|
||||
{} 1
|
||||
|
@ -157,6 +179,9 @@ eval instant at 5m histogram_count(single_zero_histogram)
|
|||
eval instant at 5m histogram_sum(single_zero_histogram)
|
||||
{} 0.25
|
||||
|
||||
eval instant at 5m histogram_avg(single_zero_histogram)
|
||||
{} 0.25
|
||||
|
||||
# When only the zero bucket is populated, or there are negative buckets, the distribution is assumed to be equally
|
||||
# distributed around zero; i.e. that there are an equal number of positive and negative observations. Therefore the
|
||||
# entire distribution must lie within the full range of the zero bucket, in this case: -0.5 < x <= +0.5.
|
||||
|
@ -179,6 +204,9 @@ eval instant at 5m histogram_count(negative_histogram)
|
|||
eval instant at 5m histogram_sum(negative_histogram)
|
||||
{} -5
|
||||
|
||||
eval instant at 5m histogram_avg(negative_histogram)
|
||||
{} -1.25
|
||||
|
||||
# We expect half of the values to fall in the range -2 < x <= -1.
|
||||
eval instant at 5m histogram_fraction(-2, -1, negative_histogram)
|
||||
{} 0.5
|
||||
|
@ -199,6 +227,9 @@ eval instant at 10m histogram_count(two_samples_histogram)
|
|||
eval instant at 10m histogram_sum(two_samples_histogram)
|
||||
{} -4
|
||||
|
||||
eval instant at 10m histogram_avg(two_samples_histogram)
|
||||
{} -1
|
||||
|
||||
eval instant at 10m histogram_fraction(-2, -1, two_samples_histogram)
|
||||
{} 0.5
|
||||
|
||||
|
@ -217,6 +248,9 @@ eval instant at 5m histogram_count(balanced_histogram)
|
|||
eval instant at 5m histogram_sum(balanced_histogram)
|
||||
{} 0
|
||||
|
||||
eval instant at 5m histogram_avg(balanced_histogram)
|
||||
{} 0
|
||||
|
||||
eval instant at 5m histogram_fraction(0, 4, balanced_histogram)
|
||||
{} 0.5
|
||||
|
||||
|
|
|
@ -215,6 +215,12 @@ export const functionIdentifierTerms = [
|
|||
info: 'Round down values of input series to nearest integer',
|
||||
type: 'function',
|
||||
},
|
||||
{
|
||||
label: 'histogram_avg',
|
||||
detail: 'function',
|
||||
info: 'Return the average of observations from a native histogram (experimental feature)',
|
||||
type: 'function',
|
||||
},
|
||||
{
|
||||
label: 'histogram_count',
|
||||
detail: 'function',
|
||||
|
|
|
@ -757,6 +757,18 @@ describe('promql operations', () => {
|
|||
expectedValueType: ValueType.vector,
|
||||
expectedDiag: [],
|
||||
},
|
||||
{
|
||||
expr:
|
||||
'histogram_avg( # Root of the query, final result, returns the average of observations.\n' +
|
||||
' sum by(method, path) ( # Argument to histogram_avg(), an aggregated histogram.\n' +
|
||||
' rate( # Argument to sum(), the per-second increase of a histogram over 5m.\n' +
|
||||
' demo_api_request_duration_seconds{job="demo"}[5m] # Argument to rate(), a vector of sparse histogram series over the last 5m.\n' +
|
||||
' )\n' +
|
||||
' )\n' +
|
||||
')',
|
||||
expectedValueType: ValueType.vector,
|
||||
expectedDiag: [],
|
||||
},
|
||||
{
|
||||
expr:
|
||||
'histogram_stddev( # Root of the query, final result, returns the standard deviation of observations.\n' +
|
||||
|
|
|
@ -39,6 +39,7 @@ import {
|
|||
Deriv,
|
||||
Exp,
|
||||
Floor,
|
||||
HistogramAvg,
|
||||
HistogramCount,
|
||||
HistogramFraction,
|
||||
HistogramQuantile,
|
||||
|
@ -269,6 +270,12 @@ const promqlFunctions: { [key: number]: PromQLFunction } = {
|
|||
variadic: 0,
|
||||
returnType: ValueType.vector,
|
||||
},
|
||||
[HistogramAvg]: {
|
||||
name: 'histogram_avg',
|
||||
argTypes: [ValueType.vector],
|
||||
variadic: 0,
|
||||
returnType: ValueType.vector,
|
||||
},
|
||||
[HistogramCount]: {
|
||||
name: 'histogram_count',
|
||||
argTypes: [ValueType.vector],
|
||||
|
|
|
@ -20,7 +20,7 @@ export const promQLHighLight = styleTags({
|
|||
NumberLiteral: tags.number,
|
||||
Duration: tags.number,
|
||||
Identifier: tags.variableName,
|
||||
'Abs Absent AbsentOverTime Acos Acosh Asin Asinh Atan Atanh AvgOverTime Ceil Changes Clamp ClampMax ClampMin Cos Cosh CountOverTime DaysInMonth DayOfMonth DayOfWeek DayOfYear Deg Delta Deriv Exp Floor HistogramCount HistogramFraction HistogramQuantile HistogramSum HoltWinters Hour Idelta Increase Irate LabelReplace LabelJoin LastOverTime Ln Log10 Log2 MaxOverTime MinOverTime Minute Month Pi PredictLinear PresentOverTime QuantileOverTime Rad Rate Resets Round Scalar Sgn Sin Sinh Sort SortDesc SortByLabel SortByLabelDesc Sqrt StddevOverTime StdvarOverTime SumOverTime Tan Tanh Time Timestamp Vector Year':
|
||||
'Abs Absent AbsentOverTime Acos Acosh Asin Asinh Atan Atanh AvgOverTime Ceil Changes Clamp ClampMax ClampMin Cos Cosh CountOverTime DaysInMonth DayOfMonth DayOfWeek DayOfYear Deg Delta Deriv Exp Floor HistogramAvg HistogramCount HistogramFraction HistogramQuantile HistogramSum HoltWinters Hour Idelta Increase Irate LabelReplace LabelJoin LastOverTime Ln Log10 Log2 MaxOverTime MinOverTime Minute Month Pi PredictLinear PresentOverTime QuantileOverTime Rad Rate Resets Round Scalar Sgn Sin Sinh Sort SortDesc SortByLabel SortByLabelDesc Sqrt StddevOverTime StdvarOverTime SumOverTime Tan Tanh Time Timestamp Vector Year':
|
||||
tags.function(tags.variableName),
|
||||
'Avg Bottomk Count Count_values Group Max Min Quantile Stddev Stdvar Sum Topk': tags.operatorKeyword,
|
||||
'By Without Bool On Ignoring GroupLeft GroupRight Offset Start End': tags.modifier,
|
||||
|
|
|
@ -138,6 +138,7 @@ FunctionIdentifier {
|
|||
HistogramStdDev |
|
||||
HistogramStdVar |
|
||||
HistogramSum |
|
||||
HistogramAvg |
|
||||
HoltWinters |
|
||||
Hour |
|
||||
Idelta |
|
||||
|
@ -364,6 +365,7 @@ NumberLiteral {
|
|||
Deriv { condFn<"deriv"> }
|
||||
Exp { condFn<"exp"> }
|
||||
Floor { condFn<"floor"> }
|
||||
HistogramAvg { condFn<"histogram_avg"> }
|
||||
HistogramCount { condFn<"histogram_count"> }
|
||||
HistogramFraction { condFn<"histogram_fraction"> }
|
||||
HistogramQuantile { condFn<"histogram_quantile"> }
|
||||
|
|
Loading…
Reference in a new issue