@@ -16,8 +16,8 @@ import (
1616 "github.com/prometheus/prometheus/config"
1717 "github.com/prometheus/prometheus/notifier"
1818 "github.com/prometheus/prometheus/promql"
19- "github.com/prometheus/prometheus/rules"
20- "github.com/prometheus/prometheus/storage"
19+ promRules "github.com/prometheus/prometheus/rules"
20+ promStorage "github.com/prometheus/prometheus/storage"
2121 "github.com/prometheus/prometheus/util/strutil"
2222 "golang.org/x/net/context"
2323 "golang.org/x/net/context/ctxhttp"
@@ -48,12 +48,10 @@ var (
4848 Name : "ruler_ring_check_errors_total" ,
4949 Help : "Number of errors that have occurred when checking the ring for ownership" ,
5050 })
51- ruleMetrics * rules.Metrics
5251)
5352
5453func init () {
5554 evalDuration .Register ()
56- ruleMetrics = rules .NewGroupMetrics (prometheus .DefaultRegisterer )
5755}
5856
5957// Config is the configuration for the recording rules server.
@@ -113,7 +111,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
113111type Ruler struct {
114112 cfg Config
115113 engine * promql.Engine
116- queryable storage .Queryable
114+ queryable promStorage .Queryable
117115 pusher Pusher
118116 alertURL * url.URL
119117 notifierCfg * config.Config
@@ -127,10 +125,14 @@ type Ruler struct {
127125 // Per-user notifiers with separate queues.
128126 notifiersMtx sync.Mutex
129127 notifiers map [string ]* rulerNotifier
128+
129+ // Per-user rules metrics
130+ userMetricsMtx sync.Mutex
131+ userMetrics map [string ]* promRules.Metrics
130132}
131133
132134// NewRuler creates a new ruler from a distributor and chunk store.
133- func NewRuler (cfg Config , engine * promql.Engine , queryable storage .Queryable , d * distributor.Distributor , rulesAPI client.Client ) (* Ruler , error ) {
135+ func NewRuler (cfg Config , engine * promql.Engine , queryable promStorage .Queryable , d * distributor.Distributor , rulesAPI client.Client ) (* Ruler , error ) {
134136 if cfg .NumWorkers <= 0 {
135137 return nil , fmt .Errorf ("must have at least 1 worker, got %d" , cfg .NumWorkers )
136138 }
@@ -149,6 +151,7 @@ func NewRuler(cfg Config, engine *promql.Engine, queryable storage.Queryable, d
149151 notifierCfg : ncfg ,
150152 notifiers : map [string ]* rulerNotifier {},
151153 workerWG : & sync.WaitGroup {},
154+ userMetrics : map [string ]* promRules.Metrics {},
152155 }
153156
154157 ruler .scheduler = newScheduler (rulesAPI , cfg .EvaluationInterval , cfg .EvaluationInterval , ruler .newGroup )
@@ -208,35 +211,47 @@ func (r *Ruler) Stop() {
208211 }
209212}
210213
211- func (r * Ruler ) newGroup (userID string , groupName string , rls []rules .Rule ) (* group , error ) {
214+ func (r * Ruler ) newGroup (user string , groupName string , rls []promRules .Rule ) (* group , error ) {
212215 appendable := & appendableAppender {pusher : r .pusher }
213- notifier , err := r .getOrCreateNotifier (userID )
216+ notifier , err := r .getOrCreateNotifier (user )
214217 if err != nil {
215218 return nil , err
216219 }
217- opts := & rules.ManagerOptions {
220+
221+ // Get the rule group metrics for set user or create it if it does not exist
222+ r .userMetricsMtx .Lock ()
223+ metrics , exists := r .userMetrics [user ]
224+ if ! exists {
225+ // Wrap the default register with the users ID and pass
226+ reg := prometheus .WrapRegistererWith (prometheus.Labels {"user" : user }, prometheus .DefaultRegisterer )
227+ metrics = promRules .NewGroupMetrics (reg )
228+ r .userMetrics [user ] = metrics
229+ }
230+ r .userMetricsMtx .Unlock ()
231+
232+ opts := & promRules.ManagerOptions {
218233 Appendable : appendable ,
219- QueryFunc : rules .EngineQueryFunc (r .engine , r .queryable ),
234+ QueryFunc : promRules .EngineQueryFunc (r .engine , r .queryable ),
220235 Context : context .Background (),
221236 ExternalURL : r .alertURL ,
222237 NotifyFunc : sendAlerts (notifier , r .alertURL .String ()),
223238 Logger : util .Logger ,
224- Metrics : ruleMetrics ,
239+ Metrics : metrics ,
225240 }
226241 return newGroup (groupName , rls , appendable , opts ), nil
227242}
228243
229- // sendAlerts implements a rules .NotifyFunc for a Notifier.
244+ // sendAlerts implements a promRules .NotifyFunc for a Notifier.
230245// It filters any non-firing alerts from the input.
231246//
232247// Copied from Prometheus's main.go.
233- func sendAlerts (n * notifier.Manager , externalURL string ) rules .NotifyFunc {
234- return func (ctx native_ctx.Context , expr string , alerts ... * rules .Alert ) {
248+ func sendAlerts (n * notifier.Manager , externalURL string ) promRules .NotifyFunc {
249+ return func (ctx native_ctx.Context , expr string , alerts ... * promRules .Alert ) {
235250 var res []* notifier.Alert
236251
237252 for _ , alert := range alerts {
238253 // Only send actually firing alerts.
239- if alert .State == rules .StatePending {
254+ if alert .State == promRules .StatePending {
240255 continue
241256 }
242257 a := & notifier.Alert {
0 commit comments