cloudfoundry-incubator/eirini

View on GitHub
prometheus/lrp_client.go

Summary

Maintainability
A
2 hrs
Test Coverage
B
86%
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
}