wdc
This commit is contained in:
103
src/lib/logger.ts
Normal file
103
src/lib/logger.ts
Normal file
@@ -0,0 +1,103 @@
|
||||
// We have to use process.env, otherwise pino doesn't work
|
||||
/* eslint-disable node/no-process-env */
|
||||
import pino from "pino";
|
||||
// import pinoPretty from "pino-pretty";
|
||||
// import { isDevelopment, isTest } from "./isEnv";
|
||||
import { isObject } from "./utils";
|
||||
import { obfuscateValue } from "@/modules/app-configuration/utils";
|
||||
import { BaseError, BaseTrpcError } from "@/errors";
|
||||
|
||||
/* c8 ignore start */
|
||||
export const logger = pino({
|
||||
level: process.env.APP_DEBUG ?? "info",
|
||||
redact: {
|
||||
paths: ["secretKey", "*[*].secretKey"],
|
||||
censor: (value) => redactLogValue(value),
|
||||
},
|
||||
// transport:
|
||||
// process.env.CI || isDevelopment() || isTest()
|
||||
// ? {
|
||||
// target: "pino-pretty",
|
||||
// options: {
|
||||
// colorize: true,
|
||||
// },
|
||||
// }
|
||||
// : undefined,
|
||||
});
|
||||
/* c8 ignore stop */
|
||||
|
||||
export const createLogger = logger.child.bind(logger);
|
||||
|
||||
export const redactLogValue = (value: unknown) => {
|
||||
if (typeof value !== "string") {
|
||||
// non-string values are fully redacted to prevent leaks
|
||||
return "[REDACTED]";
|
||||
}
|
||||
|
||||
return obfuscateValue(value);
|
||||
};
|
||||
|
||||
export const redactError = (error: unknown) => {
|
||||
if (error instanceof BaseTrpcError) {
|
||||
const { message, name, errorCode, statusCode, trpcCode } = error;
|
||||
return {
|
||||
message,
|
||||
name,
|
||||
errorCode,
|
||||
statusCode,
|
||||
trpcCode,
|
||||
};
|
||||
}
|
||||
if (error instanceof BaseError) {
|
||||
const { message, name, errorCode, statusCode } = error;
|
||||
return {
|
||||
message,
|
||||
name,
|
||||
errorCode,
|
||||
statusCode,
|
||||
};
|
||||
}
|
||||
if (error instanceof Error) {
|
||||
const { message, name } = error;
|
||||
return {
|
||||
message,
|
||||
name,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export const redactLogObject = <T extends {}>(obj: T, callCount = 1): T => {
|
||||
if (callCount > 10) {
|
||||
logger.warn("Exceeded max call count for redactLogObject");
|
||||
return { _message: "[REDACTED - MAX CALL COUNT EXCEEDED]" } as unknown as T;
|
||||
}
|
||||
|
||||
const entries = Object.entries(obj).map(([key, value]) => {
|
||||
if (isObject(value)) {
|
||||
return [key, redactLogObject(value, callCount + 1)];
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return [key, redactLogArray(value)];
|
||||
}
|
||||
return [key, redactLogValue(value)];
|
||||
});
|
||||
return Object.fromEntries(entries) as T;
|
||||
};
|
||||
|
||||
export const redactLogArray = <T extends unknown[]>(array: T | undefined, callCount = 1): T => {
|
||||
if (!array) return [] as unknown as T;
|
||||
if (callCount > 10) {
|
||||
logger.warn("Exceeded max call count for redactLogArray");
|
||||
return [] as unknown as T;
|
||||
}
|
||||
|
||||
return array.map((item) => {
|
||||
if (isObject(item)) {
|
||||
return redactLogObject(item, callCount + 1);
|
||||
}
|
||||
if (Array.isArray(item)) {
|
||||
return redactLogArray(item, callCount + 1);
|
||||
}
|
||||
return redactLogValue(item);
|
||||
}) as T;
|
||||
};
|
||||
Reference in New Issue
Block a user