Skip to content

Commit ba2a617

Browse files
committed
pass user id metrics to prom eval metrics in ruler
Signed-off-by: Jacob Lisi <[email protected]>
1 parent 10a93e8 commit ba2a617

File tree

1 file changed

+30
-15
lines changed

1 file changed

+30
-15
lines changed

pkg/ruler/ruler.go

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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

5453
func 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) {
113111
type 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

Comments
 (0)