diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 9d3b1488a..28ff33831 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -6,9 +6,8 @@ import ( "sync" "time" + "github.com/prometheus/client_golang/prometheus" "k8s.io/klog/v2" - - "github.com/hetznercloud/hcloud-cloud-controller-manager/internal/metrics" ) type Mode string @@ -63,9 +62,9 @@ type Cache[T any] struct { fetchAll func(ctx context.Context) ([]*T, error) getID func(value *T) int64 getName func(value *T) string - - defaultMaxAge time.Duration - defaultMode Mode + metric *prometheus.CounterVec + defaultMaxAge time.Duration + defaultMode Mode byID map[int64]*entry[T] byName map[string]*entry[T] @@ -79,6 +78,7 @@ func newCache[T any]( fetchAll func(ctx context.Context) ([]*T, error), getID func(value *T) int64, getName func(value *T) string, + metric *prometheus.CounterVec, defaultMode Mode, defaultMaxAge time.Duration, ) *Cache[T] { @@ -88,6 +88,7 @@ func newCache[T any]( fetchAll: fetchAll, getID: getID, getName: getName, + metric: metric, defaultMode: defaultMode, defaultMaxAge: defaultMaxAge, @@ -140,12 +141,12 @@ func (c *Cache[T]) All(ctx context.Context, opts ...RefreshOption) ([]*T, error) } if now.Sub(refreshedAllAt) > refreshOpts.maxAge { - metrics.CacheRequests.WithLabelValues(subsystem, string(refreshOpts.mode), "miss").Inc() + c.metric.WithLabelValues(subsystem, string(refreshOpts.mode), "miss").Inc() if err := c.refreshAll(ctx); err != nil { return nil, err } } else { - metrics.CacheRequests.WithLabelValues(subsystem, string(refreshOpts.mode), "hit").Inc() + c.metric.WithLabelValues(subsystem, string(refreshOpts.mode), "hit").Inc() } values := make([]*T, 0, len(c.byID)) @@ -166,7 +167,7 @@ func (c *Cache[T]) getFromCache( refreshOpts := newCacheRefreshOpts(c, opts...) if refreshOpts.mode == ModeOff { - metrics.CacheRequests.WithLabelValues(subsystem, string(refreshOpts.mode), "miss").Inc() + c.metric.WithLabelValues(subsystem, string(refreshOpts.mode), "miss").Inc() klog.V(4).InfoS("cache mode is off: fetching entry from api", "subsystem", subsystem) return fetch() } @@ -177,7 +178,7 @@ func (c *Cache[T]) getFromCache( now := time.Now() if e := lookup(); e != nil && now.Sub(e.refreshedAt) <= refreshOpts.maxAge { - metrics.CacheRequests.WithLabelValues(subsystem, string(refreshOpts.mode), "hit").Inc() + c.metric.WithLabelValues(subsystem, string(refreshOpts.mode), "hit").Inc() klog.V(4).InfoS( "cache hit", "subsystem", subsystem, @@ -201,7 +202,7 @@ func (c *Cache[T]) getFromCache( // Handled above through early return } - metrics.CacheRequests.WithLabelValues(subsystem, string(refreshOpts.mode), "miss").Inc() + c.metric.WithLabelValues(subsystem, string(refreshOpts.mode), "miss").Inc() // When the value is not found in the API, the entry is not removed from the cache. // Expired entries are only evicted after an hour and when a value is found. diff --git a/internal/cache/cache_test.go b/internal/cache/cache_test.go index 48a151c6a..08a7a1146 100644 --- a/internal/cache/cache_test.go +++ b/internal/cache/cache_test.go @@ -7,6 +7,7 @@ import ( "testing/synctest" "time" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -34,6 +35,10 @@ func newTestCache(mode Mode) *Cache[hcloud.Server] { nil, func(value *hcloud.Server) int64 { return value.ID }, func(value *hcloud.Server) string { return value.Name }, + prometheus.NewCounterVec( + prometheus.CounterOpts{Name: "test_cache_requests_total"}, + []string{"subsystem", "mode", "result"}, + ), mode, 10*time.Second, ) diff --git a/internal/cache/servercache.go b/internal/cache/servercache.go index 01af784bf..19f8d9213 100644 --- a/internal/cache/servercache.go +++ b/internal/cache/servercache.go @@ -4,9 +4,21 @@ import ( "context" "time" + "github.com/prometheus/client_golang/prometheus" + + "github.com/hetznercloud/hcloud-cloud-controller-manager/internal/metrics" "github.com/hetznercloud/hcloud-go/v2/hcloud" ) +var serverCacheRequests = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "cloud_controller_manager_server_cache_requests_total", + Help: "Total cache requests to the Servers API partitioned by subsystem, mode and result.", +}, []string{"subsystem", "mode", "result"}) + +func init() { + metrics.GetRegistry().MustRegister(serverCacheRequests) +} + func NewServerCache(client *hcloud.Client, defaultMode Mode, defaultMaxAge time.Duration) *Cache[hcloud.Server] { return newCache[hcloud.Server]( func(ctx context.Context, id int64) (*hcloud.Server, error) { @@ -23,6 +35,7 @@ func NewServerCache(client *hcloud.Client, defaultMode Mode, defaultMaxAge time. }, func(value *hcloud.Server) int64 { return value.ID }, func(value *hcloud.Server) string { return value.Name }, + serverCacheRequests, defaultMode, defaultMaxAge, ) diff --git a/internal/cache/servercache_test.go b/internal/cache/servercache_test.go index c90a5f06a..7ee511e3a 100644 --- a/internal/cache/servercache_test.go +++ b/internal/cache/servercache_test.go @@ -51,6 +51,7 @@ func TestNewServerCache(t *testing.T) { require.NotNil(t, cache.fetchAll) require.NotNil(t, cache.getID) require.NotNil(t, cache.getName) + require.NotNil(t, cache.metric) ctx := t.Context() diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index 31fd5dee0..eec1373f7 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -32,20 +32,13 @@ const ( writeTimeout = 20 * time.Second ) -var ( - OperationCalled = prometheus.NewCounterVec(prometheus.CounterOpts{ - Name: "cloud_controller_manager_operations_total", - Help: "The total number of operation was called", - }, []string{"op"}) - - CacheRequests = prometheus.NewCounterVec(prometheus.CounterOpts{ - Name: "cloud_controller_manager_server_cache_requests_total", - Help: "Total cache requests partitioned by subsystem, mode and result.", - }, []string{"subsystem", "mode", "result"}) -) +var OperationCalled = prometheus.NewCounterVec(prometheus.CounterOpts{ + Name: "cloud_controller_manager_operations_total", + Help: "The total number of operation was called", +}, []string{"op"}) func init() { - GetRegistry().MustRegister(OperationCalled, CacheRequests) + GetRegistry().MustRegister(OperationCalled) } func GetRegistry() prometheus.Registerer {