Skip to content

Commit babcbee

Browse files
Updated counter to counter vec and added counter vec tests: FIX the cached_failed_queries_count metric (#60)
2 parents 95e4da3 + d648941 commit babcbee

File tree

3 files changed

+108
-15
lines changed

3 files changed

+108
-15
lines changed

internal/cortex/frontend/transport/handler.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ type Handler struct {
6262
querySeconds *prometheus.CounterVec
6363
querySeries *prometheus.CounterVec
6464
queryBytes *prometheus.CounterVec
65-
cachedHits prometheus.Counter
6665
activeUsers *util.ActiveUsersCleanupService
6766
}
6867

@@ -75,7 +74,7 @@ func NewHandler(cfg HandlerConfig, roundTripper http.RoundTripper, log log.Logge
7574
}
7675

7776
if cfg.FailedQueryCacheCapacity > 0 {
78-
FailedQueryCache, errQueryCache := utils.NewFailedQueryCache(cfg.FailedQueryCacheCapacity)
77+
FailedQueryCache, errQueryCache := utils.NewFailedQueryCache(cfg.FailedQueryCacheCapacity, reg)
7978
if errQueryCache != nil {
8079
level.Warn(log).Log(errQueryCache.Error())
8180
}
@@ -108,11 +107,6 @@ func NewHandler(cfg HandlerConfig, roundTripper http.RoundTripper, log log.Logge
108107
_ = h.activeUsers.StartAsync(context.Background())
109108
}
110109

111-
h.cachedHits = promauto.With(reg).NewCounter(prometheus.CounterOpts{
112-
Name: "cached_failed_queries_count",
113-
Help: "Total number of queries that hit the failed query cache.",
114-
})
115-
116110
return h
117111
}
118112

@@ -148,7 +142,6 @@ func (f *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
148142
if cached {
149143
w.WriteHeader(http.StatusForbidden)
150144
level.Info(util_log.WithContext(r.Context(), f.log)).Log(message)
151-
f.cachedHits.Inc()
152145
return
153146
}
154147
}

internal/cortex/frontend/transport/utils/utils.go

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"strconv"
1313

1414
lru "github.com/hashicorp/golang-lru"
15+
"github.com/prometheus/client_golang/prometheus"
16+
"github.com/prometheus/client_golang/prometheus/promauto"
1517
)
1618

