提交 43aa378a 编写于 作者: J Johannes Rieken

better extension host logging

上级 010a45cc
......@@ -74,6 +74,10 @@ export class FileLogService extends AbstractLogService implements ILogService {
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();
......
......@@ -3,20 +3,46 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { ILogService } from 'vs/platform/log/common/log';
import { Disposable } from 'vs/base/common/lifecycle';
import { IExtHostContext, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
import { IDisposable } from 'vs/base/common/lifecycle';
import { IExtHostContext, ExtHostContext, MainThreadLogShape, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { UriComponents, URI } from 'vs/base/common/uri';
import { FileLogService } from 'vs/platform/log/common/fileLogService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { basename } from 'vs/base/common/path';
@extHostCustomer
export class MainThreadLogService extends Disposable {
@extHostNamedCustomer(MainContext.MainThreadLog)
export class MainThreadLogService implements MainThreadLogShape {
private readonly _loggers = new Map<string, FileLogService>();
private readonly _logListener: IDisposable;
constructor(
extHostContext: IExtHostContext,
@ILogService logService: ILogService,
@ILogService private readonly _logService: ILogService,
@IInstantiationService private readonly _instaService: IInstantiationService,
) {
super();
this._register(logService.onDidChangeLogLevel(level => extHostContext.getProxy(ExtHostContext.ExtHostLogService).$setLevel(level)));
const proxy = extHostContext.getProxy(ExtHostContext.ExtHostLogService);
this._logListener = _logService.onDidChangeLogLevel(level => {
proxy.$setLevel(level);
this._loggers.forEach(value => value.setLevel(level));
});
}
dispose(): void {
this._logListener.dispose();
this._loggers.forEach(value => value.dispose());
this._loggers.clear();
}
}
\ No newline at end of file
$log(file: UriComponents, level: LogLevel, message: any[]): void {
const uri = URI.revive(file);
let logger = this._loggers.get(uri.toString());
if (!logger) {
logger = this._instaService.createInstance(FileLogService, basename(file.path), URI.revive(file), this._logService.getLevel());
this._loggers.set(uri.toString(), logger);
}
logger.log(level, message);
}
}
......@@ -1284,6 +1284,10 @@ export interface ExtHostLogServiceShape {
$setLevel(level: LogLevel): void;
}
export interface MainThreadLogShape {
$log(file: UriComponents, level: LogLevel, args: any[]): void;
}
export interface ExtHostOutputServiceShape {
$setVisibleChannel(channelId: string | null): void;
}
......@@ -1326,6 +1330,7 @@ export const MainContext = {
MainThreadKeytar: createMainId<MainThreadKeytarShape>('MainThreadKeytar'),
MainThreadLanguageFeatures: createMainId<MainThreadLanguageFeaturesShape>('MainThreadLanguageFeatures'),
MainThreadLanguages: createMainId<MainThreadLanguagesShape>('MainThreadLanguages'),
MainThreadLog: createMainId<MainThreadLogShape>('MainThread'),
MainThreadMessageService: createMainId<MainThreadMessageServiceShape>('MainThreadMessageService'),
MainThreadOutputService: createMainId<MainThreadOutputServiceShape>('MainThreadOutputService'),
MainThreadProgress: createMainId<MainThreadProgressShape>('MainThreadProgress'),
......
......@@ -4,24 +4,33 @@
*--------------------------------------------------------------------------------------------*/
import { ILogService, LogLevel, AbstractLogService } from 'vs/platform/log/common/log';
import { ExtHostLogServiceShape } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostLogServiceShape, MainThreadLogShape, MainContext } from 'vs/workbench/api/common/extHost.protocol';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput';
import * as vscode from 'vscode';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { joinPath } from 'vs/base/common/resources';
import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions';
import { UriComponents } from 'vs/base/common/uri';
import { localize } from 'vs/nls';
export class ExtHostLogService extends AbstractLogService implements ILogService, ExtHostLogServiceShape {
_serviceBrand: any;
private readonly _logChannel: vscode.OutputChannel;
private readonly _proxy: MainThreadLogShape;
private readonly _logFile: UriComponents;
constructor(
@IExtHostRpcService rpc: IExtHostRpcService,
@IExtHostInitDataService initData: IExtHostInitDataService,
@IExtHostOutputService extHostOutputService: IExtHostOutputService
) {
super();
const logFile = joinPath(initData.logsLocation, `${ExtensionHostLogFileName}.log`);
this._proxy = rpc.getProxy(MainContext.MainThreadLog);
this._logFile = logFile.toJSON();
this.setLevel(initData.logLevel);
this._logChannel = extHostOutputService.createOutputChannel('Log (Worker Extension Host)');
extHostOutputService.createOutputChannelFromLogFile(localize('name', "Worker Extension Host"), logFile);
}
$setLevel(level: LogLevel): void {
......@@ -30,55 +39,37 @@ export class ExtHostLogService extends AbstractLogService implements ILogService
trace(_message: string, ..._args: any[]): void {
if (this.getLevel() <= LogLevel.Trace) {
this._logChannel.appendLine(this._format(arguments));
this._proxy.$log(this._logFile, LogLevel.Trace, Array.from(arguments));
}
}
debug(_message: string, ..._args: any[]): void {
if (this.getLevel() <= LogLevel.Debug) {
this._logChannel.appendLine(this._format(arguments));
this._proxy.$log(this._logFile, LogLevel.Debug, Array.from(arguments));
}
}
info(_message: string, ..._args: any[]): void {
if (this.getLevel() <= LogLevel.Info) {
this._logChannel.appendLine(this._format(arguments));
this._proxy.$log(this._logFile, LogLevel.Info, Array.from(arguments));
}
}
warn(_message: string, ..._args: any[]): void {
if (this.getLevel() <= LogLevel.Warning) {
this._logChannel.appendLine(this._format(arguments));
this._proxy.$log(this._logFile, LogLevel.Warning, Array.from(arguments));
}
}
error(_message: string | Error, ..._args: any[]): void {
if (this.getLevel() <= LogLevel.Error) {
this._logChannel.appendLine(this._format(arguments));
this._proxy.$log(this._logFile, LogLevel.Error, Array.from(arguments));
}
}
critical(_message: string | Error, ..._args: any[]): void {
if (this.getLevel() <= LogLevel.Critical) {
this._logChannel.appendLine(String(arguments));
this._proxy.$log(this._logFile, LogLevel.Critical, Array.from(arguments));
}
}
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;
}
}
......@@ -28,6 +28,7 @@ import { Schemas } from 'vs/base/common/network';
import { DisposableStore } from 'vs/base/common/lifecycle';
import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
import { DeltaExtensionsResult } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
import { INMEMORY_LOG_SCHEME } from 'vs/workbench/services/log/common/inMemoryLogProvider';
export class ExtensionService extends AbstractExtensionService implements IExtensionService {
......@@ -86,7 +87,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
const result: ExtensionHostProcessManager[] = [];
const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => isWebExtension(ext, this._configService)));
const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.parse('empty:value')); //todo@joh
const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.from({ scheme: INMEMORY_LOG_SCHEME, path: '/' }));
const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, null, initialActivationEvents);
result.push(webHostProcessManager);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册