(scope: string)
| 10 | } |
| 11 | |
| 12 | export function createLogger(scope: string): Logger { |
| 13 | let logger: Logger | null = null; |
| 14 | let cachedLogLevel: string | undefined = undefined; |
| 15 | |
| 16 | function getLogger(): Logger { |
| 17 | const currentLogLevel = process.env.TRAINLOOP_LOG_LEVEL; |
| 18 | |
| 19 | // Invalidate cached logger if log level changed |
| 20 | if (!logger || cachedLogLevel !== currentLogLevel) { |
| 21 | cachedLogLevel = currentLogLevel; |
| 22 | const env = (currentLogLevel || DEFAULT_LEVEL).toLowerCase() as Level; |
| 23 | const threshold = ORDER[env] ?? ORDER.info; |
| 24 | |
| 25 | function log(level: Level, msg: string): void { |
| 26 | if (ORDER[level] > threshold) return; |
| 27 | const ts = new Date().toISOString(); |
| 28 | // eslint-disable-next-line no-console |
| 29 | console[level](`[${level.toUpperCase()}] [${ts}] [${scope}] ${msg}`); |
| 30 | } |
| 31 | |
| 32 | logger = { |
| 33 | error: (m: string) => log("error", m), |
| 34 | warn: (m: string) => log("warn", m), |
| 35 | info: (m: string) => log("info", m), |
| 36 | debug: (m: string) => log("debug", m) |
| 37 | }; |
| 38 | } |
| 39 | return logger; |
| 40 | } |
| 41 | |
| 42 | // Return a proxy that creates logger on first access |
| 43 | return new Proxy({} as Logger, { |
| 44 | get(_target, prop: keyof Logger) { |
| 45 | return getLogger()[prop]; |
| 46 | } |
| 47 | }); |
| 48 | } |
no outgoing calls
no test coverage detected