1719
var (
@@ -23,9 +25,10 @@ type FailedQueryCache struct {
2325
regex *regexp.Regexp
2426
errorExtract *regexp.Regexp
2527
lruCache *lru.Cache
28+
cachedHits *prometheus.CounterVec
2629
}
2730

28-
func NewFailedQueryCache(capacity int) (*FailedQueryCache, error) {
31+
func NewFailedQueryCache(capacity int, reg prometheus.Registerer) (*FailedQueryCache, error) {
2932
regex := regexp.MustCompile(`[\s\n\t]+`)
3033
errorExtract := regexp.MustCompile(`Code\((\d+)\)`)
3134
lruCache, err := lru.New(capacity)
@@ -34,10 +37,17 @@ func NewFailedQueryCache(capacity int) (*FailedQueryCache, error) {
3437
err = fmt.Errorf("Failed to create lru cache: %s", err)
3538
return nil, err
3639
}
40+
cachedHits := promauto.With(reg).NewCounterVec(prometheus.CounterOpts{
41+
Name: "cached_failed_queries_count",
42+
Help: "Total number of queries that hit the failed query cache.",
43+
}, []string{})
44+
3745
return &FailedQueryCache{
3846
regex: regex,
3947
errorExtract: errorExtract,
40-
lruCache: lruCache}, err
48+
lruCache: lruCache,
49+
cachedHits: cachedHits,
50+
}, err
4151
}
4252

4353
// UpdateFailedQueryCache returns true if query is cached so that callsite can increase counter, returns message as a string for callsite to log outcome
@@ -79,10 +89,11 @@ func (f *FailedQueryCache) updateFailedQueryCache(err error, queryExpressionNorm
7989
}
8090

8191
// QueryHitCache checks if the lru cache is hit and returns whether to increment counter for cache hits along with appropriate message.
82-
func queryHitCache(queryExpressionNormalized string, queryExpressionRangeLength int, lruCache *lru.Cache) (bool, string) {
92+
func queryHitCache(queryExpressionNormalized string, queryExpressionRangeLength int, lruCache *lru.Cache, cachedHits *prometheus.CounterVec) (bool, string) {
8393
if value, ok := lruCache.Get(queryExpressionNormalized); ok && value.(int) <= queryExpressionRangeLength {
8494
cachedQueryRangeSeconds := value.(int)
8595
message := createLogMessage("Retrieved query from cache", queryExpressionNormalized, cachedQueryRangeSeconds, queryExpressionRangeLength, nil)
96+
cachedHits.WithLabelValues().Inc()
8697
return true, message
8798
}
8899
return false, ""
@@ -140,6 +151,6 @@ func (f *FailedQueryCache) UpdateFailedQueryCache(err error, query url.Values) (
140151
func (f *FailedQueryCache) QueryHitCache(query url.Values) (bool, string) {
141152
queryExpressionNormalized := f.normalizeQueryString(query)
142153
queryExpressionRangeLength := getQueryRangeSeconds(query)
143-
cached, message := queryHitCache(queryExpressionNormalized, queryExpressionRangeLength, f.lruCache)
154+
cached, message := queryHitCache(queryExpressionNormalized, queryExpressionRangeLength, f.lruCache, f.cachedHits)
144155
return cached, message
145156
}

internal/cortex/frontend/transport/utils/utils_test.go

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ import (
88
"errors"
99
"net/url"
1010
"testing"
11+
12+
"github.com/prometheus/client_golang/prometheus"
13+
"github.com/prometheus/client_golang/prometheus/testutil"
1114
)
1215

1316
func TestNewFailedQueryCache(t *testing.T) {
14-
cache, err := NewFailedQueryCache(2)
17+
reg := prometheus.NewRegistry()
18+
cache, err := NewFailedQueryCache(2, reg)
1519
if cache == nil {
1620
t.Fatalf("Expected cache to be created, but got nil")
1721
}
@@ -21,7 +25,8 @@ func TestNewFailedQueryCache(t *testing.T) {
2125
}
2226

2327
func TestUpdateFailedQueryCache(t *testing.T) {
24-
cache, _ := NewFailedQueryCache(2)
28+
reg := prometheus.NewRegistry()
29+
cache, _ := NewFailedQueryCache(2, reg)
2530

2631
tests := []struct {
2732
name string
@@ -116,7 +121,8 @@ func TestUpdateFailedQueryCache(t *testing.T) {
116121

117122
// TestQueryHitCache tests the QueryHitCache method
118123
func TestQueryHitCache(t *testing.T) {
119-
cache, _ := NewFailedQueryCache(2)
124+
reg := prometheus.NewRegistry()
125+
cache, _ := NewFailedQueryCache(2, reg)
120126
lruCache := cache.lruCache
121127

122128
lruCache.Add("test_query", 100)
@@ -195,3 +201,86 @@ func TestQueryHitCache(t *testing.T) {
195201
})
196202
}
197203
}
204+
205+
func TestCacheCounterVec(t *testing.T) {
206+
reg := prometheus.NewRegistry()
207+
cache, _ := NewFailedQueryCache(2, reg)
208+
lruCache := cache.lruCache
209+
210+
lruCache.Add("test_query", 100)
211+
lruCache.Add(" tes t query ", 100)
212+
213+
tests := []struct {
214+
name string
215+
query url.Values
216+
expectedCounter int
217+
}{
218+
{
219+
name: "Cache miss",
220+
query: url.Values{
221+
"start": {"100"},
222+
"end": {"2000"},
223+
"query": {"miss_query_counter_test"},
224+
},
225+
expectedCounter: 0,
226+
}, {
227+
name: "Cache hit",
228+
query: url.Values{
229+
"start": {"100"},
230+
"end": {"200"},
231+
"query": {"test_query"},
232+
},
233+
expectedCounter: 1,
234+
},
235+
{
236+
name: "Cache miss",
237+
query: url.Values{
238+
"start": {"100"},
239+
"end": {"200"},
240+
"query": {"miss"},
241+
},
242+
expectedCounter: 1,
243+
},
244+
245+
{
246+
name: "Cache miss due to shorter range length",
247+
query: url.Values{
248+
"start": {"100"},
249+
"end": {"150"},
250+
"query": {"test_query"},
251+
},
252+
expectedCounter: 1,
253+
},
254+
255+
{
256+
name: "Cache hit whitespace",
257+
query: url.Values{
258+
"start": {"100"},
259+
"end": {"200"},
260+
"query": {" \n\ttes \tt \n query \t\n "},
261+
},
262+
expectedCounter: 2,
263+
},
264+
265+
{
266+
name: "Cache miss whitespace",
267+
query: url.Values{
268+
"start": {"100"},
269+
"end": {"200"},
270+
"query": {" \n\tte s \tt \n query \t\n "},
271+
},
272+
expectedCounter: 2,
273+
},
274+
}
275+
276+
for _, tt := range tests {
277+
t.Run(tt.name, func(t *testing.T) {
278+
cache.QueryHitCache(tt.query)
279+
result := int(testutil.ToFloat64(cache.cachedHits.WithLabelValues()))
280+
if result != tt.expectedCounter {
281+
t.Errorf("expected counter value to be %v, got %v", tt.expectedCounter, result)
282+
}
283+
284+
})
285+
}
286+
}

0 commit comments

Comments
 (0)