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:
@@ -56,7 +56,7 @@ app.use(apiRoutes);
|
|||||||
app.use(healthRoutes);
|
app.use(healthRoutes);
|
||||||
|
|
||||||
app.listen(env.PORT, (server) => {
|
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) {
|
function getErrorReturn(error: Error) {
|
||||||
|
|||||||
@@ -73,14 +73,21 @@ export const cacheRoutes = new Elysia({ prefix: "/cache" })
|
|||||||
"/",
|
"/",
|
||||||
async ({ query: { key, fuzzy } }) => {
|
async ({ query: { key, fuzzy } }) => {
|
||||||
key = validateKey(key);
|
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 };
|
return { deletedKeys };
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -133,7 +140,7 @@ async function deleteWithPattern(pattern: string) {
|
|||||||
|
|
||||||
const deleteCount = await redis.del(foundKeys);
|
const deleteCount = await redis.del(foundKeys);
|
||||||
|
|
||||||
cacheRouteLogger.info(`Deleted ${deleteCount} keys in this batch.`);
|
cacheRouteLogger.debug(`Deleted ${deleteCount} keys in this batch.`);
|
||||||
totalDeleteCount += deleteCount;
|
totalDeleteCount += deleteCount;
|
||||||
} while (cursor !== "0");
|
} while (cursor !== "0");
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,25 @@ import * as Sentry from "@sentry/bun";
|
|||||||
|
|
||||||
import { env } from "@/env";
|
import { env } from "@/env";
|
||||||
|
|
||||||
Sentry.init({
|
const s = Sentry.init({
|
||||||
dsn: env.SENTRY_DSN,
|
dsn: env.SENTRY_DSN,
|
||||||
enabled: env.SENTRY_ENABLED,
|
enabled: env.SENTRY_ENABLED,
|
||||||
environment: env.SENTRY_ENVIRONMENT,
|
environment: env.SENTRY_ENVIRONMENT,
|
||||||
tracesSampleRate: env.SENTRY_TRACE_SAMPLE_RATE,
|
tracesSampleRate: env.SENTRY_TRACE_SAMPLE_RATE,
|
||||||
release: env.VERSION,
|
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;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ export function setupShutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function shutdown() {
|
async function shutdown() {
|
||||||
shutdownLogger.info("Shutting down...");
|
shutdownLogger.debug("Shutting down...");
|
||||||
shutdownLogger.info("Closing Redis connection...");
|
shutdownLogger.debug("Closing Redis connection...");
|
||||||
await redis.quit();
|
await redis.quit();
|
||||||
process.exit(0);
|
process.exit(0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import pino from "pino";
|
|||||||
import { env } from "@/env";
|
import { env } from "@/env";
|
||||||
|
|
||||||
import { mask } from "./mask";
|
import { mask } from "./mask";
|
||||||
|
import { SentryLogger } from "@/server/sentry.server.config";
|
||||||
|
|
||||||
const serializers: { [key: string]: pino.SerializerFn } = {
|
const serializers: { [key: string]: pino.SerializerFn } = {
|
||||||
password: (payload) => {
|
password: (payload) => {
|
||||||
@@ -29,8 +30,38 @@ export const baseLogger = pino({
|
|||||||
level: process.env.LOG_LEVEL || "info",
|
level: process.env.LOG_LEVEL || "info",
|
||||||
timestamp: pino.stdTimeFunctions.isoTime,
|
timestamp: pino.stdTimeFunctions.isoTime,
|
||||||
serializers,
|
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) => {
|
export const loggerModule = (loggerName: string) => {
|
||||||
return baseLogger.child({ module: loggerName });
|
return baseLogger.child({ module: loggerName });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const pinoLevels = {
|
||||||
|
trace: 10,
|
||||||
|
debug: 20,
|
||||||
|
info: 30,
|
||||||
|
warn: 40,
|
||||||
|
error: 50,
|
||||||
|
fatal: 60,
|
||||||
|
} as const;
|
||||||
|
|||||||
Reference in New Issue
Block a user