github.com/thanos-io/thanos@v0.32.5/pkg/query/testdata/promql/prometheus/histograms.test (about) 1 # Two histograms with 4 buckets each (x_sum and x_count not included, 2 # only buckets). Lowest bucket for one histogram < 0, for the other > 3 # 0. They have the same name, just separated by label. Not useful in 4 # practice, but can happen (if clients change bucketing), and the 5 # server has to cope with it. 6 7 # Test histogram. 8 load 5m 9 testhistogram_bucket{le="0.1", start="positive"} 0+5x10 10 testhistogram_bucket{le=".2", start="positive"} 0+7x10 11 testhistogram_bucket{le="1e0", start="positive"} 0+11x10 12 testhistogram_bucket{le="+Inf", start="positive"} 0+12x10 13 testhistogram_bucket{le="-.2", start="negative"} 0+1x10 14 testhistogram_bucket{le="-0.1", start="negative"} 0+2x10 15 testhistogram_bucket{le="0.3", start="negative"} 0+2x10 16 testhistogram_bucket{le="+Inf", start="negative"} 0+3x10 17 18 19 # Now a more realistic histogram per job and instance to test aggregation. 20 load 5m 21 request_duration_seconds_bucket{job="job1", instance="ins1", le="0.1"} 0+1x10 22 request_duration_seconds_bucket{job="job1", instance="ins1", le="0.2"} 0+3x10 23 request_duration_seconds_bucket{job="job1", instance="ins1", le="+Inf"} 0+4x10 24 request_duration_seconds_bucket{job="job1", instance="ins2", le="0.1"} 0+2x10 25 request_duration_seconds_bucket{job="job1", instance="ins2", le="0.2"} 0+5x10 26 request_duration_seconds_bucket{job="job1", instance="ins2", le="+Inf"} 0+6x10 27 request_duration_seconds_bucket{job="job2", instance="ins1", le="0.1"} 0+3x10 28 request_duration_seconds_bucket{job="job2", instance="ins1", le="0.2"} 0+4x10 29 request_duration_seconds_bucket{job="job2", instance="ins1", le="+Inf"} 0+6x10 30 request_duration_seconds_bucket{job="job2", instance="ins2", le="0.1"} 0+4x10 31 request_duration_seconds_bucket{job="job2", instance="ins2", le="0.2"} 0+7x10 32 request_duration_seconds_bucket{job="job2", instance="ins2", le="+Inf"} 0+9x10 33 34 # Different le representations in one histogram. 35 load 5m 36 mixed_bucket{job="job1", instance="ins1", le="0.1"} 0+1x10 37 mixed_bucket{job="job1", instance="ins1", le="0.2"} 0+1x10 38 mixed_bucket{job="job1", instance="ins1", le="2e-1"} 0+1x10 39 mixed_bucket{job="job1", instance="ins1", le="2.0e-1"} 0+1x10 40 mixed_bucket{job="job1", instance="ins1", le="+Inf"} 0+4x10 41 mixed_bucket{job="job1", instance="ins2", le="+inf"} 0+0x10 42 mixed_bucket{job="job1", instance="ins2", le="+Inf"} 0+0x10 43 44 # Quantile too low. 45 eval instant at 50m histogram_quantile(-0.1, testhistogram_bucket) 46 {start="positive"} -Inf 47 {start="negative"} -Inf 48 49 # Quantile too high. 50 eval instant at 50m histogram_quantile(1.01, testhistogram_bucket) 51 {start="positive"} +Inf 52 {start="negative"} +Inf 53 54 # Quantile value in lowest bucket, which is positive. 55 eval instant at 50m histogram_quantile(0, testhistogram_bucket{start="positive"}) 56 {start="positive"} 0 57 58 # Quantile value in lowest bucket, which is negative. 59 eval instant at 50m histogram_quantile(0, testhistogram_bucket{start="negative"}) 60 {start="negative"} -0.2 61 62 # Quantile value in highest bucket. 63 eval instant at 50m histogram_quantile(1, testhistogram_bucket) 64 {start="positive"} 1 65 {start="negative"} 0.3 66 67 # Finally some useful quantiles. 68 eval instant at 50m histogram_quantile(0.2, testhistogram_bucket) 69 {start="positive"} 0.048 70 {start="negative"} -0.2 71 72 73 eval instant at 50m histogram_quantile(0.5, testhistogram_bucket) 74 {start="positive"} 0.15 75 {start="negative"} -0.15 76 77 eval instant at 50m histogram_quantile(0.8, testhistogram_bucket) 78 {start="positive"} 0.72 79 {start="negative"} 0.3 80 81 # More realistic with rates. 82 eval instant at 50m histogram_quantile(0.2, rate(testhistogram_bucket[5m])) 83 {start="positive"} 0.048 84 {start="negative"} -0.2 85 86 eval instant at 50m histogram_quantile(0.5, rate(testhistogram_bucket[5m])) 87 {start="positive"} 0.15 88 {start="negative"} -0.15 89 90 eval instant at 50m histogram_quantile(0.8, rate(testhistogram_bucket[5m])) 91 {start="positive"} 0.72 92 {start="negative"} 0.3 93 94 # Aggregated histogram: Everything in one. 95 eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le)) 96 {} 0.075 97 98 eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le)) 99 {} 0.1277777777777778 100 101 # Aggregated histogram: Everything in one. Now with avg, which does not change anything. 102 eval instant at 50m histogram_quantile(0.3, avg(rate(request_duration_seconds_bucket[5m])) by (le)) 103 {} 0.075 104 105 eval instant at 50m histogram_quantile(0.5, avg(rate(request_duration_seconds_bucket[5m])) by (le)) 106 {} 0.12777777777777778 107 108 # Aggregated histogram: By job. 109 eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) 110 {instance="ins1"} 0.075 111 {instance="ins2"} 0.075 112 113 eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) 114 {instance="ins1"} 0.1333333333 115 {instance="ins2"} 0.125 116 117 # Aggregated histogram: By instance. 118 eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) 119 {job="job1"} 0.1 120 {job="job2"} 0.0642857142857143 121 122 eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) 123 {job="job1"} 0.14 124 {job="job2"} 0.1125 125 126 # Aggregated histogram: By job and instance. 127 eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) 128 {instance="ins1", job="job1"} 0.11 129 {instance="ins2", job="job1"} 0.09 130 {instance="ins1", job="job2"} 0.06 131 {instance="ins2", job="job2"} 0.0675 132 133 eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) 134 {instance="ins1", job="job1"} 0.15 135 {instance="ins2", job="job1"} 0.1333333333333333 136 {instance="ins1", job="job2"} 0.1 137 {instance="ins2", job="job2"} 0.1166666666666667 138 139 # The unaggregated histogram for comparison. Same result as the previous one. 140 eval instant at 50m histogram_quantile(0.3, rate(request_duration_seconds_bucket[5m])) 141 {instance="ins1", job="job1"} 0.11 142 {instance="ins2", job="job1"} 0.09 143 {instance="ins1", job="job2"} 0.06 144 {instance="ins2", job="job2"} 0.0675 145 146 eval instant at 50m histogram_quantile(0.5, rate(request_duration_seconds_bucket[5m])) 147 {instance="ins1", job="job1"} 0.15 148 {instance="ins2", job="job1"} 0.13333333333333333 149 {instance="ins1", job="job2"} 0.1 150 {instance="ins2", job="job2"} 0.11666666666666667 151 152 # A histogram with nonmonotonic bucket counts. This may happen when recording 153 # rule evaluation or federation races scrape ingestion, causing some buckets 154 # counts to be derived from fewer samples. 155 156 load 5m 157 nonmonotonic_bucket{le="0.1"} 0+2x10 158 nonmonotonic_bucket{le="1"} 0+1x10 159 nonmonotonic_bucket{le="10"} 0+5x10 160 nonmonotonic_bucket{le="100"} 0+4x10 161 nonmonotonic_bucket{le="1000"} 0+9x10 162 nonmonotonic_bucket{le="+Inf"} 0+8x10 163 164 # Nonmonotonic buckets 165 eval instant at 50m histogram_quantile(0.01, nonmonotonic_bucket) 166 {} 0.0045 167 168 eval instant at 50m histogram_quantile(0.5, nonmonotonic_bucket) 169 {} 8.5 170 171 eval instant at 50m histogram_quantile(0.99, nonmonotonic_bucket) 172 {} 979.75 173 174 # Buckets with different representations of the same upper bound. 175 eval instant at 50m histogram_quantile(0.5, rate(mixed_bucket[5m])) 176 {instance="ins1", job="job1"} 0.15 177 {instance="ins2", job="job1"} NaN 178 179 eval instant at 50m histogram_quantile(0.75, rate(mixed_bucket[5m])) 180 {instance="ins1", job="job1"} 0.2 181 {instance="ins2", job="job1"} NaN 182 183 eval instant at 50m histogram_quantile(1, rate(mixed_bucket[5m])) 184 {instance="ins1", job="job1"} 0.2 185 {instance="ins2", job="job1"} NaN 186 187 load 5m 188 empty_bucket{le="0.1", job="job1", instance="ins1"} 0x10 189 empty_bucket{le="0.2", job="job1", instance="ins1"} 0x10 190 empty_bucket{le="+Inf", job="job1", instance="ins1"} 0x10 191 192 eval instant at 50m histogram_quantile(0.2, rate(empty_bucket[5m])) 193 {instance="ins1", job="job1"} NaN