Skip to content

Commit 82f45d6

Browse files
authored
Add metrics to CacheService (#1713)
* feat: add metrics to cacheService Signed-off-by: Ivo Yankov <[email protected]> * chore: reset metric at init Signed-off-by: Ivo Yankov <[email protected]> --------- Signed-off-by: Ivo Yankov <[email protected]>
1 parent 82fc1ba commit 82f45d6

File tree

2 files changed

+55
-19
lines changed

2 files changed

+55
-19
lines changed

packages/relay/src/lib/clients/cache/localLRUCache.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,6 @@ export class LocalLRUCache implements ICacheClient {
6363
private readonly register: Registry;
6464
private cacheKeyGauge: Gauge<string>;
6565

66-
private static getCacheLabel = 'get';
67-
private static setCacheLabel = 'set';
68-
6966
/**
7067
* Represents a LocalLRUCache instance that uses an LRU (Least Recently Used) caching strategy
7168
* for caching items internally from requests.
@@ -89,8 +86,7 @@ export class LocalLRUCache implements ICacheClient {
8986
register.removeSingleMetric(metricCounterName);
9087
this.cacheKeyGauge = new Gauge({
9188
name: metricCounterName,
92-
help: 'Relay cache gauge',
93-
labelNames: ['key', 'type', 'method'],
89+
help: 'Relay LRU cache gauge',
9490
registers: [register],
9591
async collect() {
9692
cacheSizeCollect();
@@ -109,9 +105,8 @@ export class LocalLRUCache implements ICacheClient {
109105
public get(key: string, callingMethod: string, requestIdPrefix?: string): any {
110106
const value = this.cache.get(key);
111107
if (value !== undefined) {
112-
this.cacheKeyGauge.labels('', LocalLRUCache.getCacheLabel, callingMethod || '').inc(1);
113108
this.logger.trace(
114-
`${requestIdPrefix} returning cached value ${key}:${JSON.stringify(value)} on ${callingMethod} call`
109+
`${requestIdPrefix} returning cached value ${key}:${JSON.stringify(value)} on ${callingMethod} call`,
115110
);
116111
return value;
117112
}
@@ -132,7 +127,6 @@ export class LocalLRUCache implements ICacheClient {
132127
const resolvedTtl = ttl ?? this.options.ttl;
133128
this.logger.trace(`${requestIdPrefix} caching ${key}:${JSON.stringify(value)} for ${resolvedTtl} ms`);
134129
this.cache.set(key, value, { ttl: resolvedTtl });
135-
this.cacheKeyGauge.labels('', LocalLRUCache.setCacheLabel, callingMethod || '').inc(1);
136130
}
137131

138132
/**

packages/relay/src/lib/services/cacheService/cacheService.ts

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*/
2020

2121
import { Logger } from 'pino';
22-
import { Registry } from 'prom-client';
22+
import { Counter, Registry } from 'prom-client';
2323
import { ICacheClient } from '../../clients/cache/ICacheClient';
2424
import { LocalLRUCache, RedisCache } from '../../clients';
2525
import { RedisCacheError } from '../../errors/RedisCacheError';
@@ -63,6 +63,21 @@ export class CacheService {
6363
* @param {Logger} logger - The logger used for logging all output from this class.
6464
* @param {Registry} register - The metrics register used for metrics tracking.
6565
*/
66+
67+
private static readonly cacheTypes = {
68+
REDIS: 'redis',
69+
LRU: 'lru',
70+
};
71+
72+
private static readonly methods = {
73+
GET: 'get',
74+
GET_ASYNC: 'getAsync',
75+
SET: 'set',
76+
DELETE: 'delete',
77+
};
78+
79+
private readonly cacheMethodsCounter: Counter;
80+
6681
public constructor(logger: Logger, register: Registry) {
6782
this.logger = logger;
6883
this.register = register;
@@ -74,6 +89,21 @@ export class CacheService {
7489
if (this.isSharedCacheEnabled) {
7590
this.sharedCache = new RedisCache(logger.child({ name: 'redisCache' }), register);
7691
}
92+
93+
/**
94+
* Labels:
95+
* callingMethod - The method initiating the cache operation
96+
* cacheType - redis/lru
97+
* method - The CacheService method being called
98+
*/
99+
const metricName = 'rpc_cache_service_methods_counter';
100+
this.register.removeSingleMetric(metricName);
101+
this.cacheMethodsCounter = new Counter({
102+
name: metricName,
103+
help: 'Counter for calls to methods of CacheService separated by CallingMethod and CacheType',
104+
registers: [register],
105+
labelNames: ['callingMethod', 'cacheType', 'method'],
106+
});
77107
}
78108

79109
/**
@@ -99,21 +129,21 @@ export class CacheService {
99129
* @param {string} [requestIdPrefix] - The optional request ID prefix.
100130
* @returns {Promise<any>} A Promise that resolves with the cached value or null if not found.
101131
*/
102-
public async getAsync(
103-
key: string,
104-
callingMethod: string,
105-
requestIdPrefix?: string
106-
): Promise<any> {
132+
public async getAsync(key: string, callingMethod: string, requestIdPrefix?: string): Promise<any> {
107133
if (!this.isSharedCacheEnabled) {
108134
return null;
109135
}
110136

111137
try {
138+
this.cacheMethodsCounter
139+
.labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.GET_ASYNC)
140+
.inc(1);
141+
112142
return await this.sharedCache.get(key, callingMethod, requestIdPrefix);
113143
} catch (error) {
114144
const redisError = new RedisCacheError(error);
115145
this.logger.error(
116-
`${requestIdPrefix} Error occurred while getting the cache from Redis. Fallback to internal cache. Error is: ${redisError.fullError}`
146+
`${requestIdPrefix} Error occurred while getting the cache from Redis. Fallback to internal cache. Error is: ${redisError.fullError}`,
117147
);
118148
}
119149
}
@@ -127,6 +157,8 @@ export class CacheService {
127157
* @returns {Promise<any>} A Promise that resolves with the cached value or null if not found.
128158
*/
129159
public get(key: string, callingMethod: string, requestIdPrefix?: string): any {
160+
this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.GET).inc(1);
161+
130162
return this.internalCache.get(key, callingMethod, requestIdPrefix);
131163
}
132164

@@ -147,18 +179,22 @@ export class CacheService {
147179
callingMethod: string,
148180
ttl?: number,
149181
requestIdPrefix?: string,
150-
shared: boolean = false
182+
shared: boolean = false,
151183
): void {
152184
if (shared && this.isSharedCacheEnabled) {
153185
try {
186+
this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.SET).inc(1);
187+
154188
this.sharedCache.set(key, value, callingMethod, ttl, requestIdPrefix);
155189
} catch (error) {
156190
const redisError = new RedisCacheError(error);
157191
this.logger.error(
158-
`${requestIdPrefix} Error occurred while setting the cache to Redis. Fallback to internal cache. Error is: ${redisError.fullError}`
192+
`${requestIdPrefix} Error occurred while setting the cache to Redis. Fallback to internal cache. Error is: ${redisError.fullError}`,
159193
);
160194
}
161195
} else {
196+
this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.SET).inc(1);
197+
162198
this.internalCache.set(key, value, callingMethod, ttl, requestIdPrefix);
163199
}
164200
}
@@ -175,14 +211,20 @@ export class CacheService {
175211
public delete(key: string, callingMethod: string, requestIdPrefix?: string, shared: boolean = false): void {
176212
if (shared && this.isSharedCacheEnabled) {
177213
try {
214+
this.cacheMethodsCounter
215+
.labels(callingMethod, CacheService.cacheTypes.REDIS, CacheService.methods.DELETE)
216+
.inc(1);
217+
178218
return this.sharedCache.delete(key, callingMethod, requestIdPrefix);
179219
} catch (error) {
180220
const redisError = new RedisCacheError(error);
181221
this.logger.error(
182-
`${requestIdPrefix} Error occurred while deleting cache from Redis. Error is: ${redisError.fullError}`
222+
`${requestIdPrefix} Error occurred while deleting cache from Redis. Error is: ${redisError.fullError}`,
183223
);
184224
}
185225
} else {
226+
this.cacheMethodsCounter.labels(callingMethod, CacheService.cacheTypes.LRU, CacheService.methods.DELETE).inc(1);
227+
186228
this.internalCache.delete(key, callingMethod, requestIdPrefix);
187229
}
188230
}
@@ -200,7 +242,7 @@ export class CacheService {
200242
} catch (error) {
201243
const redisError = new RedisCacheError(error);
202244
this.logger.error(
203-
`${requestIdPrefix} Error occurred while clearing Redis cache. Error is: ${redisError.fullError}`
245+
`${requestIdPrefix} Error occurred while clearing Redis cache. Error is: ${redisError.fullError}`,
204246
);
205247
}
206248
} else {

0 commit comments

Comments
 (0)