import * as Sentry from "@sentry/nextjs" const logLevels = ["debug", "info", "warn", "error"] as const const minimumLogLevel = (() => { const configuredMinimumLogLevel = ( (process.env.MINIMUM_LOG_LEVEL || process.env.NEXT_PUBLIC_MINIMUM_LOG_LEVEL) ?? "info" ).toLowerCase() as (typeof logLevels)[number] if (!logLevels.includes(configuredMinimumLogLevel)) { console.warn( `Invalid log level configured: ${configuredMinimumLogLevel}, defaulting to 'info'` ) return "info" } return configuredMinimumLogLevel })() function shouldLog(level: (typeof logLevels)[number]) { return logLevels.indexOf(level) >= logLevels.indexOf(minimumLogLevel) } export function createLogger(loggerPrefix: string | (() => Promise)) { const asyncWrapper: () => Promise = typeof loggerPrefix === "string" ? async () => loggerPrefix : loggerPrefix const getLoggerPrefix = async () => { const prefix = await asyncWrapper() if (!prefix) { return "" } return `[${prefix}]` } async function log( level: (typeof logLevels)[number], message: string, ...args: unknown[] ) { if (!shouldLog(level)) { return } Sentry.logger[level](`${await getLoggerPrefix()} ${message}`.trim(), { ...args, }) console[level](`${await getLoggerPrefix()} ${message}`.trim(), ...args) } return { async debug(message: string, ...args: unknown[]): Promise { await log("debug", message, ...args) }, async info(message: string, ...args: unknown[]): Promise { await log("info", message, ...args) }, async warn(message: string, ...args: unknown[]): Promise { await log("warn", message, ...args) }, async error(message: string, ...args: unknown[]): Promise { await log("error", message, ...args) }, } }