diff --git a/src/routes/getStatus.ts b/src/routes/getStatus.ts index 6315fdf..15563b6 100644 --- a/src/routes/getStatus.ts +++ b/src/routes/getStatus.ts @@ -2,7 +2,7 @@ import { db } from "../databases/databases"; import { Logger } from "../utils/logger"; import { Request, Response } from "express"; import os from "os"; -import redis, { getRedisActiveRequests } from "../utils/redis"; +import redis, { getRedisStats } from "../utils/redis"; import { promiseOrTimeout } from "../utils/promise"; import { Postgres } from "../databases/Postgres"; @@ -45,7 +45,7 @@ export async function getStatus(req: Request, res: Response): Promise statusRequests, hostname: os.hostname(), activePostgresRequests: (db as Postgres)?.activePostgresRequests, - activeRedisRequests: getRedisActiveRequests(), + redisStats: getRedisStats(), }; return value ? res.send(JSON.stringify(statusValues[value])) : res.send(statusValues); } catch (err) /* istanbul ignore next */ { diff --git a/src/utils/redis.ts b/src/utils/redis.ts index 4106606..97d34de 100644 --- a/src/utils/redis.ts +++ b/src/utils/redis.ts @@ -5,6 +5,13 @@ import { RedisCommandArgument, RedisCommandArguments, RedisCommandRawReply } fro import { RedisClientOptions } from "@redis/client/dist/lib/client"; import { RedisReply } from "rate-limit-redis"; +export interface RedisStats { + activeRequests: number; + writeRequests: number; + avgReadTime: number; + avgWriteTime: number; +} + interface RedisSB { get(key: RedisCommandArgument): Promise; set(key: RedisCommandArgument, value: RedisCommandArgument): Promise; @@ -28,6 +35,11 @@ let exportClient: RedisSB = { let lastClientFail = 0; let lastReadFail = 0; let activeRequests = 0; +let writeRequests = 0; + +const readResponseTime: number[] = []; +const writeResponseTime: number[] = []; +const maxStoredTimes = 200; if (config.redis?.enabled) { Logger.info("Connected to redis"); @@ -47,6 +59,7 @@ if (config.redis?.enabled) { return; } + const start = Date.now(); activeRequests++; const timeout = config.redis.getTimeout ? setTimeout(() => reject(), config.redis.getTimeout) : null; @@ -56,6 +69,9 @@ if (config.redis?.enabled) { activeRequests--; resolve(reply); + + readResponseTime.push(Date.now() - start); + if (readResponseTime.length > maxStoredTimes) readResponseTime.shift(); }).catch((err) => { if (chosenGet === get) { lastClientFail = Date.now(); @@ -73,13 +89,20 @@ if (config.redis?.enabled) { return; } + const start = Date.now(); activeRequests++; + writeRequests++; set(key, value).then((reply) => { activeRequests--; + writeRequests--; resolve(reply); + + readResponseTime.push(Date.now() - start); + if (readResponseTime.length > maxStoredTimes) readResponseTime.shift(); }).catch((err) => { activeRequests--; + writeRequests--; reject(err); }); }); @@ -119,8 +142,13 @@ function pickChoice(client: T, readClient: T): T { } } -export function getRedisActiveRequests(): number { - return activeRequests; +export function getRedisStats(): RedisStats { + return { + activeRequests, + writeRequests, + avgReadTime: readResponseTime.length > 0 ? readResponseTime.reduce((a, b) => a + b, 0) / readResponseTime.length : 0, + avgWriteTime: writeResponseTime.length > 0 ? writeResponseTime.reduce((a, b) => a + b, 0) / writeResponseTime.length : 0, + }; } export default exportClient;