diff --git a/src/vs/platform/log/common/fileLog.ts b/src/vs/platform/log/common/fileLog.ts index 60ad7b2f10c97..05d6579338d15 100644 --- a/src/vs/platform/log/common/fileLog.ts +++ b/src/vs/platform/log/common/fileLog.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { Queue } from 'vs/base/common/async'; +import { ThrottledDelayer } from 'vs/base/common/async'; import { VSBuffer } from 'vs/base/common/buffer'; import { basename, dirname, joinPath } from 'vs/base/common/resources'; import { URI } from 'vs/base/common/uri'; @@ -16,8 +16,9 @@ const MAX_FILE_SIZE = 5 * ByteSize.MB; class FileLogger extends AbstractMessageLogger implements ILogger { private readonly initializePromise: Promise; - private readonly queue: Queue; + private readonly flushDelayer: ThrottledDelayer; private backupIndex: number = 1; + private buffer: string = ''; constructor( private readonly resource: URI, @@ -27,11 +28,25 @@ class FileLogger extends AbstractMessageLogger implements ILogger { ) { super(); this.setLevel(level); - this.queue = this._register(new Queue()); + this.flushDelayer = new ThrottledDelayer(100 /* buffer saves over a short time */); this.initializePromise = this.initialize(); } - override flush(): void { + override async flush(): Promise { + if (!this.buffer) { + return; + } + await this.initializePromise; + let content = await this.loadContent(); + if (content.length > MAX_FILE_SIZE) { + await this.fileService.writeFile(this.getBackupResource(), VSBuffer.fromString(content)); + content = ''; + } + if (this.buffer) { + content += this.buffer; + this.buffer = ''; + await this.fileService.writeFile(this.resource, VSBuffer.fromString(content)); + } } private async initialize(): Promise { @@ -45,20 +60,12 @@ class FileLogger extends AbstractMessageLogger implements ILogger { } protected log(level: LogLevel, message: string): void { - this.queue.queue(async () => { - await this.initializePromise; - let content = await this.loadContent(); - if (content.length > MAX_FILE_SIZE) { - await this.fileService.writeFile(this.getBackupResource(), VSBuffer.fromString(content)); - content = ''; - } - if (this.donotUseFormatters) { - content += message; - } else { - content += `${this.getCurrentTimestamp()} [${this.stringifyLogLevel(level)}] ${message}\n`; - } - await this.fileService.writeFile(this.resource, VSBuffer.fromString(content)); - }); + if (this.donotUseFormatters) { + this.buffer += message; + } else { + this.buffer += `${this.getCurrentTimestamp()} [${this.stringifyLogLevel(level)}] ${message}\n`; + } + this.flushDelayer.trigger(() => this.flush()); } private getCurrentTimestamp(): string { diff --git a/src/vs/workbench/api/browser/mainThreadLogService.ts b/src/vs/workbench/api/browser/mainThreadLogService.ts index d4e83b4a14ac3..da8ac21f4fb4b 100644 --- a/src/vs/workbench/api/browser/mainThreadLogService.ts +++ b/src/vs/workbench/api/browser/mainThreadLogService.ts @@ -60,6 +60,14 @@ export class MainThreadLoggerService implements MainThreadLoggerShape { this.loggerService.setVisibility(URI.revive(resource), visible); } + $flush(file: UriComponents): void { + const logger = this.loggerService.getLogger(URI.revive(file)); + if (!logger) { + throw new Error('Create the logger before flushing'); + } + logger.flush(); + } + dispose(): void { this.disposables.dispose(); } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index a1a33c11b0412..e640b255e0ed7 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -2055,6 +2055,7 @@ export interface ExtHostLogLevelServiceShape { export interface MainThreadLoggerShape { $log(file: UriComponents, messages: [LogLevel, string][]): void; + $flush(file: UriComponents): void; $createLogger(file: UriComponents, options?: ILoggerOptions): Promise; $registerLogger(logger: UriDto): Promise; $deregisterLogger(resource: UriComponents): Promise; diff --git a/src/vs/workbench/api/common/extHostLoggerService.ts b/src/vs/workbench/api/common/extHostLoggerService.ts index 8a9c7dbb072c9..1d7b4288378c6 100644 --- a/src/vs/workbench/api/common/extHostLoggerService.ts +++ b/src/vs/workbench/api/common/extHostLoggerService.ts @@ -73,4 +73,8 @@ class Logger extends AbstractMessageLogger { private doLog(messages: [LogLevel, string][]) { this.proxy.$log(this.file, messages); } + + override flush(): void { + this.proxy.$flush(this.file); + } }