Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions internal/cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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]
Expand All @@ -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] {
Expand All @@ -88,6 +88,7 @@ func newCache[T any](
fetchAll: fetchAll,
getID: getID,
getName: getName,
metric: metric,

defaultMode: defaultMode,
defaultMaxAge: defaultMaxAge,
Expand Down Expand Up @@ -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))
Expand All @@ -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()
}
Expand All @@ -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,
Expand All @@ -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.
Expand Down
5 changes: 5 additions & 0 deletions internal/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"testing/synctest"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -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,
)
Expand Down
13 changes: 13 additions & 0 deletions internal/cache/servercache.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
)
Expand Down
1 change: 1 addition & 0 deletions internal/cache/servercache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
17 changes: 5 additions & 12 deletions internal/metrics/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading