| const LOG_LEVELS = { debug: 0, info: 1, warn: 2, error: 3 } as const; |
| type LogLevel = keyof typeof LOG_LEVELS; |
|
|
| function getMinLevel(): LogLevel { |
| const env = (import.meta.env?.VITE_LOG_LEVEL ?? 'info').toLowerCase(); |
| return env in LOG_LEVELS ? (env as LogLevel) : 'info'; |
| } |
|
|
| function isJsonFormat(): boolean { |
| return import.meta.env?.VITE_LOG_FORMAT === 'json'; |
| } |
|
|
| function formatLine(level: LogLevel, tag: string, args: unknown[]): string { |
| const timestamp = new Date().toISOString(); |
| const upperLevel = level.toUpperCase(); |
| const msg = args |
| .map((a) => |
| a instanceof Error ? (a.stack ?? a.message) : typeof a === 'string' ? a : JSON.stringify(a), |
| ) |
| .join(' '); |
|
|
| if (isJsonFormat()) { |
| return JSON.stringify({ timestamp, level: upperLevel, tag, message: msg }); |
| } |
| return `[${timestamp}] [${upperLevel}] [${tag}] ${msg}`; |
| } |
|
|
| export function createLogger(tag: string) { |
| const emit = (level: LogLevel, args: unknown[]) => { |
| if (LOG_LEVELS[level] < LOG_LEVELS[getMinLevel()]) return; |
|
|
| const line = formatLine(level, tag, args); |
|
|
| |
| const fn = |
| level === 'debug' |
| ? console.debug |
| : level === 'warn' |
| ? console.warn |
| : level === 'error' |
| ? console.error |
| : console.log; |
| fn(line); |
| }; |
|
|
| return { |
| debug: (...args: unknown[]) => emit('debug', args), |
| info: (...args: unknown[]) => emit('info', args), |
| warn: (...args: unknown[]) => emit('warn', args), |
| error: (...args: unknown[]) => emit('error', args), |
| }; |
| } |
|
|