| 69 | */ |
| 70 | export function createLogger(client?: Client): Logger { |
| 71 | function log(level: LogLevel, message: string, extra?: Record<string, unknown>): void { |
| 72 | if (client) { |
| 73 | // Fire-and-forget — don't await, don't catch |
| 74 | client.app |
| 75 | .log({ |
| 76 | body: { |
| 77 | service: LOG_SERVICE, |
| 78 | level, |
| 79 | message, |
| 80 | ...(extra ? { extra } : {}), |
| 81 | }, |
| 82 | }) |
| 83 | .catch(() => { |
| 84 | // Swallow logging errors — never let logging break the plugin |
| 85 | }) |
| 86 | } else { |
| 87 | // Fallback for tests or early initialization |
| 88 | const prefix = `[${LOG_SERVICE}] [${level}]` |
| 89 | const suffix = extra ? ` ${JSON.stringify(extra)}` : "" |
| 90 | switch (level) { |
| 91 | case "debug": |
| 92 | console.debug(`${prefix} ${message}${suffix}`) |
| 93 | break |
| 94 | case "info": |
| 95 | console.info(`${prefix} ${message}${suffix}`) |
| 96 | break |
| 97 | case "warn": |
| 98 | console.warn(`${prefix} ${message}${suffix}`) |
| 99 | break |
| 100 | case "error": |
| 101 | console.error(`${prefix} ${message}${suffix}`) |
| 102 | break |
| 103 | } |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | return { |
| 108 | debug: (message, extra) => log("debug", message, extra), |