Skip to content

Commit

Permalink
metrics: Simplify Group interface
Browse files Browse the repository at this point in the history
Get rid of RegisterWithInit method. Instead, check inside Register method if
the registered collector implements CollectorWithInit.

Signed-off-by: Anna Kapuscinska <anna@isovalent.com>
  • Loading branch information
lambdanis committed Jul 3, 2024
1 parent 92e5dfa commit 8fd8005
Showing 1 changed file with 47 additions and 54 deletions.
101 changes: 47 additions & 54 deletions pkg/metrics/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,37 +9,34 @@ import (
"github.com/prometheus/client_golang/prometheus"
)

// CollectorWithInit extends prometheus.Collector with methods for metrics
// initialization and checking constraints.
type CollectorWithInit interface {
prometheus.Collector
// initializer contains methods for metrics initialization and checking
// constraints.
type initializer interface {
IsConstrained() bool
Init()
InitForDocs()
}

// Group extends prometheus.Registerer with methods for metrics
// initialization and checking constraints. It also includes
// prometheus.Collector, because MetricsGroups are intended to be registered in
// a root prometheus.Registry.
type Group interface {
// CollectorWithInit extends prometheus.Collector with initializer.
type CollectorWithInit interface {
prometheus.Collector
initializer
}

// Group extends prometheus.Registerer with CollectorWithInit.
// It represents a sub-registry of the root prometheus.Registry.
type Group interface {
prometheus.Registerer
RegisterWithInit(CollectorWithInit) error
MustRegisterWithInit(CollectorWithInit)
CollectorWithInit
ExtendInit(func())
ExtendInitForDocs(func())
IsConstrained() bool
Init()
InitForDocs()
}

// metricsGroup wraps prometheus.Registry and implements Group
type metricsGroup struct {
registry *prometheus.Registry
// If constrained is true, group will only accept metrics with constrained
// cardinality - but this is checked only for metrics registered with
// (Must)RegisterWithInit.
// If constrained is true, group will accept collectors implementing
// initializer only if they are constrained.
constrained bool
initFunc func()
initForDocsFunc func()
Expand All @@ -66,65 +63,61 @@ func (r *metricsGroup) Collect(ch chan<- prometheus.Metric) {
}

// Register implements Group (prometheus.Registerer).
//
// It wraps the Register method of the underlying registry. Additionally, if
// the collector implements initializer, it:
// - checks constraints - attempt to register an unconstrained collector in
// a constrained group results in an error
// - extends Init and InitForDocs methods with initialization of the
// registered collector
func (r *metricsGroup) Register(c prometheus.Collector) error {
return r.registry.Register(c)
cc, hasInit := c.(initializer)
if hasInit {
// check constraints
if r.IsConstrained() && !cc.IsConstrained() {
return errors.New("can't register unconstrained metrics in a constrained group")
}
}
// register
err := r.registry.Register(c)
if err != nil {
return err
}
if hasInit {
// extend init
r.ExtendInit(cc.Init)
r.ExtendInitForDocs(cc.InitForDocs)
}
return nil
}

// MustRegister implements Group (prometheus.Registerer).
func (r *metricsGroup) MustRegister(cs ...prometheus.Collector) {
r.registry.MustRegister(cs...)
for _, c := range cs {
if err := r.Register(c); err != nil {
panic(err)
}
}
}

// Unregister implements Group (prometheus.Registerer).
func (r *metricsGroup) Unregister(c prometheus.Collector) bool {
return r.registry.Unregister(c)
}

// IsConstrained implements Group.
// IsConstrained implements Group (initializer).
func (r *metricsGroup) IsConstrained() bool {
return r.constrained
}

// RegisterWithInit implements Group. It wraps Register method and
// additionally:
// - checks constraints - attempt to register an unconstrained collector in
// a constrained group results in an error
// - extends Init and InitForDocs methods with initialization of the
// registered collector
func (r *metricsGroup) RegisterWithInit(c CollectorWithInit) error {
// check constraints
if r.IsConstrained() && !c.IsConstrained() {
return errors.New("can't register unconstrained metrics in a constrained group")
}

// register
err := r.Register(c)
if err != nil {
return err
}

// extend init
r.ExtendInit(c.Init)
r.ExtendInitForDocs(c.InitForDocs)
return nil
}

// MustRegisterWithInit implements Group.
func (r *metricsGroup) MustRegisterWithInit(c CollectorWithInit) {
err := r.RegisterWithInit(c)
if err != nil {
panic(err)
}
}

// Init implements Group.
// Init implements Group (initializer).
func (r *metricsGroup) Init() {
if r.initFunc != nil {
r.initFunc()
}
}

// InitForDocs implements Group.
// InitForDocs implements Group (initializer).
func (r *metricsGroup) InitForDocs() {
if r.initForDocsFunc != nil {
r.initForDocsFunc()
Expand Down

0 comments on commit 8fd8005

Please # to comment.