Skip to content

Commit 43aa378

Browse files
committed
better extension host logging
1 parent 010a45c commit 43aa378

5 files changed

Lines changed: 66 additions & 39 deletions

File tree

src/vs/platform/log/common/fileLogService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ export class FileLogService extends AbstractLogService implements ILogService {
7474
return this.queue.queue(() => Promise.resolve());
7575
}
7676

77+
log(level: LogLevel, args: any[]): void {
78+
this._log(level, this.format(args));
79+
}
80+
7781
private _log(level: LogLevel, message: string): void {
7882
this.queue.queue(async () => {
7983
let content = await this.loadContent();

src/vs/workbench/api/browser/mainThreadLogService.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,46 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { extHostCustomer } from 'vs/workbench/api/common/extHostCustomers';
7-
import { ILogService } from 'vs/platform/log/common/log';
8-
import { Disposable } from 'vs/base/common/lifecycle';
9-
import { IExtHostContext, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol';
6+
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
7+
import { ILogService, LogLevel } from 'vs/platform/log/common/log';
8+
import { IDisposable } from 'vs/base/common/lifecycle';
9+
import { IExtHostContext, ExtHostContext, MainThreadLogShape, MainContext } from 'vs/workbench/api/common/extHost.protocol';
10+
import { UriComponents, URI } from 'vs/base/common/uri';
11+
import { FileLogService } from 'vs/platform/log/common/fileLogService';
12+
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
13+
import { basename } from 'vs/base/common/path';
1014

11-
@extHostCustomer
12-
export class MainThreadLogService extends Disposable {
15+
@extHostNamedCustomer(MainContext.MainThreadLog)
16+
export class MainThreadLogService implements MainThreadLogShape {
17+
18+
private readonly _loggers = new Map<string, FileLogService>();
19+
private readonly _logListener: IDisposable;
1320

1421
constructor(
1522
extHostContext: IExtHostContext,
16-
@ILogService logService: ILogService,
23+
@ILogService private readonly _logService: ILogService,
24+
@IInstantiationService private readonly _instaService: IInstantiationService,
1725
) {
18-
super();
19-
this._register(logService.onDidChangeLogLevel(level => extHostContext.getProxy(ExtHostContext.ExtHostLogService).$setLevel(level)));
26+
const proxy = extHostContext.getProxy(ExtHostContext.ExtHostLogService);
27+
this._logListener = _logService.onDidChangeLogLevel(level => {
28+
proxy.$setLevel(level);
29+
this._loggers.forEach(value => value.setLevel(level));
30+
});
31+
}
32+
33+
dispose(): void {
34+
this._logListener.dispose();
35+
this._loggers.forEach(value => value.dispose());
36+
this._loggers.clear();
2037
}
2138

22-
}
39+
$log(file: UriComponents, level: LogLevel, message: any[]): void {
40+
const uri = URI.revive(file);
41+
let logger = this._loggers.get(uri.toString());
42+
if (!logger) {
43+
logger = this._instaService.createInstance(FileLogService, basename(file.path), URI.revive(file), this._logService.getLevel());
44+
this._loggers.set(uri.toString(), logger);
45+
}
46+
logger.log(level, message);
47+
}
48+
}

src/vs/workbench/api/common/extHost.protocol.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,6 +1284,10 @@ export interface ExtHostLogServiceShape {
12841284
$setLevel(level: LogLevel): void;
12851285
}
12861286

1287+
export interface MainThreadLogShape {
1288+
$log(file: UriComponents, level: LogLevel, args: any[]): void;
1289+
}
1290+
12871291
export interface ExtHostOutputServiceShape {
12881292
$setVisibleChannel(channelId: string | null): void;
12891293
}
@@ -1326,6 +1330,7 @@ export const MainContext = {
13261330
MainThreadKeytar: createMainId<MainThreadKeytarShape>('MainThreadKeytar'),
13271331
MainThreadLanguageFeatures: createMainId<MainThreadLanguageFeaturesShape>('MainThreadLanguageFeatures'),
13281332
MainThreadLanguages: createMainId<MainThreadLanguagesShape>('MainThreadLanguages'),
1333+
MainThreadLog: createMainId<MainThreadLogShape>('MainThread'),
13291334
MainThreadMessageService: createMainId<MainThreadMessageServiceShape>('MainThreadMessageService'),
13301335
MainThreadOutputService: createMainId<MainThreadOutputServiceShape>('MainThreadOutputService'),
13311336
MainThreadProgress: createMainId<MainThreadProgressShape>('MainThreadProgress'),

src/vs/workbench/api/worker/extHostLogService.ts

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,33 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { ILogService, LogLevel, AbstractLogService } from 'vs/platform/log/common/log';
7-
import { ExtHostLogServiceShape } from 'vs/workbench/api/common/extHost.protocol';
7+
import { ExtHostLogServiceShape, MainThreadLogShape, MainContext } from 'vs/workbench/api/common/extHost.protocol';
88
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
99
import { IExtHostOutputService } from 'vs/workbench/api/common/extHostOutput';
10-
import * as vscode from 'vscode';
10+
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
11+
import { joinPath } from 'vs/base/common/resources';
12+
import { ExtensionHostLogFileName } from 'vs/workbench/services/extensions/common/extensions';
13+
import { UriComponents } from 'vs/base/common/uri';
14+
import { localize } from 'vs/nls';
1115

1216
export class ExtHostLogService extends AbstractLogService implements ILogService, ExtHostLogServiceShape {
1317

1418
_serviceBrand: any;
1519

16-
private readonly _logChannel: vscode.OutputChannel;
20+
private readonly _proxy: MainThreadLogShape;
21+
private readonly _logFile: UriComponents;
1722

1823
constructor(
24+
@IExtHostRpcService rpc: IExtHostRpcService,
1925
@IExtHostInitDataService initData: IExtHostInitDataService,
2026
@IExtHostOutputService extHostOutputService: IExtHostOutputService
2127
) {
2228
super();
29+
const logFile = joinPath(initData.logsLocation, `${ExtensionHostLogFileName}.log`);
30+
this._proxy = rpc.getProxy(MainContext.MainThreadLog);
31+
this._logFile = logFile.toJSON();
2332
this.setLevel(initData.logLevel);
24-
this._logChannel = extHostOutputService.createOutputChannel('Log (Worker Extension Host)');
33+
extHostOutputService.createOutputChannelFromLogFile(localize('name', "Worker Extension Host"), logFile);
2534
}
2635

2736
$setLevel(level: LogLevel): void {
@@ -30,55 +39,37 @@ export class ExtHostLogService extends AbstractLogService implements ILogService
3039

3140
trace(_message: string, ..._args: any[]): void {
3241
if (this.getLevel() <= LogLevel.Trace) {
33-
this._logChannel.appendLine(this._format(arguments));
42+
this._proxy.$log(this._logFile, LogLevel.Trace, Array.from(arguments));
3443
}
3544
}
3645

3746
debug(_message: string, ..._args: any[]): void {
3847
if (this.getLevel() <= LogLevel.Debug) {
39-
this._logChannel.appendLine(this._format(arguments));
48+
this._proxy.$log(this._logFile, LogLevel.Debug, Array.from(arguments));
4049
}
4150
}
4251

4352
info(_message: string, ..._args: any[]): void {
4453
if (this.getLevel() <= LogLevel.Info) {
45-
this._logChannel.appendLine(this._format(arguments));
54+
this._proxy.$log(this._logFile, LogLevel.Info, Array.from(arguments));
4655
}
4756
}
4857

4958
warn(_message: string, ..._args: any[]): void {
5059
if (this.getLevel() <= LogLevel.Warning) {
51-
this._logChannel.appendLine(this._format(arguments));
60+
this._proxy.$log(this._logFile, LogLevel.Warning, Array.from(arguments));
5261
}
5362
}
5463

5564
error(_message: string | Error, ..._args: any[]): void {
5665
if (this.getLevel() <= LogLevel.Error) {
57-
this._logChannel.appendLine(this._format(arguments));
66+
this._proxy.$log(this._logFile, LogLevel.Error, Array.from(arguments));
5867
}
5968
}
6069

6170
critical(_message: string | Error, ..._args: any[]): void {
6271
if (this.getLevel() <= LogLevel.Critical) {
63-
this._logChannel.appendLine(String(arguments));
72+
this._proxy.$log(this._logFile, LogLevel.Critical, Array.from(arguments));
6473
}
6574
}
66-
67-
private _format(args: any): string {
68-
let result = '';
69-
70-
for (let i = 0; i < args.length; i++) {
71-
let a = args[i];
72-
73-
if (typeof a === 'object') {
74-
try {
75-
a = JSON.stringify(a);
76-
} catch (e) { }
77-
}
78-
79-
result += (i > 0 ? ' ' : '') + a;
80-
}
81-
82-
return result;
83-
}
8475
}

src/vs/workbench/services/extensions/browser/extensionService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { Schemas } from 'vs/base/common/network';
2828
import { DisposableStore } from 'vs/base/common/lifecycle';
2929
import { IStaticExtensionsService } from 'vs/workbench/services/extensions/common/staticExtensions';
3030
import { DeltaExtensionsResult } from 'vs/workbench/services/extensions/common/extensionDescriptionRegistry';
31+
import { INMEMORY_LOG_SCHEME } from 'vs/workbench/services/log/common/inMemoryLogProvider';
3132

3233
export class ExtensionService extends AbstractExtensionService implements IExtensionService {
3334

@@ -86,7 +87,7 @@ export class ExtensionService extends AbstractExtensionService implements IExten
8687
const result: ExtensionHostProcessManager[] = [];
8788

8889
const webExtensions = this.getExtensions().then(extensions => extensions.filter(ext => isWebExtension(ext, this._configService)));
89-
const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.parse('empty:value')); //todo@joh
90+
const webHostProcessWorker = this._instantiationService.createInstance(WebWorkerExtensionHostStarter, true, webExtensions, URI.from({ scheme: INMEMORY_LOG_SCHEME, path: '/' }));
9091
const webHostProcessManager = this._instantiationService.createInstance(ExtensionHostProcessManager, false, webHostProcessWorker, null, initialActivationEvents);
9192
result.push(webHostProcessManager);
9293

0 commit comments

Comments
 (0)