Merged in feat/redis-api-send-logs (pull request #2290)

feature: send logs to Sentry for Redis-Api

* feature: send logs to Sentry for Redis-Api


Approved-by: Linus Flood
This commit is contained in:
Joakim Jäderberg
2025-06-19 08:28:53 +00:00
parent 46e7f33ab6
commit 3af994b0a9
5 changed files with 65 additions and 12 deletions

View File

@@ -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) {

View File

@@ -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");

View File

@@ -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: <explanation>
export const sentry = s!;
export const SentryLogger = Sentry.logger;

View File

@@ -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);
}

View File

@@ -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;