mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-25 11:08:51 +01:00
Log improvements (#163532)
* - expose log level in the proposed api - ability to set log level per logger * fix tests
This commit is contained in:
committed by
GitHub
parent
a78f7af399
commit
894aa9a7a7
@@ -5,29 +5,41 @@
|
||||
|
||||
import { extHostNamedCustomer, IExtHostContext } from 'vs/workbench/services/extensions/common/extHostCustomers';
|
||||
import { ILoggerOptions, ILoggerService, ILogService, log, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostContext, MainThreadLoggerShape, MainContext } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { UriComponents, URI } from 'vs/base/common/uri';
|
||||
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { ILogLevelService } from 'vs/workbench/contrib/logs/common/logLevelService';
|
||||
import { IOutputService } from 'vs/workbench/services/output/common/output';
|
||||
import { localExtHostLog, remoteExtHostLog, webWorkerExtHostLog } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
@extHostNamedCustomer(MainContext.MainThreadLogger)
|
||||
export class MainThreadLoggerService implements MainThreadLoggerShape {
|
||||
|
||||
private readonly _logListener: IDisposable;
|
||||
private readonly disposables = new DisposableStore();
|
||||
|
||||
constructor(
|
||||
extHostContext: IExtHostContext,
|
||||
@ILogService logService: ILogService,
|
||||
@ILoggerService private readonly _loggerService: ILoggerService,
|
||||
@ILoggerService private readonly loggerService: ILoggerService,
|
||||
@ILogLevelService extensionLoggerService: ILogLevelService,
|
||||
@IOutputService outputService: IOutputService,
|
||||
) {
|
||||
const proxy = extHostContext.getProxy(ExtHostContext.ExtHostLogLevelServiceShape);
|
||||
this._logListener = logService.onDidChangeLogLevel(level => proxy.$setLevel(level));
|
||||
this.disposables.add(logService.onDidChangeLogLevel(level => proxy.$setLevel(level)));
|
||||
this.disposables.add(extensionLoggerService.onDidChangeLogLevel(({ id, logLevel }) => {
|
||||
const channel = outputService.getChannelDescriptor(id);
|
||||
const resource = channel?.log ? channel.file : undefined;
|
||||
if (resource && (channel?.extensionId || id === localExtHostLog || id === remoteExtHostLog || id === webWorkerExtHostLog)) {
|
||||
proxy.$setLevel(logLevel, resource);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
$log(file: UriComponents, messages: [LogLevel, string][]): void {
|
||||
const logger = this._loggerService.getLogger(URI.revive(file));
|
||||
const logger = this.loggerService.getLogger(URI.revive(file));
|
||||
if (!logger) {
|
||||
throw new Error('Create the logger before logging');
|
||||
}
|
||||
@@ -37,11 +49,11 @@ export class MainThreadLoggerService implements MainThreadLoggerShape {
|
||||
}
|
||||
|
||||
async $createLogger(file: UriComponents, options?: ILoggerOptions): Promise<void> {
|
||||
this._loggerService.createLogger(URI.revive(file), options);
|
||||
this.loggerService.createLogger(URI.revive(file), options);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._logListener.dispose();
|
||||
this.disposables.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ import { IExtHostDecorations } from 'vs/workbench/api/common/extHostDecorations'
|
||||
import { IExtHostTask } from 'vs/workbench/api/common/extHostTask';
|
||||
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
|
||||
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
|
||||
import { ILoggerService, ILogService } from 'vs/platform/log/common/log';
|
||||
import { ILoggerService, ILogService, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
@@ -364,6 +364,14 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
},
|
||||
get uiKind() {
|
||||
return initData.uiKind;
|
||||
},
|
||||
get logLevel() {
|
||||
checkProposedApiEnabled(extension, 'extensionLog');
|
||||
return extHostLogService.getLevel();
|
||||
},
|
||||
get onDidChangeLogLevel() {
|
||||
checkProposedApiEnabled(extension, 'extensionLog');
|
||||
return extHostLogService.onDidChangeLogLevel;
|
||||
}
|
||||
};
|
||||
if (!initData.environment.extensionTestsLocationURI) {
|
||||
@@ -1383,7 +1391,8 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
TabInputWebview: extHostTypes.WebviewEditorTabInput,
|
||||
TabInputTerminal: extHostTypes.TerminalEditorTabInput,
|
||||
TabInputInteractiveWindow: extHostTypes.InteractiveWindowInput,
|
||||
TerminalExitReason: extHostTypes.TerminalExitReason
|
||||
TerminalExitReason: extHostTypes.TerminalExitReason,
|
||||
LogLevel: LogLevel,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1944,7 +1944,7 @@ export interface ExtHostWindowShape {
|
||||
}
|
||||
|
||||
export interface ExtHostLogLevelServiceShape {
|
||||
$setLevel(level: LogLevel): void;
|
||||
$setLevel(level: LogLevel, resource?: UriComponents): void;
|
||||
}
|
||||
|
||||
export interface MainThreadLoggerShape {
|
||||
|
||||
@@ -7,27 +7,29 @@ import { ILogger, ILoggerOptions, AbstractMessageLogger, LogLevel, AbstractLogge
|
||||
import { MainThreadLoggerShape, MainContext, ExtHostLogLevelServiceShape as ExtHostLogLevelServiceShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { isUndefined } from 'vs/base/common/types';
|
||||
|
||||
export class ExtHostLoggerService extends AbstractLoggerService implements ExtHostLogLevelServiceShape {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
private readonly _onDidChangeLogLevel: Emitter<LogLevel>;
|
||||
private readonly _proxy: MainThreadLoggerShape;
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService rpc: IExtHostRpcService,
|
||||
@IExtHostInitDataService initData: IExtHostInitDataService,
|
||||
) {
|
||||
const emitter = new Emitter<LogLevel>();
|
||||
super(initData.logLevel, emitter.event);
|
||||
super(initData.logLevel, Event.None, []);
|
||||
this._proxy = rpc.getProxy(MainContext.MainThreadLogger);
|
||||
this._onDidChangeLogLevel = this._register(emitter);
|
||||
}
|
||||
|
||||
$setLevel(level: LogLevel): void {
|
||||
this._onDidChangeLogLevel.fire(level);
|
||||
$setLevel(level: LogLevel, resource?: UriComponents): void {
|
||||
if (resource) {
|
||||
this.setLevel(URI.revive(resource), level);
|
||||
} else if (!isUndefined(level)) {
|
||||
this.setLevel(level);
|
||||
}
|
||||
}
|
||||
|
||||
protected doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger {
|
||||
|
||||
@@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
|
||||
import { IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { AbstractMessageLogger, ILogger, ILoggerService, log, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { AbstractMessageLogger, ILogger, ILoggerService, ILogService, log, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { OutputChannelUpdateMode } from 'vs/workbench/services/output/common/output';
|
||||
import { IExtHostConsumerFileSystem } from 'vs/workbench/api/common/extHostFileSystemConsumer';
|
||||
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
|
||||
@@ -18,6 +18,9 @@ import { toLocalISOString } from 'vs/base/common/date';
|
||||
import { VSBuffer } from 'vs/base/common/buffer';
|
||||
import { isString } from 'vs/base/common/types';
|
||||
import { FileSystemProviderErrorCode, toFileSystemProviderErrorCode } from 'vs/platform/files/common/files';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { checkProposedApiEnabled } from 'vs/workbench/services/extensions/common/extensions';
|
||||
|
||||
class ExtHostOutputChannel extends AbstractMessageLogger implements vscode.LogOutputChannel {
|
||||
|
||||
@@ -38,6 +41,10 @@ class ExtHostOutputChannel extends AbstractMessageLogger implements vscode.LogOu
|
||||
this._register(logger.onDidChangeLogLevel(level => this.setLevel(level)));
|
||||
}
|
||||
|
||||
get logLevel(): LogLevel {
|
||||
return this.logger.getLevel();
|
||||
}
|
||||
|
||||
appendLine(value: string): void {
|
||||
this.append(value + '\n');
|
||||
}
|
||||
@@ -118,6 +125,7 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
|
||||
@IExtHostConsumerFileSystem private readonly extHostFileSystem: IExtHostConsumerFileSystem,
|
||||
@IExtHostFileSystemInfo private readonly extHostFileSystemInfo: IExtHostFileSystemInfo,
|
||||
@ILoggerService private readonly loggerService: ILoggerService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
) {
|
||||
this.proxy = extHostRpc.getProxy(MainContext.MainThreadOutputService);
|
||||
this.outputsLocation = this.extHostFileSystemInfo.extUri.joinPath(initData.logsLocation, `output_logging_${toLocalISOString(new Date()).replace(/-|:|\.\d+Z$/g, '')}`);
|
||||
@@ -136,6 +144,9 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
|
||||
throw new Error('illegal argument `name`. must not be falsy');
|
||||
}
|
||||
const log = typeof options === 'object' && options.log;
|
||||
if (log) {
|
||||
checkProposedApiEnabled(extension, 'extensionLog');
|
||||
}
|
||||
const languageId = isString(options) ? options : undefined;
|
||||
if (isString(languageId) && !languageId.trim()) {
|
||||
throw new Error('illegal argument `languageId`. must not be empty');
|
||||
@@ -226,14 +237,25 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
|
||||
}
|
||||
|
||||
private createExtHostLogOutputChannel(name: string, channelPromise: Promise<ExtHostOutputChannel>): vscode.LogOutputChannel {
|
||||
let disposed = false;
|
||||
const disposables = new DisposableStore();
|
||||
const validate = () => {
|
||||
if (disposed) {
|
||||
if (disposables.isDisposed) {
|
||||
throw new Error('Channel has been closed');
|
||||
}
|
||||
};
|
||||
let logLevel = this.logService.getLevel();
|
||||
const onDidChangeLogLevel = disposables.add(new Emitter<LogLevel>());
|
||||
channelPromise.then(channel => {
|
||||
disposables.add(channel);
|
||||
disposables.add(channel.onDidChangeLogLevel(e => {
|
||||
logLevel = e;
|
||||
onDidChangeLogLevel.fire(e);
|
||||
}));
|
||||
});
|
||||
return {
|
||||
...this.createExtHostOutputChannel(name, channelPromise),
|
||||
get logLevel() { return logLevel; },
|
||||
onDidChangeLogLevel: onDidChangeLogLevel.event,
|
||||
trace(value: string, ...args: any[]): void {
|
||||
validate();
|
||||
channelPromise.then(channel => channel.trace(value, ...args));
|
||||
@@ -255,8 +277,7 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
|
||||
channelPromise.then(channel => channel.error(value, ...args));
|
||||
},
|
||||
dispose(): void {
|
||||
disposed = true;
|
||||
channelPromise.then(channel => channel.dispose());
|
||||
disposables.dispose();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user