ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Calculate Histogram Quantile

PromQL

Goal -- WPM

Ready
Exercise Algorithm Area
1package main
2
3import (
4 "fmt"
5 "strings"
6 "time"
7)
8
9// calculateHistogramQuantile computes the specified quantile for a histogram metric.
10// It uses the histogram_quantile function and handles potential label aggregation.
11func calculateHistogramQuantile(metricName string, quantile float64, duration time.Duration, labelsToSum []string) string {
12 if metricName == "" {
13 fmt.Println("Error: Metric name cannot be empty.")
14 return ""
15 }
16 if quantile <= 0 || quantile >= 1 {
17 fmt.Println("Error: Quantile must be between 0 and 1 (exclusive).")
18 return ""
19 }
20 if duration <= 0 {
21 fmt.Println("Error: Duration must be positive.")
22 return ""
23 }
24
25 // Construct the base histogram query.
26 // We need to sum the buckets for the given duration.
27 bucketQuery := fmt.Sprintf("sum by (%s) (%s_bucket)", strings.Join(labelsToSum, ","), metricName)
28
29 // Apply the histogram_quantile function.
30 // The second argument is the quantile, and the third is the duration for rate calculation.
31 // We use rate() on the bucket counts to get the per-second rate of observations in each bucket.
32 query := fmt.Sprintf("histogram_quantile(%f, sum by (%s) (rate(%s_bucket[%s])))",
33 quantile,
34 strings.Join(labelsToSum, ","),
35 metricName,
36 duration)
37
38 return query
39}
40
41// calculateQuantileWithRate demonstrates calculating quantile over a rate of observations.
42func calculateQuantileWithRate(metricName string, quantile float64, duration time.Duration) string {
43 if metricName == "" {
44 fmt.Println("Error: Metric name cannot be empty.")
45 return ""
46 }
47 if quantile <= 0 || quantile >= 1 {
48 fmt.Println("Error: Quantile must be between 0 and 1 (exclusive).")
49 return ""
50 }
51 if duration <= 0 {
52 fmt.Println("Error: Duration must be positive.")
53 return ""
54 }
55
56 // This query calculates the quantile based on the rate of observations in each bucket.
57 // This is the standard way to use histogram_quantile.
58 query := fmt.Sprintf("histogram_quantile(%f, sum by (le) (rate(%s_bucket[%s])))",
59 quantile,
60 metricName,
61 duration)
62
63 return query
64}
65
66func main() {
67 metric := "http_request_duration_seconds"
68 quantile := 0.95
69 duration := 5 * time.Minute
70 labels := []string{"method", "path"}
71
72 quantileQuery := calculateHistogramQuantile(metric, quantile, duration, labels)
73 fmt.Printf("Generated PromQL query for p%d: %s\n", int(quantile*100), quantileQuery)
74
75 // Example using the standard rate-based approach
76 rateQuery := calculateQuantileWithRate(metric, quantile, duration)
77 fmt.Printf("Generated PromQL query using rate: %s\n", rateQuery)
78}
Algorithm description viewbox

Calculate Histogram Quantile

Algorithm description:

This scenario involves calculating a specific quantile (e.g., p95) from a histogram metric in PromQL. Histograms record observations into buckets, and this query aggregates these buckets over a time window to estimate the value below which a certain percentage of observations fall. This is crucial for understanding latency distributions and identifying performance bottlenecks.

Algorithm explanation:

The `histogram_quantile(quantile, bucket_rate)` function in PromQL is used to calculate quantiles from histogram metrics. It requires a `quantile` value (between 0 and 1) and a `bucket_rate` series. The `bucket_rate` is typically derived by applying `rate()` to the `_bucket` metric of the histogram, aggregated by the `le` (less than or equal to) label. This calculates the per-second rate of observations falling into each bucket over the specified `duration`. The `histogram_quantile` function then interpolates between buckets to estimate the value at the desired quantile. The `sum by (le)` clause is essential to aggregate buckets correctly. Time complexity is O(N*M) where N is the number of time series and M is the number of buckets, as it iterates through buckets for each series. Space complexity is O(N) to store intermediate results. Edge cases include invalid quantile values, non-positive durations, and missing `_bucket` metrics.

Pseudocode:

function calculateHistogramQuantile(metricName, quantile, duration, labelsToSum):
  if metricName is empty or quantile is invalid or duration is not positive:
    return error message
  
  bucketQuery = "sum by (" + labelsToSum + ") (" + metricName + "_bucket)"
  // Note: In PromQL, we typically apply rate() to the buckets directly.
  // This pseudocode simplifies the aggregation step.
  query = "histogram_quantile(" + quantile + ", sum by (" + labelsToSum + ") (rate(" + metricName + "_bucket[" + duration + "])))"
  return query

function calculateQuantileWithRate(metricName, quantile, duration):
  // Similar checks
  query = "histogram_quantile(" + quantile + ", sum by (le) (rate(" + metricName + "_bucket[" + duration + "])))"
  return query