// src/services/logger.ts /** * A simple logger service that wraps the console. * This provides a centralized place to manage logging behavior, * such as adding timestamps, log levels, or sending logs to a remote service. */ const getTimestamp = () => new Date().toISOString(); type LogLevel = 'INFO' | 'WARN' | 'ERROR' | 'DEBUG'; /** * The core logging function. It uses a generic rest parameter `` * to safely accept any number of arguments of any type, just like the native console * methods. Using `unknown[]` is more type-safe than `any[]` and satisfies the linter. */ const log = (level: LogLevel, message: string, ...args: T) => { // Check if `process` is available (Node.js) vs. browser environment. // This makes the logger "isomorphic" and prevents runtime errors on the client. const envIdentifier = typeof process !== 'undefined' && process.pid ? `PID:${process.pid}` : 'BROWSER'; const timestamp = getTimestamp(); // We construct the log message with a timestamp, PID, and level for better context. const logMessage = `[${timestamp}] [${envIdentifier}] [${level}] ${message}`; switch (level) { case 'INFO': console.log(logMessage, ...args); break; case 'WARN': console.warn(logMessage, ...args); break; case 'ERROR': console.error(logMessage, ...args); break; case 'DEBUG': // For now, we can show debug logs in development. This could be controlled by an environment variable. console.debug(logMessage, ...args); break; } }; // Export the logger object for use throughout the application. export const logger = { info: (message: string, ...args: T) => log('INFO', message, ...args), warn: (message: string, ...args: T) => log('WARN', message, ...args), error: (message: string, ...args: T) => log('ERROR', message, ...args), debug: (message: string, ...args: T) => log('DEBUG', message, ...args), };