github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/ruler/base/manager_metrics_test.go (about)

     1  package base
     2  
     3  import (
     4  	"bytes"
     5  	"testing"
     6  
     7  	"github.com/prometheus/client_golang/prometheus"
     8  	"github.com/prometheus/client_golang/prometheus/promauto"
     9  	"github.com/prometheus/client_golang/prometheus/testutil"
    10  	dto "github.com/prometheus/client_model/go"
    11  	"github.com/stretchr/testify/assert"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestManagerMetricsWithRuleGroupLabel(t *testing.T) {
    16  	mainReg := prometheus.NewPedanticRegistry()
    17  
    18  	managerMetrics := NewManagerMetrics(false)
    19  	mainReg.MustRegister(managerMetrics)
    20  	managerMetrics.AddUserRegistry("user1", populateManager(1))
    21  	managerMetrics.AddUserRegistry("user2", populateManager(10))
    22  	managerMetrics.AddUserRegistry("user3", populateManager(100))
    23  
    24  	managerMetrics.AddUserRegistry("user4", populateManager(1000))
    25  	managerMetrics.RemoveUserRegistry("user4")
    26  
    27  	//noinspection ALL
    28  	err := testutil.GatherAndCompare(mainReg, bytes.NewBufferString(`
    29  # HELP cortex_prometheus_last_evaluation_samples The number of samples returned during the last rule group evaluation.
    30  # TYPE cortex_prometheus_last_evaluation_samples gauge
    31  cortex_prometheus_last_evaluation_samples{rule_group="group_one",user="user1"} 1000
    32  cortex_prometheus_last_evaluation_samples{rule_group="group_one",user="user2"} 10000
    33  cortex_prometheus_last_evaluation_samples{rule_group="group_one",user="user3"} 100000
    34  cortex_prometheus_last_evaluation_samples{rule_group="group_two",user="user1"} 1000
    35  cortex_prometheus_last_evaluation_samples{rule_group="group_two",user="user2"} 10000
    36  cortex_prometheus_last_evaluation_samples{rule_group="group_two",user="user3"} 100000
    37  # HELP cortex_prometheus_rule_evaluation_duration_seconds The duration for a rule to execute.
    38  # TYPE cortex_prometheus_rule_evaluation_duration_seconds summary
    39  cortex_prometheus_rule_evaluation_duration_seconds{user="user1",quantile="0.5"} 1
    40  cortex_prometheus_rule_evaluation_duration_seconds{user="user1",quantile="0.9"} 1
    41  cortex_prometheus_rule_evaluation_duration_seconds{user="user1",quantile="0.99"} 1
    42  cortex_prometheus_rule_evaluation_duration_seconds_sum{user="user1"} 1
    43  cortex_prometheus_rule_evaluation_duration_seconds_count{user="user1"} 1
    44  cortex_prometheus_rule_evaluation_duration_seconds{user="user2",quantile="0.5"} 10
    45  cortex_prometheus_rule_evaluation_duration_seconds{user="user2",quantile="0.9"} 10
    46  cortex_prometheus_rule_evaluation_duration_seconds{user="user2",quantile="0.99"} 10
    47  cortex_prometheus_rule_evaluation_duration_seconds_sum{user="user2"} 10
    48  cortex_prometheus_rule_evaluation_duration_seconds_count{user="user2"} 1
    49  cortex_prometheus_rule_evaluation_duration_seconds{user="user3",quantile="0.5"} 100
    50  cortex_prometheus_rule_evaluation_duration_seconds{user="user3",quantile="0.9"} 100
    51  cortex_prometheus_rule_evaluation_duration_seconds{user="user3",quantile="0.99"} 100
    52  cortex_prometheus_rule_evaluation_duration_seconds_sum{user="user3"} 100
    53  cortex_prometheus_rule_evaluation_duration_seconds_count{user="user3"} 1
    54  # HELP cortex_prometheus_rule_evaluation_failures_total The total number of rule evaluation failures.
    55  # TYPE cortex_prometheus_rule_evaluation_failures_total counter
    56  cortex_prometheus_rule_evaluation_failures_total{rule_group="group_one",user="user1"} 1
    57  cortex_prometheus_rule_evaluation_failures_total{rule_group="group_one",user="user2"} 10
    58  cortex_prometheus_rule_evaluation_failures_total{rule_group="group_one",user="user3"} 100
    59  cortex_prometheus_rule_evaluation_failures_total{rule_group="group_two",user="user1"} 1
    60  cortex_prometheus_rule_evaluation_failures_total{rule_group="group_two",user="user2"} 10
    61  cortex_prometheus_rule_evaluation_failures_total{rule_group="group_two",user="user3"} 100
    62  # HELP cortex_prometheus_rule_evaluations_total The total number of rule evaluations.
    63  # TYPE cortex_prometheus_rule_evaluations_total counter
    64  cortex_prometheus_rule_evaluations_total{rule_group="group_one",user="user1"} 1
    65  cortex_prometheus_rule_evaluations_total{rule_group="group_one",user="user2"} 10
    66  cortex_prometheus_rule_evaluations_total{rule_group="group_one",user="user3"} 100
    67  cortex_prometheus_rule_evaluations_total{rule_group="group_two",user="user1"} 1
    68  cortex_prometheus_rule_evaluations_total{rule_group="group_two",user="user2"} 10
    69  cortex_prometheus_rule_evaluations_total{rule_group="group_two",user="user3"} 100
    70  # HELP cortex_prometheus_rule_group_duration_seconds The duration of rule group evaluations.
    71  # TYPE cortex_prometheus_rule_group_duration_seconds summary
    72  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.01"} 1
    73  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.05"} 1
    74  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.5"} 1
    75  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.9"} 1
    76  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.99"} 1
    77  cortex_prometheus_rule_group_duration_seconds_sum{user="user1"} 1
    78  cortex_prometheus_rule_group_duration_seconds_count{user="user1"} 1
    79  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.01"} 10
    80  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.05"} 10
    81  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.5"} 10
    82  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.9"} 10
    83  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.99"} 10
    84  cortex_prometheus_rule_group_duration_seconds_sum{user="user2"} 10
    85  cortex_prometheus_rule_group_duration_seconds_count{user="user2"} 1
    86  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.01"} 100
    87  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.05"} 100
    88  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.5"} 100
    89  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.9"} 100
    90  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.99"} 100
    91  cortex_prometheus_rule_group_duration_seconds_sum{user="user3"} 100
    92  cortex_prometheus_rule_group_duration_seconds_count{user="user3"} 1
    93  # HELP cortex_prometheus_rule_group_iterations_missed_total The total number of rule group evaluations missed due to slow rule group evaluation.
    94  # TYPE cortex_prometheus_rule_group_iterations_missed_total counter
    95  cortex_prometheus_rule_group_iterations_missed_total{rule_group="group_one",user="user1"} 1
    96  cortex_prometheus_rule_group_iterations_missed_total{rule_group="group_one",user="user2"} 10
    97  cortex_prometheus_rule_group_iterations_missed_total{rule_group="group_one",user="user3"} 100
    98  cortex_prometheus_rule_group_iterations_missed_total{rule_group="group_two",user="user1"} 1
    99  cortex_prometheus_rule_group_iterations_missed_total{rule_group="group_two",user="user2"} 10
   100  cortex_prometheus_rule_group_iterations_missed_total{rule_group="group_two",user="user3"} 100
   101  # HELP cortex_prometheus_rule_group_iterations_total The total number of scheduled rule group evaluations, whether executed or missed.
   102  # TYPE cortex_prometheus_rule_group_iterations_total counter
   103  cortex_prometheus_rule_group_iterations_total{rule_group="group_one",user="user1"} 1
   104  cortex_prometheus_rule_group_iterations_total{rule_group="group_one",user="user2"} 10
   105  cortex_prometheus_rule_group_iterations_total{rule_group="group_one",user="user3"} 100
   106  cortex_prometheus_rule_group_iterations_total{rule_group="group_two",user="user1"} 1
   107  cortex_prometheus_rule_group_iterations_total{rule_group="group_two",user="user2"} 10
   108  cortex_prometheus_rule_group_iterations_total{rule_group="group_two",user="user3"} 100
   109  # HELP cortex_prometheus_rule_group_last_duration_seconds The duration of the last rule group evaluation.
   110  # TYPE cortex_prometheus_rule_group_last_duration_seconds gauge
   111  cortex_prometheus_rule_group_last_duration_seconds{rule_group="group_one",user="user1"} 1000
   112  cortex_prometheus_rule_group_last_duration_seconds{rule_group="group_one",user="user2"} 10000
   113  cortex_prometheus_rule_group_last_duration_seconds{rule_group="group_one",user="user3"} 100000
   114  cortex_prometheus_rule_group_last_duration_seconds{rule_group="group_two",user="user1"} 1000
   115  cortex_prometheus_rule_group_last_duration_seconds{rule_group="group_two",user="user2"} 10000
   116  cortex_prometheus_rule_group_last_duration_seconds{rule_group="group_two",user="user3"} 100000
   117  # HELP cortex_prometheus_rule_group_last_evaluation_timestamp_seconds The timestamp of the last rule group evaluation in seconds.
   118  # TYPE cortex_prometheus_rule_group_last_evaluation_timestamp_seconds gauge
   119  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{rule_group="group_one",user="user1"} 1000
   120  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{rule_group="group_one",user="user2"} 10000
   121  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{rule_group="group_one",user="user3"} 100000
   122  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{rule_group="group_two",user="user1"} 1000
   123  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{rule_group="group_two",user="user2"} 10000
   124  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{rule_group="group_two",user="user3"} 100000
   125  # HELP cortex_prometheus_rule_group_rules The number of rules.
   126  # TYPE cortex_prometheus_rule_group_rules gauge
   127  cortex_prometheus_rule_group_rules{rule_group="group_one",user="user1"} 1000
   128  cortex_prometheus_rule_group_rules{rule_group="group_one",user="user2"} 10000
   129  cortex_prometheus_rule_group_rules{rule_group="group_one",user="user3"} 100000
   130  cortex_prometheus_rule_group_rules{rule_group="group_two",user="user1"} 1000
   131  cortex_prometheus_rule_group_rules{rule_group="group_two",user="user2"} 10000
   132  cortex_prometheus_rule_group_rules{rule_group="group_two",user="user3"} 100000
   133  `))
   134  	require.NoError(t, err)
   135  }
   136  
   137  func TestManagerMetricsWithoutRuleGroupLabel(t *testing.T) {
   138  	mainReg := prometheus.NewPedanticRegistry()
   139  
   140  	managerMetrics := NewManagerMetrics(true)
   141  	mainReg.MustRegister(managerMetrics)
   142  	managerMetrics.AddUserRegistry("user1", populateManager(1))
   143  	managerMetrics.AddUserRegistry("user2", populateManager(10))
   144  	managerMetrics.AddUserRegistry("user3", populateManager(100))
   145  
   146  	managerMetrics.AddUserRegistry("user4", populateManager(1000))
   147  	managerMetrics.RemoveUserRegistry("user4")
   148  
   149  	//noinspection ALL
   150  	err := testutil.GatherAndCompare(mainReg, bytes.NewBufferString(`
   151  # HELP cortex_prometheus_last_evaluation_samples The number of samples returned during the last rule group evaluation.
   152  # TYPE cortex_prometheus_last_evaluation_samples gauge
   153  cortex_prometheus_last_evaluation_samples{user="user1"} 2000
   154  cortex_prometheus_last_evaluation_samples{user="user2"} 20000
   155  cortex_prometheus_last_evaluation_samples{user="user3"} 200000
   156  # HELP cortex_prometheus_rule_evaluation_duration_seconds The duration for a rule to execute.
   157  # TYPE cortex_prometheus_rule_evaluation_duration_seconds summary
   158  cortex_prometheus_rule_evaluation_duration_seconds{user="user1",quantile="0.5"} 1
   159  cortex_prometheus_rule_evaluation_duration_seconds{user="user1",quantile="0.9"} 1
   160  cortex_prometheus_rule_evaluation_duration_seconds{user="user1",quantile="0.99"} 1
   161  cortex_prometheus_rule_evaluation_duration_seconds_sum{user="user1"} 1
   162  cortex_prometheus_rule_evaluation_duration_seconds_count{user="user1"} 1
   163  cortex_prometheus_rule_evaluation_duration_seconds{user="user2",quantile="0.5"} 10
   164  cortex_prometheus_rule_evaluation_duration_seconds{user="user2",quantile="0.9"} 10
   165  cortex_prometheus_rule_evaluation_duration_seconds{user="user2",quantile="0.99"} 10
   166  cortex_prometheus_rule_evaluation_duration_seconds_sum{user="user2"} 10
   167  cortex_prometheus_rule_evaluation_duration_seconds_count{user="user2"} 1
   168  cortex_prometheus_rule_evaluation_duration_seconds{user="user3",quantile="0.5"} 100
   169  cortex_prometheus_rule_evaluation_duration_seconds{user="user3",quantile="0.9"} 100
   170  cortex_prometheus_rule_evaluation_duration_seconds{user="user3",quantile="0.99"} 100
   171  cortex_prometheus_rule_evaluation_duration_seconds_sum{user="user3"} 100
   172  cortex_prometheus_rule_evaluation_duration_seconds_count{user="user3"} 1
   173  # HELP cortex_prometheus_rule_evaluation_failures_total The total number of rule evaluation failures.
   174  # TYPE cortex_prometheus_rule_evaluation_failures_total counter
   175  cortex_prometheus_rule_evaluation_failures_total{user="user1"} 2
   176  cortex_prometheus_rule_evaluation_failures_total{user="user2"} 20
   177  cortex_prometheus_rule_evaluation_failures_total{user="user3"} 200
   178  # HELP cortex_prometheus_rule_evaluations_total The total number of rule evaluations.
   179  # TYPE cortex_prometheus_rule_evaluations_total counter
   180  cortex_prometheus_rule_evaluations_total{user="user1"} 2
   181  cortex_prometheus_rule_evaluations_total{user="user2"} 20
   182  cortex_prometheus_rule_evaluations_total{user="user3"} 200
   183  # HELP cortex_prometheus_rule_group_duration_seconds The duration of rule group evaluations.
   184  # TYPE cortex_prometheus_rule_group_duration_seconds summary
   185  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.01"} 1
   186  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.05"} 1
   187  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.5"} 1
   188  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.9"} 1
   189  cortex_prometheus_rule_group_duration_seconds{user="user1",quantile="0.99"} 1
   190  cortex_prometheus_rule_group_duration_seconds_sum{user="user1"} 1
   191  cortex_prometheus_rule_group_duration_seconds_count{user="user1"} 1
   192  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.01"} 10
   193  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.05"} 10
   194  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.5"} 10
   195  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.9"} 10
   196  cortex_prometheus_rule_group_duration_seconds{user="user2",quantile="0.99"} 10
   197  cortex_prometheus_rule_group_duration_seconds_sum{user="user2"} 10
   198  cortex_prometheus_rule_group_duration_seconds_count{user="user2"} 1
   199  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.01"} 100
   200  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.05"} 100
   201  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.5"} 100
   202  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.9"} 100
   203  cortex_prometheus_rule_group_duration_seconds{user="user3",quantile="0.99"} 100
   204  cortex_prometheus_rule_group_duration_seconds_sum{user="user3"} 100
   205  cortex_prometheus_rule_group_duration_seconds_count{user="user3"} 1
   206  # HELP cortex_prometheus_rule_group_iterations_missed_total The total number of rule group evaluations missed due to slow rule group evaluation.
   207  # TYPE cortex_prometheus_rule_group_iterations_missed_total counter
   208  cortex_prometheus_rule_group_iterations_missed_total{user="user1"} 2
   209  cortex_prometheus_rule_group_iterations_missed_total{user="user2"} 20
   210  cortex_prometheus_rule_group_iterations_missed_total{user="user3"} 200
   211  # HELP cortex_prometheus_rule_group_iterations_total The total number of scheduled rule group evaluations, whether executed or missed.
   212  # TYPE cortex_prometheus_rule_group_iterations_total counter
   213  cortex_prometheus_rule_group_iterations_total{user="user1"} 2
   214  cortex_prometheus_rule_group_iterations_total{user="user2"} 20
   215  cortex_prometheus_rule_group_iterations_total{user="user3"} 200
   216  # HELP cortex_prometheus_rule_group_last_duration_seconds The duration of the last rule group evaluation.
   217  # TYPE cortex_prometheus_rule_group_last_duration_seconds gauge
   218  cortex_prometheus_rule_group_last_duration_seconds{user="user1"} 2000
   219  cortex_prometheus_rule_group_last_duration_seconds{user="user2"} 20000
   220  cortex_prometheus_rule_group_last_duration_seconds{user="user3"} 200000
   221  # HELP cortex_prometheus_rule_group_last_evaluation_timestamp_seconds The timestamp of the last rule group evaluation in seconds.
   222  # TYPE cortex_prometheus_rule_group_last_evaluation_timestamp_seconds gauge
   223  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{user="user1"} 2000
   224  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{user="user2"} 20000
   225  cortex_prometheus_rule_group_last_evaluation_timestamp_seconds{user="user3"} 200000
   226  # HELP cortex_prometheus_rule_group_rules The number of rules.
   227  # TYPE cortex_prometheus_rule_group_rules gauge
   228  cortex_prometheus_rule_group_rules{user="user1"} 2000
   229  cortex_prometheus_rule_group_rules{user="user2"} 20000
   230  cortex_prometheus_rule_group_rules{user="user3"} 200000
   231  `))
   232  	require.NoError(t, err)
   233  }
   234  
   235  func populateManager(base float64) *prometheus.Registry {
   236  	r := prometheus.NewRegistry()
   237  
   238  	metrics := newGroupMetrics(r)
   239  
   240  	metrics.evalDuration.Observe(base)
   241  	metrics.iterationDuration.Observe(base)
   242  
   243  	metrics.iterationsScheduled.WithLabelValues("group_one").Add(base)
   244  	metrics.iterationsScheduled.WithLabelValues("group_two").Add(base)
   245  	metrics.iterationsMissed.WithLabelValues("group_one").Add(base)
   246  	metrics.iterationsMissed.WithLabelValues("group_two").Add(base)
   247  	metrics.evalTotal.WithLabelValues("group_one").Add(base)
   248  	metrics.evalTotal.WithLabelValues("group_two").Add(base)
   249  	metrics.evalFailures.WithLabelValues("group_one").Add(base)
   250  	metrics.evalFailures.WithLabelValues("group_two").Add(base)
   251  
   252  	metrics.groupLastEvalTime.WithLabelValues("group_one").Add(base * 1000)
   253  	metrics.groupLastEvalTime.WithLabelValues("group_two").Add(base * 1000)
   254  
   255  	metrics.groupLastDuration.WithLabelValues("group_one").Add(base * 1000)
   256  	metrics.groupLastDuration.WithLabelValues("group_two").Add(base * 1000)
   257  
   258  	metrics.groupRules.WithLabelValues("group_one").Add(base * 1000)
   259  	metrics.groupRules.WithLabelValues("group_two").Add(base * 1000)
   260  
   261  	metrics.groupLastEvalSamples.WithLabelValues("group_one").Add(base * 1000)
   262  	metrics.groupLastEvalSamples.WithLabelValues("group_two").Add(base * 1000)
   263  
   264  	return r
   265  }
   266  
   267  // Copied from github.com/prometheus/rules/manager.go
   268  type groupMetrics struct {
   269  	evalDuration         prometheus.Summary
   270  	iterationDuration    prometheus.Summary
   271  	iterationsMissed     *prometheus.CounterVec
   272  	iterationsScheduled  *prometheus.CounterVec
   273  	evalTotal            *prometheus.CounterVec
   274  	evalFailures         *prometheus.CounterVec
   275  	groupInterval        *prometheus.GaugeVec
   276  	groupLastEvalTime    *prometheus.GaugeVec
   277  	groupLastDuration    *prometheus.GaugeVec
   278  	groupRules           *prometheus.GaugeVec
   279  	groupLastEvalSamples *prometheus.GaugeVec
   280  }
   281  
   282  func newGroupMetrics(r prometheus.Registerer) *groupMetrics {
   283  	m := &groupMetrics{
   284  		evalDuration: promauto.With(r).NewSummary(
   285  			prometheus.SummaryOpts{
   286  				Name:       "prometheus_rule_evaluation_duration_seconds",
   287  				Help:       "The duration for a rule to execute.",
   288  				Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
   289  			}),
   290  		iterationDuration: promauto.With(r).NewSummary(prometheus.SummaryOpts{
   291  			Name:       "prometheus_rule_group_duration_seconds",
   292  			Help:       "The duration of rule group evaluations.",
   293  			Objectives: map[float64]float64{0.01: 0.001, 0.05: 0.005, 0.5: 0.05, 0.90: 0.01, 0.99: 0.001},
   294  		}),
   295  		iterationsMissed: promauto.With(r).NewCounterVec(
   296  			prometheus.CounterOpts{
   297  				Name: "prometheus_rule_group_iterations_missed_total",
   298  				Help: "The total number of rule group evaluations missed due to slow rule group evaluation.",
   299  			},
   300  			[]string{"rule_group"},
   301  		),
   302  		iterationsScheduled: promauto.With(r).NewCounterVec(
   303  			prometheus.CounterOpts{
   304  				Name: "prometheus_rule_group_iterations_total",
   305  				Help: "The total number of scheduled rule group evaluations, whether executed or missed.",
   306  			},
   307  			[]string{"rule_group"},
   308  		),
   309  		evalTotal: promauto.With(r).NewCounterVec(
   310  			prometheus.CounterOpts{
   311  				Name: "prometheus_rule_evaluations_total",
   312  				Help: "The total number of rule evaluations.",
   313  			},
   314  			[]string{"rule_group"},
   315  		),
   316  		evalFailures: promauto.With(r).NewCounterVec(
   317  			prometheus.CounterOpts{
   318  				Name: "prometheus_rule_evaluation_failures_total",
   319  				Help: "The total number of rule evaluation failures.",
   320  			},
   321  			[]string{"rule_group"},
   322  		),
   323  		groupInterval: promauto.With(r).NewGaugeVec(
   324  			prometheus.GaugeOpts{
   325  				Name: "prometheus_rule_group_interval_seconds",
   326  				Help: "The interval of a rule group.",
   327  			},
   328  			[]string{"rule_group"},
   329  		),
   330  		groupLastEvalTime: promauto.With(r).NewGaugeVec(
   331  			prometheus.GaugeOpts{
   332  				Name: "prometheus_rule_group_last_evaluation_timestamp_seconds",
   333  				Help: "The timestamp of the last rule group evaluation in seconds.",
   334  			},
   335  			[]string{"rule_group"},
   336  		),
   337  		groupLastDuration: promauto.With(r).NewGaugeVec(
   338  			prometheus.GaugeOpts{
   339  				Name: "prometheus_rule_group_last_duration_seconds",
   340  				Help: "The duration of the last rule group evaluation.",
   341  			},
   342  			[]string{"rule_group"},
   343  		),
   344  		groupRules: promauto.With(r).NewGaugeVec(
   345  			prometheus.GaugeOpts{
   346  				Name: "prometheus_rule_group_rules",
   347  				Help: "The number of rules.",
   348  			},
   349  			[]string{"rule_group"},
   350  		),
   351  		groupLastEvalSamples: promauto.With(r).NewGaugeVec(
   352  			prometheus.GaugeOpts{
   353  				Name: "prometheus_rule_group_last_evaluation_samples",
   354  				Help: "The number of samples returned during the last rule group evaluation.",
   355  			},
   356  			[]string{"rule_group"},
   357  		),
   358  	}
   359  
   360  	return m
   361  }
   362  
   363  func TestMetricsArePerUser(t *testing.T) {
   364  	mainReg := prometheus.NewPedanticRegistry()
   365  
   366  	managerMetrics := NewManagerMetrics(true)
   367  	mainReg.MustRegister(managerMetrics)
   368  	managerMetrics.AddUserRegistry("user1", populateManager(1))
   369  	managerMetrics.AddUserRegistry("user2", populateManager(10))
   370  	managerMetrics.AddUserRegistry("user3", populateManager(100))
   371  
   372  	ch := make(chan prometheus.Metric)
   373  
   374  	defer func() {
   375  		// drain the channel, so that collecting gouroutine can stop.
   376  		// This is useful if test fails.
   377  		for range ch {
   378  		}
   379  	}()
   380  
   381  	go func() {
   382  		managerMetrics.Collect(ch)
   383  		close(ch)
   384  	}()
   385  
   386  	for m := range ch {
   387  		desc := m.Desc()
   388  
   389  		dtoM := &dto.Metric{}
   390  		err := m.Write(dtoM)
   391  
   392  		require.NoError(t, err)
   393  
   394  		foundUserLabel := false
   395  		for _, l := range dtoM.Label {
   396  			if l.GetName() == "user" {
   397  				foundUserLabel = true
   398  				break
   399  			}
   400  		}
   401  
   402  		assert.True(t, foundUserLabel, "user label not found for metric %s", desc.String())
   403  	}
   404  }