diff --git a/apps/redis-api/src/index.ts b/apps/redis-api/src/index.ts index b97d323c2..55da9a95a 100644 --- a/apps/redis-api/src/index.ts +++ b/apps/redis-api/src/index.ts @@ -56,7 +56,7 @@ app.use(apiRoutes); app.use(healthRoutes); app.listen(env.PORT, (server) => { - baseLogger.info(`🦊 REDISAPI@${env.VERSION} running on ${server.url}`); + baseLogger.debug(`🦊 REDISAPI@${env.VERSION} running on ${server.url}`); }); function getErrorReturn(error: Error) { diff --git a/apps/redis-api/src/routes/api/cache.ts b/apps/redis-api/src/routes/api/cache.ts index 173a19f94..bf8f4b004 100644 --- a/apps/redis-api/src/routes/api/cache.ts +++ b/apps/redis-api/src/routes/api/cache.ts @@ -73,14 +73,21 @@ export const cacheRoutes = new Elysia({ prefix: "/cache" }) "/", async ({ query: { key, fuzzy } }) => { key = validateKey(key); - cacheRouteLogger.debug( - `DELETE /cache ${key} ${fuzzy ? "fuzzy" : ""}`, - ); - const deletedKeys: number = fuzzy - ? await deleteWithPattern(`*${key}*`) - : await redis.del(key); - cacheRouteLogger.info(`Deleted ${deletedKeys} keys for '${key}'`); + const keyToDelete = fuzzy ? `*${key}*` : key; + cacheRouteLogger.debug(`DELETE /cache ${keyToDelete}`); + + const now = performance.now(); + const deletedKeys: number = fuzzy + ? await deleteWithPattern(keyToDelete) + : await redis.del(keyToDelete); + const elapsed = performance.now() - now; + + cacheRouteLogger.info( + `Deleted ${deletedKeys} keys for '${keyToDelete}' in ${elapsed}ms`, + { fuzzy, deletedKeys, keyToDelete, elapsed }, + ); + return { deletedKeys }; }, { @@ -133,7 +140,7 @@ async function deleteWithPattern(pattern: string) { const deleteCount = await redis.del(foundKeys); - cacheRouteLogger.info(`Deleted ${deleteCount} keys in this batch.`); + cacheRouteLogger.debug(`Deleted ${deleteCount} keys in this batch.`); totalDeleteCount += deleteCount; } while (cursor !== "0"); diff --git a/apps/redis-api/src/server/sentry.server.config.ts b/apps/redis-api/src/server/sentry.server.config.ts index e410507c2..8ef0d3ced 100644 --- a/apps/redis-api/src/server/sentry.server.config.ts +++ b/apps/redis-api/src/server/sentry.server.config.ts @@ -4,10 +4,25 @@ import * as Sentry from "@sentry/bun"; import { env } from "@/env"; -Sentry.init({ +const s = Sentry.init({ dsn: env.SENTRY_DSN, enabled: env.SENTRY_ENABLED, environment: env.SENTRY_ENVIRONMENT, tracesSampleRate: env.SENTRY_TRACE_SAMPLE_RATE, release: env.VERSION, + _experiments: { + enableLogs: true, + beforeSendLog(log) { + const ignoredLevels: (typeof log.level)[] = ["debug", "trace"]; + if (ignoredLevels.includes(log.level)) { + return null; + } + + return log; + }, + }, }); + +// biome-ignore lint/style/noNonNullAssertion: +export const sentry = s!; +export const SentryLogger = Sentry.logger; diff --git a/apps/redis-api/src/shutdown.ts b/apps/redis-api/src/shutdown.ts index 1783b3984..7b5fea8b5 100644 --- a/apps/redis-api/src/shutdown.ts +++ b/apps/redis-api/src/shutdown.ts @@ -9,8 +9,8 @@ export function setupShutdown() { } async function shutdown() { - shutdownLogger.info("Shutting down..."); - shutdownLogger.info("Closing Redis connection..."); + shutdownLogger.debug("Shutting down..."); + shutdownLogger.debug("Closing Redis connection..."); await redis.quit(); process.exit(0); } diff --git a/apps/redis-api/src/utils/logger.ts b/apps/redis-api/src/utils/logger.ts index 25f1eaa4c..b5da95fae 100644 --- a/apps/redis-api/src/utils/logger.ts +++ b/apps/redis-api/src/utils/logger.ts @@ -3,6 +3,7 @@ import pino from "pino"; import { env } from "@/env"; import { mask } from "./mask"; +import { SentryLogger } from "@/server/sentry.server.config"; const serializers: { [key: string]: pino.SerializerFn } = { password: (payload) => { @@ -29,8 +30,38 @@ export const baseLogger = pino({ level: process.env.LOG_LEVEL || "info", timestamp: pino.stdTimeFunctions.isoTime, serializers, + hooks: { + logMethod(args, method, level) { + const [msg, ...rest] = args; + switch (level) { + case pinoLevels.error: + SentryLogger.error(msg, rest); + break; + case pinoLevels.warn: + SentryLogger.warn(msg, rest); + break; + case pinoLevels.info: + SentryLogger.info(msg, rest); + break; + case pinoLevels.debug: + SentryLogger.debug(msg, rest); + break; + } + + method.apply(this, args); + }, + }, }); export const loggerModule = (loggerName: string) => { return baseLogger.child({ module: loggerName }); }; + +const pinoLevels = { + trace: 10, + debug: 20, + info: 30, + warn: 40, + error: 50, + fatal: 60, +} as const;