UNPKG

@sentry/node

Version:

Sentry Node SDK using OpenTelemetry for performance instrumentation

115 lines (98 loc) 3.27 kB
const SINGLE_ARG_COMMANDS = ['get', 'set', 'setex']; const GET_COMMANDS = ['get', 'mget']; const SET_COMMANDS = ['set', 'setex']; // todo: del, expire /** Checks if a given command is in the list of redis commands. * Useful because commands can come in lowercase or uppercase (depending on the library). */ function isInCommands(redisCommands, command) { return redisCommands.includes(command.toLowerCase()); } /** Determine cache operation based on redis statement */ function getCacheOperation( command, ) { if (isInCommands(GET_COMMANDS, command)) { return 'cache.get'; } else if (isInCommands(SET_COMMANDS, command)) { return 'cache.put'; } else { return undefined; } } function keyHasPrefix(key, prefixes) { return prefixes.some(prefix => key.startsWith(prefix)); } /** Safely converts a redis key to a string (comma-separated if there are multiple keys) */ function getCacheKeySafely(redisCommand, cmdArgs) { try { if (cmdArgs.length === 0) { return undefined; } // eslint-disable-next-line @typescript-eslint/no-explicit-any const processArg = (arg) => { if (typeof arg === 'string' || typeof arg === 'number' || Buffer.isBuffer(arg)) { return [arg.toString()]; } else if (Array.isArray(arg)) { return flatten(arg.map(arg => processArg(arg))); } else { return ['<unknown>']; } }; const firstArg = cmdArgs[0]; if (isInCommands(SINGLE_ARG_COMMANDS, redisCommand) && firstArg != null) { return processArg(firstArg); } return flatten(cmdArgs.map(arg => processArg(arg))); } catch { return undefined; } } /** Determines whether a redis operation should be considered as "cache operation" by checking if a key is prefixed. * We only support certain commands (such as 'set', 'get', 'mget'). */ function shouldConsiderForCache(redisCommand, keys, prefixes) { if (!getCacheOperation(redisCommand)) { return false; } for (const key of keys) { if (keyHasPrefix(key, prefixes)) { return true; } } return false; } /** Calculates size based on the cache response value */ function calculateCacheItemSize(response) { const getSize = (value) => { try { if (Buffer.isBuffer(value)) return value.byteLength; else if (typeof value === 'string') return value.length; else if (typeof value === 'number') return value.toString().length; else if (value === null || value === undefined) return 0; return JSON.stringify(value).length; } catch { return undefined; } }; return Array.isArray(response) ? response.reduce((acc, curr) => { const size = getSize(curr); return typeof size === 'number' ? (acc !== undefined ? acc + size : size) : acc; }, 0) : getSize(response); } function flatten(input) { const result = []; const flattenHelper = (input) => { input.forEach((el) => { if (Array.isArray(el)) { flattenHelper(el ); } else { result.push(el ); } }); }; flattenHelper(input); return result; } export { GET_COMMANDS, SET_COMMANDS, calculateCacheItemSize, getCacheKeySafely, getCacheOperation, isInCommands, shouldConsiderForCache }; //# sourceMappingURL=redisCache.js.map