Merge from vscode e558dc6ea73a75bd69d7a0b485f0e7e4194c66bf (#6864)

This commit is contained in:
Anthony Dresser
2019-08-21 20:44:59 -07:00
committed by GitHub
parent d2ae0f0154
commit 985bfae8a0
107 changed files with 2260 additions and 814 deletions

View File

@@ -0,0 +1,134 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ILogService, LogLevel, AbstractLogService } from 'vs/platform/log/common/log';
import { URI } from 'vs/base/common/uri';
import { IFileService } from 'vs/platform/files/common/files';
import { Queue } from 'vs/base/common/async';
import { VSBuffer } from 'vs/base/common/buffer';
export class FileLogService extends AbstractLogService implements ILogService {
_serviceBrand: any;
private readonly queue: Queue<void>;
constructor(
private readonly name: string,
private readonly resource: URI,
level: LogLevel,
@IFileService private readonly fileService: IFileService
) {
super();
this.setLevel(level);
this.queue = this._register(new Queue<void>());
}
trace(): void {
if (this.getLevel() <= LogLevel.Trace) {
this._log(LogLevel.Trace, this.format(arguments));
}
}
debug(): void {
if (this.getLevel() <= LogLevel.Debug) {
this._log(LogLevel.Debug, this.format(arguments));
}
}
info(): void {
if (this.getLevel() <= LogLevel.Info) {
this._log(LogLevel.Info, this.format(arguments));
}
}
warn(): void {
if (this.getLevel() <= LogLevel.Warning) {
this._log(LogLevel.Warning, this.format(arguments));
}
}
error(): void {
if (this.getLevel() <= LogLevel.Error) {
const arg = arguments[0];
if (arg instanceof Error) {
const array = Array.prototype.slice.call(arguments) as any[];
array[0] = arg.stack;
this._log(LogLevel.Error, this.format(array));
} else {
this._log(LogLevel.Error, this.format(arguments));
}
}
}
critical(): void {
if (this.getLevel() <= LogLevel.Critical) {
this._log(LogLevel.Critical, this.format(arguments));
}
}
flush(): Promise<void> {
return this.queue.queue(() => Promise.resolve());
}
log(level: LogLevel, args: any[]): void {
this._log(level, this.format(args));
}
private _log(level: LogLevel, message: string): void {
this.queue.queue(async () => {
let content = await this.loadContent();
content += `[${this.getCurrentTimestamp()}] [${this.name}] [${this.stringifyLogLevel(level)}] ${message}\n`;
await this.fileService.writeFile(this.resource, VSBuffer.fromString(content));
});
}
private getCurrentTimestamp(): string {
const toTwoDigits = (v: number) => v < 10 ? `0${v}` : v;
const toThreeDigits = (v: number) => v < 10 ? `00${v}` : v < 100 ? `0${v}` : v;
const currentTime = new Date();
return `${currentTime.getFullYear()}-${toTwoDigits(currentTime.getMonth() + 1)}-${toTwoDigits(currentTime.getDate())} ${toTwoDigits(currentTime.getHours())}:${toTwoDigits(currentTime.getMinutes())}:${toTwoDigits(currentTime.getSeconds())}.${toThreeDigits(currentTime.getMilliseconds())}`;
}
private async loadContent(): Promise<string> {
try {
const content = await this.fileService.readFile(this.resource);
return content.value.toString();
} catch (e) {
return '';
}
}
private stringifyLogLevel(level: LogLevel): string {
switch (level) {
case LogLevel.Critical: return 'critical';
case LogLevel.Debug: return 'debug';
case LogLevel.Error: return 'error';
case LogLevel.Info: return 'info';
case LogLevel.Trace: return 'trace';
case LogLevel.Warning: return 'warning';
}
return '';
}
private format(args: any): string {
let result = '';
for (let i = 0; i < args.length; i++) {
let a = args[i];
if (typeof a === 'object') {
try {
a = JSON.stringify(a);
} catch (e) { }
}
result += (i > 0 ? ' ' : '') + a;
}
return result;
}
}