import pino, { Logger as PinoLogger } from "pino"; import type { LoggerService } from "./logger-service"; import { config } from "../../config"; export class PinoLoggerService implements LoggerService { private readonly logger: PinoLogger; constructor(name?: string, parent?: PinoLogger) { if (parent) { this.logger = parent.child({ name }); } else { // In Next.js, especially in the Edge runtime or during instrumentation, // pino transports (which use worker threads) can cause issues. // We disable transport in production and during instrumentation. const useTransport = config.isDevelopment && typeof window === "undefined"; this.logger = pino({ name: name || "app", level: config.logging.level, transport: useTransport ? { target: "pino-pretty", options: { colorize: true, }, } : undefined, }); } } trace(msg: string, ...args: unknown[]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any this.logger.trace(msg, ...(args as any)); } debug(msg: string, ...args: unknown[]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any this.logger.debug(msg, ...(args as any)); } info(msg: string, ...args: unknown[]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any this.logger.info(msg, ...(args as any)); } warn(msg: string, ...args: unknown[]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any this.logger.warn(msg, ...(args as any)); } error(msg: string, ...args: unknown[]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any this.logger.error(msg, ...(args as any)); } fatal(msg: string, ...args: unknown[]) { // eslint-disable-next-line @typescript-eslint/no-explicit-any this.logger.fatal(msg, ...(args as any)); } child(bindings: Record): LoggerService { const childPino = this.logger.child(bindings); const service = new PinoLoggerService(); // eslint-disable-next-line @typescript-eslint/no-explicit-any (service as any).logger = childPino; return service; } }