@@ -16,8 +16,8 @@ import (
16
16
"github.com/prometheus/prometheus/config"
17
17
"github.com/prometheus/prometheus/notifier"
18
18
"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"
21
21
"github.com/prometheus/prometheus/util/strutil"
22
22
"golang.org/x/net/context"
23
23
"golang.org/x/net/context/ctxhttp"
@@ -48,12 +48,10 @@ var (
48
48
Name : "ruler_ring_check_errors_total" ,
49
49
Help : "Number of errors that have occurred when checking the ring for ownership" ,
50
50
})
51
- ruleMetrics * rules.Metrics
52
51
)
53
52
54
53
func init () {
55
54
evalDuration .Register ()
56
- ruleMetrics = rules .NewGroupMetrics (prometheus .DefaultRegisterer )
57
55
}
58
56
59
57
// Config is the configuration for the recording rules server.
@@ -113,7 +111,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) {
113
111
type Ruler struct {
114
112
cfg Config
115
113
engine * promql.Engine
116
- queryable storage .Queryable
114
+ queryable promStorage .Queryable
117
115
pusher Pusher
118
116
alertURL * url.URL
119
117
notifierCfg * config.Config
@@ -127,10 +125,14 @@ type Ruler struct {
127
125
// Per-user notifiers with separate queues.
128
126
notifiersMtx sync.Mutex
129
127
notifiers map [string ]* rulerNotifier
128
+
129
+ // Per-user rules metrics
130
+ userMetricsMtx sync.Mutex
131
+ userMetrics map [string ]* promRules.Metrics
130
132
}
131
133
132
134
// 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 ) {
134
136
if cfg .NumWorkers <= 0 {
135
137
return nil , fmt .Errorf ("must have at least 1 worker, got %d" , cfg .NumWorkers )
136
138
}
@@ -149,6 +151,7 @@ func NewRuler(cfg Config, engine *promql.Engine, queryable storage.Queryable, d
149
151
notifierCfg : ncfg ,
150
152
notifiers : map [string ]* rulerNotifier {},
151
153
workerWG : & sync.WaitGroup {},
154
+ userMetrics : map [string ]* promRules.Metrics {},
152
155
}
153
156
154
157
ruler .scheduler = newScheduler (rulesAPI , cfg .EvaluationInterval , cfg .EvaluationInterval , ruler .newGroup )
@@ -208,35 +211,47 @@ func (r *Ruler) Stop() {
208
211
}
209
212
}
210
213
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 ) {
212
215
appendable := & appendableAppender {pusher : r .pusher }
213
- notifier , err := r .getOrCreateNotifier (userID )
216
+ notifier , err := r .getOrCreateNotifier (user )
214
217
if err != nil {
215
218
return nil , err
216
219
}
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 {
218
233
Appendable : appendable ,
219
- QueryFunc : rules .EngineQueryFunc (r .engine , r .queryable ),
234
+ QueryFunc : promRules .EngineQueryFunc (r .engine , r .queryable ),
220
235
Context : context .Background (),
221
236
ExternalURL : r .alertURL ,
222
237
NotifyFunc : sendAlerts (notifier , r .alertURL .String ()),
223
238
Logger : util .Logger ,
224
- Metrics : ruleMetrics ,
239
+ Metrics : metrics ,
225
240
}
226
241
return newGroup (groupName , rls , appendable , opts ), nil
227
242
}
228
243
229
- // sendAlerts implements a rules .NotifyFunc for a Notifier.
244
+ // sendAlerts implements a promRules .NotifyFunc for a Notifier.
230
245
// It filters any non-firing alerts from the input.
231
246
//
232
247
// 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 ) {
235
250
var res []* notifier.Alert
236
251
237
252
for _ , alert := range alerts {
238
253
// Only send actually firing alerts.
239
- if alert .State == rules .StatePending {
254
+ if alert .State == promRules .StatePending {
240
255
continue
241
256
}
242
257
a := & notifier.Alert {
0 commit comments