prometheus/lrp_client.go
package prometheus
import (
"context"
"errors"
"code.cloudfoundry.org/eirini/api"
"code.cloudfoundry.org/eirini/k8s/shared"
"code.cloudfoundry.org/lager"
prometheus_api "github.com/prometheus/client_golang/prometheus"
"k8s.io/utils/clock"
)
const (
LRPCreations = "eirini_lrp_creations"
LRPCreationsHelp = "The total number of created lrps"
LRPCreationDurations = "eirini_lrp_creation_durations"
LRPCreationDurationsHelp = "The duration of lrp creations"
)
//counterfeiter:generate . LRPClient
type LRPClient interface {
Desire(ctx context.Context, namespace string, lrp *api.LRP, opts ...shared.Option) error
Get(ctx context.Context, identifier api.LRPIdentifier) (*api.LRP, error)
Update(ctx context.Context, lrp *api.LRP) error
}
type LRPClientDecorator struct {
LRPClient
logger lager.Logger
creations prometheus_api.Counter
creationDurations prometheus_api.Histogram
clock clock.PassiveClock
}
func NewLRPClientDecorator(
logger lager.Logger,
lrpClient LRPClient,
registry prometheus_api.Registerer,
clck clock.PassiveClock,
) (*LRPClientDecorator, error) {
creations, err := registerCounter(registry, LRPCreations, "The total number of created lrps")
if err != nil {
return nil, err
}
creationDurations, err := registerHistogram(registry, LRPCreationDurations, LRPCreationDurationsHelp)
if err != nil {
return nil, err
}
return &LRPClientDecorator{
LRPClient: lrpClient,
logger: logger,
creations: creations,
creationDurations: creationDurations,
clock: clck,
}, nil
}
func (d *LRPClientDecorator) Desire(ctx context.Context, namespace string, lrp *api.LRP, opts ...shared.Option) error {
start := d.clock.Now()
err := d.LRPClient.Desire(ctx, namespace, lrp, opts...)
if err == nil {
d.creations.Inc()
d.creationDurations.Observe(float64(d.clock.Since(start).Milliseconds()))
}
return err
}
func registerCounter(registry prometheus_api.Registerer, name, help string) (prometheus_api.Counter, error) {
c := prometheus_api.NewCounter(prometheus_api.CounterOpts{
Name: name,
Help: help,
})
err := registry.Register(c)
if err == nil {
return c, nil
}
var are prometheus_api.AlreadyRegisteredError
if errors.As(err, &are) {
return are.ExistingCollector.(prometheus_api.Counter), nil //nolint:forcetypeassert
}
return nil, err
}
func registerHistogram(registry prometheus_api.Registerer, name, help string) (prometheus_api.Histogram, error) {
h := prometheus_api.NewHistogram(prometheus_api.HistogramOpts{
Name: name,
Help: help,
})
err := registry.Register(h)
if err == nil {
return h, nil
}
var are prometheus_api.AlreadyRegisteredError
if errors.As(err, &are) {
return are.ExistingCollector.(prometheus_api.Histogram), nil //nolint:forcetypeassert
}
return nil, err
}