Skip to content

Commit c05eb67

Browse files
authored
Merge pull request #880 from fluxcd/cache-custom-metric-labels
Add option for custom event namespace label in cache metrics
2 parents 6be31fc + 4d91aae commit c05eb67

File tree

11 files changed

+79
-47
lines changed

11 files changed

+79
-47
lines changed

auth/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ require (
1111
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0
1212
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2
1313
github.com/bradleyfalzon/ghinstallation/v2 v2.14.0
14-
github.com/fluxcd/pkg/cache v0.5.0
14+
github.com/fluxcd/pkg/cache v0.6.0
1515
github.com/fluxcd/pkg/ssh v0.17.0
1616
github.com/onsi/gomega v1.36.2
1717
golang.org/x/net v0.35.0

cache/cache.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ func New[T any](capacity int, opts ...Options) (*Cache[T], error) {
8585
}
8686

8787
if opt.registerer != nil {
88-
c.metrics = newCacheMetrics(opt.metricsPrefix, opt.registerer)
88+
c.metrics = newCacheMetrics(opt.metricsPrefix, opt.registerer, opts...)
8989
}
9090

9191
C := &Cache[T]{cache: c}

cache/lru.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func NewLRU[T any](capacity int, opts ...Options) (*LRU[T], error) {
9797
}
9898

9999
if opt.registerer != nil {
100-
lru.metrics = newCacheMetrics(opt.metricsPrefix, opt.registerer)
100+
lru.metrics = newCacheMetrics(opt.metricsPrefix, opt.registerer, opts...)
101101
}
102102

103103
return lru, nil
@@ -139,7 +139,7 @@ func (c *LRU[T]) GetIfOrSet(ctx context.Context,
139139
opts ...Options,
140140
) (value T, ok bool, err error) {
141141

142-
var evicted bool
142+
var existed, evicted bool
143143

144144
c.mu.Lock()
145145
defer func() {
@@ -150,21 +150,22 @@ func (c *LRU[T]) GetIfOrSet(ctx context.Context,
150150

151151
// Record metrics.
152152
status := StatusSuccess
153-
event := CacheEventTypeMiss
154-
switch {
155-
case ok:
156-
event = CacheEventTypeHit
157-
case evicted:
158-
recordEviction(c.metrics)
159-
case err == nil:
160-
recordItemIncrement(c.metrics)
161-
default:
153+
if err != nil {
162154
status = StatusFailure
163155
}
164156
recordRequest(c.metrics, status)
157+
event := CacheEventTypeMiss
158+
if ok {
159+
event = CacheEventTypeHit
160+
}
165161
if obj := o.involvedObject; obj != nil {
166162
c.RecordCacheEvent(event, obj.Kind, obj.Name, obj.Namespace)
167163
}
164+
if evicted {
165+
recordEviction(c.metrics)
166+
} else if !existed && err == nil {
167+
recordItemIncrement(c.metrics)
168+
}
168169

169170
// Print debug logs. The involved object should already be set in the context logger.
170171
switch l := logr.FromContextOrDiscard(ctx).V(1).WithValues("key", key); {
@@ -180,16 +181,15 @@ func (c *LRU[T]) GetIfOrSet(ctx context.Context,
180181
}()
181182

182183
var curNode *node[T]
183-
curNode, ok = c.cache[key]
184+
curNode, existed = c.cache[key]
184185

185-
if ok {
186+
if existed {
186187
c.delete(curNode)
187188
if condition(curNode.value) {
188189
_ = c.add(curNode)
189-
value = curNode.value
190+
value, ok = curNode.value, true
190191
return
191192
}
192-
ok = false
193193
}
194194

195195
value, err = fetch(ctx)

cache/metrics.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,11 @@ type cacheMetrics struct {
4343
}
4444

4545
// newcacheMetrics returns a new cacheMetrics.
46-
func newCacheMetrics(prefix string, reg prometheus.Registerer) *cacheMetrics {
47-
labels := []string{"event_type", "kind", "name", "namespace"}
46+
func newCacheMetrics(prefix string, reg prometheus.Registerer, opts ...Options) *cacheMetrics {
47+
o := storeOptions{eventNamespaceLabel: "namespace"}
48+
o.apply(opts...)
49+
50+
labels := []string{"event_type", "kind", "name", o.eventNamespaceLabel}
4851
return &cacheMetrics{
4952
cacheEventsCounter: promauto.With(reg).NewCounterVec(
5053
prometheus.CounterOpts{

cache/metrics_test.go

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package cache
1818

1919
import (
2020
"bytes"
21+
"fmt"
2122
"testing"
2223

2324
. "github.com/onsi/gomega"
@@ -26,22 +27,39 @@ import (
2627
)
2728

2829
func TestCacheMetrics(t *testing.T) {
29-
g := NewWithT(t)
30-
reg := prometheus.NewPedanticRegistry()
31-
m := newCacheMetrics("gotk_", reg)
32-
g.Expect(m).ToNot(BeNil())
30+
for _, tt := range []struct {
31+
name string
32+
opts []Options
33+
eventLabels string
34+
}{
35+
{
36+
name: "default event namespace label",
37+
eventLabels: `kind="TestObject",name="test",namespace="test-ns"`,
38+
},
39+
{
40+
name: "custom event namespace label",
41+
opts: []Options{WithEventNamespaceLabel("exported_namespace")},
42+
eventLabels: `exported_namespace="test-ns",kind="TestObject",name="test"`,
43+
},
44+
} {
45+
t.Run(tt.name, func(t *testing.T) {
46+
g := NewWithT(t)
47+
48+
reg := prometheus.NewPedanticRegistry()
49+
m := newCacheMetrics("gotk_", reg, tt.opts...)
50+
g.Expect(m).ToNot(BeNil())
3351

34-
// CounterVec is a collection of counters and is not exported until it has counters in it.
35-
m.incCacheEvents(CacheEventTypeHit, []string{"TestObject", "test", "test-ns"}...)
36-
m.incCacheEvents(CacheEventTypeMiss, []string{"TestObject", "test", "test-ns"}...)
37-
m.incCacheRequests("success")
38-
m.incCacheRequests("failure")
52+
// CounterVec is a collection of counters and is not exported until it has counters in it.
53+
m.incCacheEvents(CacheEventTypeHit, []string{"TestObject", "test", "test-ns"}...)
54+
m.incCacheEvents(CacheEventTypeMiss, []string{"TestObject", "test", "test-ns"}...)
55+
m.incCacheRequests("success")
56+
m.incCacheRequests("failure")
3957

40-
validateMetrics(reg, `
58+
validateMetrics(reg, fmt.Sprintf(`
4159
# HELP gotk_cache_events_total Total number of cache retrieval events for a Gitops Toolkit resource reconciliation.
4260
# TYPE gotk_cache_events_total counter
43-
gotk_cache_events_total{event_type="cache_hit",kind="TestObject",name="test",namespace="test-ns"} 1
44-
gotk_cache_events_total{event_type="cache_miss",kind="TestObject",name="test",namespace="test-ns"} 1
61+
gotk_cache_events_total{event_type="cache_hit",%[1]s} 1
62+
gotk_cache_events_total{event_type="cache_miss",%[1]s} 1
4563
# HELP gotk_cache_evictions_total Total number of cache evictions.
4664
# TYPE gotk_cache_evictions_total counter
4765
gotk_cache_evictions_total 0
@@ -52,11 +70,13 @@ func TestCacheMetrics(t *testing.T) {
5270
# HELP gotk_cached_items Total number of items in the cache.
5371
# TYPE gotk_cached_items gauge
5472
gotk_cached_items 0
55-
`, t)
73+
`, tt.eventLabels), t)
5674

57-
res, err := testutil.GatherAndLint(reg)
58-
g.Expect(err).ToNot(HaveOccurred())
59-
g.Expect(res).To(BeEmpty())
75+
res, err := testutil.GatherAndLint(reg)
76+
g.Expect(err).ToNot(HaveOccurred())
77+
g.Expect(res).To(BeEmpty())
78+
})
79+
}
6080
}
6181

6282
func validateMetrics(reg prometheus.Gatherer, expected string, t *testing.T) {

cache/store.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,14 @@ type Expirable[T any] interface {
4444
}
4545

4646
type storeOptions struct {
47-
interval time.Duration
48-
registerer prometheus.Registerer
49-
metricsPrefix string
50-
maxDuration time.Duration
51-
involvedObject *InvolvedObject
52-
debugKey string
53-
debugValueFunc func(any) any
47+
interval time.Duration
48+
registerer prometheus.Registerer
49+
metricsPrefix string
50+
maxDuration time.Duration
51+
involvedObject *InvolvedObject
52+
debugKey string
53+
debugValueFunc func(any) any
54+
eventNamespaceLabel string
5455
}
5556

5657
func (o *storeOptions) apply(opts ...Options) error {
@@ -108,3 +109,11 @@ func WithInvolvedObject(kind, name, namespace string) Options {
108109
return nil
109110
}
110111
}
112+
113+
// WithEventNamespaceLabel sets the namespace label for the cache events.
114+
func WithEventNamespaceLabel(label string) Options {
115+
return func(o *storeOptions) error {
116+
o.eventNamespaceLabel = label
117+
return nil
118+
}
119+
}

cache/token.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (c *TokenCache) GetOrSet(ctx context.Context,
103103
so.debugKey = "token"
104104
so.debugValueFunc = func(v any) any {
105105
return map[string]any{
106-
"duration": v.(*tokenItem).token.GetDuration(),
106+
"duration": v.(*tokenItem).token.GetDuration().String(),
107107
}
108108
}
109109
return nil

git/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ require (
2525
github.com/bradleyfalzon/ghinstallation/v2 v2.14.0 // indirect
2626
github.com/cespare/xxhash/v2 v2.3.0 // indirect
2727
github.com/cloudflare/circl v1.5.0 // indirect
28-
github.com/fluxcd/pkg/cache v0.5.0 // indirect
28+
github.com/fluxcd/pkg/cache v0.6.0 // indirect
2929
github.com/go-logr/logr v1.4.2 // indirect
3030
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
3131
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect

git/gogit/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ require (
4141
github.com/cloudflare/circl v1.5.0 // indirect
4242
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
4343
github.com/emirpasic/gods v1.18.1 // indirect
44-
github.com/fluxcd/pkg/cache v0.5.0 // indirect
44+
github.com/fluxcd/pkg/cache v0.6.0 // indirect
4545
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
4646
github.com/go-logr/logr v1.4.2 // indirect
4747
github.com/gofrs/uuid v4.4.0+incompatible // indirect

git/internal/e2e/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ require (
4242
github.com/cyphar/filepath-securejoin v0.4.1 // indirect
4343
github.com/emirpasic/gods v1.18.1 // indirect
4444
github.com/fluxcd/gitkit v0.6.0 // indirect
45-
github.com/fluxcd/pkg/cache v0.5.0 // indirect
45+
github.com/fluxcd/pkg/cache v0.6.0 // indirect
4646
github.com/fluxcd/pkg/version v0.6.0 // indirect
4747
github.com/fsnotify/fsnotify v1.7.0 // indirect
4848
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect

0 commit comments

Comments
 (0)