|
1 | 1 | import * as vscode from 'vscode'; |
2 | 2 |
|
3 | 3 | export class Logger { |
4 | | - private outputChannel: vscode.OutputChannel; |
| 4 | + // Use a single shared OutputChannel across all Logger instances |
| 5 | + private static sharedChannel: vscode.OutputChannel | undefined; |
| 6 | + private static scopedCache: Map<string, Logger> = new Map(); |
| 7 | + private scope?: string; |
| 8 | + private get outputChannel(): vscode.OutputChannel { |
| 9 | + if (!Logger.sharedChannel) { |
| 10 | + Logger.sharedChannel = vscode.window.createOutputChannel('Promptitude'); |
| 11 | + } |
| 12 | + return Logger.sharedChannel; |
| 13 | + } |
| 14 | + |
| 15 | + constructor(scope?: string) { |
| 16 | + this.scope = scope; |
| 17 | + } |
5 | 18 |
|
6 | | - constructor() { |
7 | | - this.outputChannel = vscode.window.createOutputChannel('Promptitude'); |
| 19 | + static get(scope: string): Logger { |
| 20 | + const existing = Logger.scopedCache.get(scope); |
| 21 | + if (existing) { |
| 22 | + return existing; |
| 23 | + } |
| 24 | + const logger = new Logger(scope); |
| 25 | + Logger.scopedCache.set(scope, logger); |
| 26 | + return logger; |
8 | 27 | } |
9 | 28 |
|
10 | 29 | private get isDebugEnabled(): boolean { |
11 | 30 | return vscode.workspace.getConfiguration('promptitude').get('debug', false); |
12 | 31 | } |
13 | 32 |
|
14 | 33 | private log(level: string, message: string): void { |
15 | | - const timestamp = new Date().toISOString(); |
16 | | - const logMessage = `[${timestamp}] [${level}] ${message}`; |
| 34 | + const timestamp = this.formatTimestamp(new Date()); |
| 35 | + const scoped = this.scope ? `[${this.scope}] ${message}` : message; |
| 36 | + const logMessage = `[${timestamp}] [${level}] ${scoped}`; |
17 | 37 |
|
18 | 38 | this.outputChannel.appendLine(logMessage); |
19 | | - |
20 | | - // Also log to console for debugging |
21 | | - console.log(`Promptitude: ${logMessage}`); |
| 39 | + } |
| 40 | + |
| 41 | + private formatTimestamp(date: Date): string { |
| 42 | + const pad = (n: number, width: number = 2) => n.toString().padStart(width, '0'); |
| 43 | + const year = date.getFullYear(); |
| 44 | + const month = pad(date.getMonth() + 1); |
| 45 | + const day = pad(date.getDate()); |
| 46 | + const hours = pad(date.getHours()); |
| 47 | + const minutes = pad(date.getMinutes()); |
| 48 | + const seconds = pad(date.getSeconds()); |
| 49 | + const millis = pad(date.getMilliseconds(), 3); |
| 50 | + // Format: 2025-10-08 01:16:21.132 (local time) |
| 51 | + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}.${millis}`; |
22 | 52 | } |
23 | 53 |
|
24 | 54 | debug(message: string): void { |
@@ -46,11 +76,13 @@ export class Logger { |
46 | 76 | this.log('ERROR', errorMessage); |
47 | 77 | } |
48 | 78 |
|
49 | | - show(): void { |
50 | | - this.outputChannel.show(); |
| 79 | + show(preserveFocus: boolean = false): void { |
| 80 | + this.outputChannel.show(preserveFocus); |
51 | 81 | } |
52 | 82 |
|
53 | | - dispose(): void { |
54 | | - this.outputChannel.dispose(); |
| 83 | + static disposeSharedChannel(): void { |
| 84 | + Logger.sharedChannel?.dispose(); |
| 85 | + Logger.sharedChannel = undefined; |
| 86 | + Logger.scopedCache.clear(); |
55 | 87 | } |
56 | 88 | } |
0 commit comments