提交 810efbc8 编写于 作者: S Sandeep Somavarapu

- Remove windowId from IInitData

- Send exthost logs location from renderer
- IExtensionService: Expose an API to get exthost logs location
上级 8d0c573b
......@@ -138,8 +138,8 @@ export function createApiFactory(
const extHostMessageService = new ExtHostMessageService(rpcProtocol);
const extHostDialogs = new ExtHostDialogs(rpcProtocol);
const extHostStatusBar = new ExtHostStatusBar(rpcProtocol);
const outputDir = posix.join(initData.logsPath, `output_logging_${initData.windowId}_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`);
const extHostOutputService = new ExtHostOutputService(outputDir, rpcProtocol);
const outputPath = posix.join(initData.logsLocation.fsPath, `output_logging_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`);
const extHostOutputService = new ExtHostOutputService(outputPath, rpcProtocol);
const extHostLanguages = new ExtHostLanguages(rpcProtocol);
// Register API-ish commands
......
......@@ -66,9 +66,8 @@ export interface IInitData {
extensions: IExtensionDescription[];
configuration: IConfigurationInitData;
telemetryInfo: ITelemetryInfo;
windowId: number;
logLevel: LogLevel;
logsPath: string;
logsLocation: URI;
}
export interface IConfigurationInitData extends IConfigurationData {
......
......@@ -9,16 +9,19 @@ import { LogLevel } from 'vs/workbench/api/node/extHostTypes';
import { ILogService, DelegatedLogService } from 'vs/platform/log/common/log';
import { createSpdLogService } from 'vs/platform/log/node/spdlogService';
import { ExtHostLogServiceShape } from 'vs/workbench/api/node/extHost.protocol';
import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions';
export class ExtHostLogService extends DelegatedLogService implements ILogService, ExtHostLogServiceShape {
private _logsPath: string;
constructor(
private _windowId: number,
logLevel: LogLevel,
private _logsPath: string
logsPath: string,
) {
super(createSpdLogService(`exthost${_windowId}`, logLevel, _logsPath));
super(createSpdLogService(ExtensionHostLogFileName, logLevel, logsPath));
this._logsPath = logsPath;
}
$setLevel(level: LogLevel): void {
......@@ -26,6 +29,6 @@ export class ExtHostLogService extends DelegatedLogService implements ILogServic
}
getLogDirectory(extensionID: string): string {
return join(this._logsPath, `${extensionID}_${this._windowId}`);
return join(this._logsPath, extensionID);
}
}
......@@ -100,8 +100,9 @@ export class ExtensionHostMain {
this._workspace = rpcProtocol.transformIncomingURIs(initData.workspace);
// ensure URIs are revived
initData.extensions.forEach((ext) => (<any>ext).extensionLocation = URI.revive(ext.extensionLocation));
initData.logsLocation = URI.revive(initData.logsLocation);
this._extHostLogService = new ExtHostLogService(initData.windowId, initData.logLevel, initData.logsPath);
this._extHostLogService = new ExtHostLogService(initData.logLevel, initData.logsLocation.fsPath);
this.disposables.push(this._extHostLogService);
this._searchRequestIdProvider = new Counter();
......
......@@ -5,6 +5,7 @@
import * as nls from 'vs/nls';
import { join } from 'vs/base/common/paths';
import * as resources from 'vs/base/common/resources';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IOutputChannelRegistry, Extensions as OutputExt, } from 'vs/workbench/parts/output/common/output';
......@@ -13,26 +14,26 @@ import { IEnvironmentService } from 'vs/platform/environment/common/environment'
import { IWindowService } from 'vs/platform/windows/common/windows';
import { Disposable } from 'vs/base/common/lifecycle';
import { URI } from 'vs/base/common/uri';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import * as Constants from 'vs/workbench/parts/logs/common/logConstants';
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions';
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
import { ShowLogsAction, OpenLogsFolderAction, SetLogLevelAction, OpenLogFileAction } from 'vs/workbench/parts/logs/electron-browser/logsActions';
import { IExtensionService, ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions';
class LogOutputChannels extends Disposable implements IWorkbenchContribution {
constructor(
@IWindowService private windowService: IWindowService,
@IEnvironmentService private environmentService: IEnvironmentService,
@IInstantiationService instantiationService: IInstantiationService
@IWindowService windowService: IWindowService,
@IEnvironmentService environmentService: IEnvironmentService,
@IExtensionService extensionService: IExtensionService
) {
super();
let outputChannelRegistry = Registry.as<IOutputChannelRegistry>(OutputExt.OutputChannels);
outputChannelRegistry.registerChannel({ id: Constants.mainLogChannelId, label: nls.localize('mainLog', "Log (Main)"), file: URI.file(join(this.environmentService.logsPath, `main.log`)), log: true });
outputChannelRegistry.registerChannel({ id: Constants.sharedLogChannelId, label: nls.localize('sharedLog', "Log (Shared)"), file: URI.file(join(this.environmentService.logsPath, `sharedprocess.log`)), log: true });
outputChannelRegistry.registerChannel({ id: Constants.rendererLogChannelId, label: nls.localize('rendererLog', "Log (Window)"), file: URI.file(join(this.environmentService.logsPath, `renderer${this.windowService.getCurrentWindowId()}.log`)), log: true });
outputChannelRegistry.registerChannel({ id: Constants.extHostLogChannelId, label: nls.localize('extensionsLog', "Log (Extension Host)"), file: URI.file(join(this.environmentService.logsPath, `exthost${this.windowService.getCurrentWindowId()}.log`)), log: true });
outputChannelRegistry.registerChannel({ id: Constants.mainLogChannelId, label: nls.localize('mainLog', "Log (Main)"), file: URI.file(join(environmentService.logsPath, `main.log`)), log: true });
outputChannelRegistry.registerChannel({ id: Constants.sharedLogChannelId, label: nls.localize('sharedLog', "Log (Shared)"), file: URI.file(join(environmentService.logsPath, `sharedprocess.log`)), log: true });
outputChannelRegistry.registerChannel({ id: Constants.rendererLogChannelId, label: nls.localize('rendererLog', "Log (Window)"), file: URI.file(join(environmentService.logsPath, `renderer${windowService.getCurrentWindowId()}.log`)), log: true });
extensionService.getLogsLocations().then(([logsLocation]) => outputChannelRegistry.registerChannel({ id: Constants.extHostLogChannelId, label: nls.localize('extensionsLog', "Log (Extension Host)"), file: resources.joinPath(logsLocation, `${ExtensionHostLogFileName}.log`), log: true }));
const workbenchActionsRegistry = Registry.as<IWorkbenchActionRegistry>(WorkbenchActionExtensions.WorkbenchActions);
const devCategory = nls.localize('developer', "Developer");
......
......@@ -14,6 +14,7 @@ import { InstantiationService } from 'vs/platform/instantiation/common/instantia
import { IExtensionPoint } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { Event, Emitter } from 'vs/base/common/event';
import { NullLogService } from 'vs/platform/log/common/log';
import { URI } from 'vs/base/common/uri';
class SimpleExtensionService implements IExtensionService {
_serviceBrand: any;
......@@ -37,6 +38,7 @@ class SimpleExtensionService implements IExtensionService {
getExtensions(): TPromise<IExtensionDescription[]> {
return TPromise.wrap([]);
}
getLogsLocations(): TPromise<URI[]> { return TPromise.as([]); }
canProfileExtensionHost() {
return false;
}
......
......@@ -116,6 +116,8 @@ export class ExtensionPointContribution<T> {
}
}
export const ExtensionHostLogFileName = 'exthost';
export interface IExtensionService {
_serviceBrand: any;
......@@ -151,6 +153,11 @@ export interface IExtensionService {
*/
getExtensions(): TPromise<IExtensionDescription[]>;
/**
* Return extension host log folder paths
*/
getLogsLocations(): TPromise<URI[]>;
/**
* Read all contributions to an extension point.
*/
......
......@@ -74,6 +74,7 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
constructor(
private readonly _extensions: TPromise<IExtensionDescription[]>,
private readonly _logsLocation: TPromise<URI>,
@IWorkspaceContextService private readonly _contextService: IWorkspaceContextService,
@INotificationService private readonly _notificationService: INotificationService,
@IWindowsService private readonly _windowsService: IWindowsService,
......@@ -375,34 +376,35 @@ export class ExtensionHostProcessWorker implements IExtensionHostStarter {
}
private _createExtHostInitData(): TPromise<IInitData> {
return TPromise.join([this._telemetryService.getTelemetryInfo(), this._extensions]).then(([telemetryInfo, extensionDescriptions]) => {
const configurationData: IConfigurationInitData = { ...this._configurationService.getConfigurationData(), configurationScopes: {} };
const workspace = this._contextService.getWorkspace();
const r: IInitData = {
parentPid: process.pid,
environment: {
isExtensionDevelopmentDebug: this._isExtensionDevDebug,
appRoot: this._environmentService.appRoot,
appSettingsHome: this._environmentService.appSettingsHome,
extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI,
extensionTestsPath: this._environmentService.extensionTestsPath
},
workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : {
configuration: workspace.configuration,
folders: workspace.folders,
id: workspace.id,
name: this._labelService.getWorkspaceLabel(workspace)
},
extensions: extensionDescriptions,
// Send configurations scopes only in development mode.
configuration: !this._environmentService.isBuilt || this._environmentService.isExtensionDevelopment ? { ...configurationData, configurationScopes: getScopes() } : configurationData,
telemetryInfo,
windowId: this._windowService.getCurrentWindowId(),
logLevel: this._logService.getLevel(),
logsPath: this._environmentService.logsPath
};
return r;
});
const promises: TPromise[] = [this._telemetryService.getTelemetryInfo(), this._extensions, this._logsLocation];
return TPromise.join(promises)
.then(([telemetryInfo, extensionDescriptions, logsLocation]) => {
const configurationData: IConfigurationInitData = { ...this._configurationService.getConfigurationData(), configurationScopes: {} };
const workspace = this._contextService.getWorkspace();
const r: IInitData = {
parentPid: process.pid,
environment: {
isExtensionDevelopmentDebug: this._isExtensionDevDebug,
appRoot: this._environmentService.appRoot,
appSettingsHome: this._environmentService.appSettingsHome,
extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI,
extensionTestsPath: this._environmentService.extensionTestsPath
},
workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : {
configuration: workspace.configuration,
folders: workspace.folders,
id: workspace.id,
name: this._labelService.getWorkspaceLabel(workspace)
},
extensions: extensionDescriptions,
// Send configurations scopes only in development mode.
configuration: !this._environmentService.isBuilt || this._environmentService.isExtensionDevelopment ? { ...configurationData, configurationScopes: getScopes() } : configurationData,
telemetryInfo,
logLevel: this._logService.getLevel(),
logsLocation
};
return r;
});
}
private _logExtensionHostMessage(entry: IRemoteConsoleLog) {
......
......@@ -368,7 +368,7 @@ export class ExtensionService extends Disposable implements IExtensionService {
private _startExtensionHostProcess(initialActivationEvents: string[]): void {
this._stopExtensionHostProcess();
const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, this.getExtensions());
const extHostProcessWorker = this._instantiationService.createInstance(ExtensionHostProcessWorker, this.getExtensions(), this.getLogsLocations().then(([logsLocation]) => logsLocation));
const extHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, extHostProcessWorker, initialActivationEvents);
extHostProcessManager.onDidCrash(([code, signal]) => this._onExtensionHostCrashed(code, signal));
this._extensionHostProcessManagers.push(extHostProcessManager);
......@@ -436,6 +436,10 @@ export class ExtensionService extends Disposable implements IExtensionService {
});
}
public getLogsLocations(): TPromise<URI[]> {
return TPromise.as([URI.file(path.posix.join(this._environmentService.logsPath, `exthost${this._windowService.getCurrentWindowId()}`))]);
}
public readExtensionPointContributions<T>(extPoint: IExtensionPoint<T>): TPromise<ExtensionPointContribution<T>[]> {
return this._installedExtensionsReady.wait().then(() => {
let availableExtensions = this._registry.getAllExtensionDescriptions();
......
......@@ -307,6 +307,7 @@ export class TestExtensionService implements IExtensionService {
activateByEvent(activationEvent: string): TPromise<void> { return TPromise.as(void 0); }
whenInstalledExtensionsRegistered(): TPromise<boolean> { return TPromise.as(true); }
getExtensions(): TPromise<IExtensionDescription[]> { return TPromise.as([]); }
getLogsLocations(): TPromise<URI[]> { return TPromise.as([]); }
readExtensionPointContributions<T>(extPoint: IExtensionPoint<T>): TPromise<ExtensionPointContribution<T>[]> { return TPromise.as(Object.create(null)); }
getExtensionsStatus(): { [id: string]: IExtensionsStatus; } { return Object.create(null); }
canProfileExtensionHost(): boolean { return false; }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册