mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-15 07:28:05 +00:00
support passing extension log level from cli (#163566)
This commit is contained in:
committed by
GitHub
parent
af4b19dd24
commit
2b50ab06b1
@@ -48,7 +48,7 @@ export interface NativeParsedArgs {
|
||||
'trace-category-filter'?: string;
|
||||
'trace-options'?: string;
|
||||
'open-devtools'?: boolean;
|
||||
log?: string;
|
||||
log?: string[];
|
||||
logExtensionHostCommunication?: boolean;
|
||||
'extensions-dir'?: string;
|
||||
'extensions-download-dir'?: string;
|
||||
|
||||
@@ -81,6 +81,7 @@ export interface IEnvironmentService {
|
||||
// --- logging
|
||||
logsPath: string;
|
||||
logLevel?: string;
|
||||
extensionLogLevel?: [string, string][];
|
||||
verbose: boolean;
|
||||
isBuilt: boolean;
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
||||
import { ExtensionKind, IDebugParams, IExtensionHostDebugParams, INativeEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
export const EXTENSION_IDENTIFIER_WITH_LOG_REGEX = /^([^.]+\..+):(.+)$/;
|
||||
|
||||
export interface INativeEnvironmentPaths {
|
||||
|
||||
/**
|
||||
@@ -216,7 +218,20 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron
|
||||
|
||||
get isBuilt(): boolean { return !env['VSCODE_DEV']; }
|
||||
get verbose(): boolean { return !!this.args.verbose; }
|
||||
get logLevel(): string | undefined { return this.args.log; }
|
||||
|
||||
@memoize
|
||||
get logLevel(): string | undefined { return this.args.log?.find(entry => !EXTENSION_IDENTIFIER_WITH_LOG_REGEX.test(entry)); }
|
||||
@memoize
|
||||
get extensionLogLevel(): [string, string][] | undefined {
|
||||
const result: [string, string][] = [];
|
||||
for (const entry of this.args.log || []) {
|
||||
const matches = EXTENSION_IDENTIFIER_WITH_LOG_REGEX.exec(entry);
|
||||
if (matches && matches[1] && matches[2]) {
|
||||
result.push([matches[1], matches[2]]);
|
||||
}
|
||||
}
|
||||
return result.length ? result : undefined;
|
||||
}
|
||||
|
||||
@memoize
|
||||
get serviceMachineIdResource(): URI { return joinPath(URI.file(this.userDataPath), 'machineid'); }
|
||||
|
||||
@@ -93,7 +93,7 @@ export const OPTIONS: OptionDescriptions<Required<NativeParsedArgs>> = {
|
||||
|
||||
'version': { type: 'boolean', cat: 't', alias: 'v', description: localize('version', "Print version.") },
|
||||
'verbose': { type: 'boolean', cat: 't', global: true, description: localize('verbose', "Print verbose output (implies --wait).") },
|
||||
'log': { type: 'string', cat: 't', args: 'level', global: true, description: localize('log', "Log level to use. Default is 'info'. Allowed values are 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'.") },
|
||||
'log': { type: 'string[]', cat: 't', args: 'level', global: true, description: localize('log', "Log level to use. Default is 'info'. Allowed values are 'critical', 'error', 'warn', 'info', 'debug', 'trace', 'off'. You can also configure the log level of an extension by passing extension id and log level in the following format: '${publisher}.${name}:${logLevel}'. For example: 'vscode.csharp:trace'. Can receive one or more such entries.") },
|
||||
'status': { type: 'boolean', alias: 's', cat: 't', description: localize('status', "Print process usage and diagnostics information.") },
|
||||
'prof-startup': { type: 'boolean', cat: 't', description: localize('prof-startup', "Run CPU profiler during startup.") },
|
||||
'prof-append-timers': { type: 'string' },
|
||||
|
||||
@@ -147,7 +147,7 @@ export class FileLoggerService extends AbstractLoggerService implements ILoggerS
|
||||
@ILogService logService: ILogService,
|
||||
@IFileService private readonly fileService: IFileService,
|
||||
) {
|
||||
super(logService.getLevel(), logService.onDidChangeLogLevel, []);
|
||||
super(logService.getLevel(), logService.onDidChangeLogLevel);
|
||||
}
|
||||
|
||||
protected doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger {
|
||||
|
||||
@@ -112,7 +112,7 @@ export interface ILoggerService {
|
||||
/**
|
||||
* Creates a logger, or gets one if it already exists.
|
||||
*/
|
||||
createLogger(resource: URI, options?: ILoggerOptions): ILogger;
|
||||
createLogger(resource: URI, options?: ILoggerOptions, logLevel?: LogLevel): ILogger;
|
||||
|
||||
/**
|
||||
* Gets an existing logger, if any.
|
||||
@@ -128,12 +128,6 @@ export interface ILoggerService {
|
||||
* Get log level for a logger.
|
||||
*/
|
||||
getLogLevel(resource: URI): LogLevel | undefined;
|
||||
|
||||
/**
|
||||
* Get default log level for a logger with given name.
|
||||
* @param name logger name
|
||||
*/
|
||||
getDefaultLogLevel(name: string): LogLevel;
|
||||
}
|
||||
|
||||
export abstract class AbstractLogger extends Disposable {
|
||||
@@ -535,7 +529,6 @@ export abstract class AbstractLoggerService extends Disposable implements ILogge
|
||||
constructor(
|
||||
private logLevel: LogLevel,
|
||||
onDidChangeLogLevel: Event<LogLevel>,
|
||||
private readonly defaultLogLevels: [string, LogLevel][]
|
||||
) {
|
||||
super();
|
||||
this._register(onDidChangeLogLevel(logLevel => this.setLevel(logLevel)));
|
||||
@@ -549,11 +542,11 @@ export abstract class AbstractLoggerService extends Disposable implements ILogge
|
||||
return this.loggerItems.get(resource)?.logger;
|
||||
}
|
||||
|
||||
createLogger(resource: URI, options?: ILoggerOptions): ILogger {
|
||||
createLogger(resource: URI, options?: ILoggerOptions, logLevel?: LogLevel): ILogger {
|
||||
let logger = this.loggerItems.get(resource)?.logger;
|
||||
if (!logger) {
|
||||
const logLevel = options?.always ? LogLevel.Trace : undefined;
|
||||
logger = this.doCreateLogger(resource, logLevel ?? (options?.name ? this.getDefaultLogLevel(options?.name) : this.logLevel), options);
|
||||
logLevel = options?.always ? LogLevel.Trace : logLevel;
|
||||
logger = this.doCreateLogger(resource, logLevel ?? this.logLevel, options);
|
||||
this.loggerItems.set(resource, { logger, logLevel });
|
||||
}
|
||||
return logger;
|
||||
@@ -587,10 +580,6 @@ export abstract class AbstractLoggerService extends Disposable implements ILogge
|
||||
return logger?.logLevel;
|
||||
}
|
||||
|
||||
getDefaultLogLevel(name: string): LogLevel {
|
||||
return this.defaultLogLevels.find(([loggerName]) => loggerName === name)?.[1] ?? this.logLevel;
|
||||
}
|
||||
|
||||
override dispose(): void {
|
||||
this.loggerItems.forEach(({ logger }) => logger.dispose());
|
||||
this.loggerItems.clear();
|
||||
|
||||
@@ -111,7 +111,7 @@ export class LoggerChannel implements IServerChannel {
|
||||
export class LoggerChannelClient extends AbstractLoggerService implements ILoggerService {
|
||||
|
||||
constructor(logLevel: LogLevel, onDidChangeLogLevel: Event<LogLevel>, private readonly channel: IChannel) {
|
||||
super(logLevel, onDidChangeLogLevel, []);
|
||||
super(logLevel, onDidChangeLogLevel);
|
||||
}
|
||||
|
||||
createConsoleMainLogger(): ILogger {
|
||||
|
||||
@@ -13,7 +13,7 @@ export class LoggerService extends AbstractLoggerService implements ILoggerServi
|
||||
constructor(
|
||||
@ILogService logService: ILogService
|
||||
) {
|
||||
super(logService.getLevel(), logService.onDidChangeLogLevel, []);
|
||||
super(logService.getLevel(), logService.onDidChangeLogLevel);
|
||||
}
|
||||
|
||||
protected doCreateLogger(resource: URI, logLevel: LogLevel, options?: ILoggerOptions): ILogger {
|
||||
|
||||
@@ -147,7 +147,7 @@ export interface ServerParsedArgs {
|
||||
'disable-telemetry'?: boolean;
|
||||
'file-watcher-polling'?: string;
|
||||
|
||||
'log'?: string;
|
||||
'log'?: string[];
|
||||
'logsPath'?: string;
|
||||
|
||||
'force-disable-user-env'?: boolean;
|
||||
|
||||
@@ -20,7 +20,7 @@ export class ExtHostLoggerService extends AbstractLoggerService implements ExtHo
|
||||
@IExtHostRpcService rpc: IExtHostRpcService,
|
||||
@IExtHostInitDataService initData: IExtHostInitDataService,
|
||||
) {
|
||||
super(initData.logLevel, Event.None, []);
|
||||
super(initData.logLevel, Event.None);
|
||||
this._proxy = rpc.getProxy(MainContext.MainThreadLogger);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ import type * as vscode from 'vscode';
|
||||
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, ILogService, log, LogLevel } from 'vs/platform/log/common/log';
|
||||
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
import { AbstractMessageLogger, ILogger, ILoggerService, ILogService, log, LogLevel, parseLogLevel } 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';
|
||||
@@ -151,12 +151,13 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
|
||||
if (isString(languageId) && !languageId.trim()) {
|
||||
throw new Error('illegal argument `languageId`. must not be empty');
|
||||
}
|
||||
const extHostOutputChannel = log ? this.doCreateLogOutputChannel(name, extension) : this.doCreateOutputChannel(name, languageId, extension);
|
||||
const logLevel = this.getDefaultLogLevel(extension);
|
||||
const extHostOutputChannel = log ? this.doCreateLogOutputChannel(name, logLevel, extension) : this.doCreateOutputChannel(name, languageId, extension);
|
||||
extHostOutputChannel.then(channel => {
|
||||
this.channels.set(channel.id, channel);
|
||||
channel.visible = channel.id === this.visibleChannelId;
|
||||
});
|
||||
return log ? this.createExtHostLogOutputChannel(name, <Promise<ExtHostOutputChannel>>extHostOutputChannel) : this.createExtHostOutputChannel(name, <Promise<ExtHostOutputChannel>>extHostOutputChannel);
|
||||
return log ? this.createExtHostLogOutputChannel(name, logLevel, <Promise<ExtHostOutputChannel>>extHostOutputChannel) : this.createExtHostOutputChannel(name, <Promise<ExtHostOutputChannel>>extHostOutputChannel);
|
||||
}
|
||||
|
||||
private async doCreateOutputChannel(name: string, languageId: string | undefined, extension: IExtensionDescription): Promise<ExtHostOutputChannel> {
|
||||
@@ -170,14 +171,23 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
|
||||
return new ExtHostOutputChannel(id, name, logger, this.proxy, extension);
|
||||
}
|
||||
|
||||
private async doCreateLogOutputChannel(name: string, extension: IExtensionDescription): Promise<ExtHostLogOutputChannel> {
|
||||
private async doCreateLogOutputChannel(name: string, logLevel: LogLevel, extension: IExtensionDescription): Promise<ExtHostLogOutputChannel> {
|
||||
const extensionLogDir = await this.createExtensionLogDirectory(extension);
|
||||
const file = this.extHostFileSystemInfo.extUri.joinPath(extensionLogDir, `${name.replace(/[\\/:\*\?"<>\|]/g, '')}.log`);
|
||||
const logger = this.loggerService.createLogger(file, { name });
|
||||
const logger = this.loggerService.createLogger(file, { name }, logLevel);
|
||||
const id = await this.proxy.$register(name, file, true, undefined, extension.identifier.value);
|
||||
return new ExtHostLogOutputChannel(id, name, logger, this.proxy, extension);
|
||||
}
|
||||
|
||||
private getDefaultLogLevel(extension: IExtensionDescription): LogLevel {
|
||||
let logLevel: LogLevel | undefined;
|
||||
const logLevelValue = this.initData.environment.extensionLogLevel?.find(([identifier]) => ExtensionIdentifier.equals(extension.identifier, identifier))?.[1];
|
||||
if (logLevelValue) {
|
||||
logLevel = parseLogLevel(logLevelValue);
|
||||
}
|
||||
return logLevel ?? this.logService.getLevel();
|
||||
}
|
||||
|
||||
private createExtensionLogDirectory(extension: IExtensionDescription): Thenable<URI> {
|
||||
let extensionLogDirectoryPromise = this.extensionLogDirectoryPromise.get(extension.identifier.value);
|
||||
if (!extensionLogDirectoryPromise) {
|
||||
@@ -236,14 +246,13 @@ export class ExtHostOutputService implements ExtHostOutputServiceShape {
|
||||
};
|
||||
}
|
||||
|
||||
private createExtHostLogOutputChannel(name: string, channelPromise: Promise<ExtHostOutputChannel>): vscode.LogOutputChannel {
|
||||
private createExtHostLogOutputChannel(name: string, logLevel: LogLevel, channelPromise: Promise<ExtHostOutputChannel>): vscode.LogOutputChannel {
|
||||
const disposables = new DisposableStore();
|
||||
const validate = () => {
|
||||
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);
|
||||
|
||||
@@ -697,6 +697,11 @@ export interface IDevelopmentOptions {
|
||||
*/
|
||||
readonly logLevel?: LogLevel;
|
||||
|
||||
/**
|
||||
* Extension log level.
|
||||
*/
|
||||
readonly extensionLogLevel?: [string, LogLevel][];
|
||||
|
||||
/**
|
||||
* Location of a module containing extension tests to run once the workbench is open.
|
||||
*/
|
||||
|
||||
@@ -5,17 +5,19 @@
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { ILogService, LogLevel, DEFAULT_LOG_LEVEL } from 'vs/platform/log/common/log';
|
||||
import { ILogService, LogLevel, getLogLevel, parseLogLevel } from 'vs/platform/log/common/log';
|
||||
import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { dirname, basename, isEqual } from 'vs/base/common/resources';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IOutputService } from 'vs/workbench/services/output/common/output';
|
||||
import { IOutputChannelDescriptor, IOutputService } from 'vs/workbench/services/output/common/output';
|
||||
import { isUndefined } from 'vs/base/common/types';
|
||||
import { ILogLevelService } from 'vs/workbench/contrib/logs/common/logLevelService';
|
||||
import { extensionTelemetryLogChannelId, telemetryLogChannelId } from 'vs/workbench/contrib/logs/common/logConstants';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
|
||||
export class SetLogLevelAction extends Action {
|
||||
|
||||
@@ -26,19 +28,20 @@ export class SetLogLevelAction extends Action {
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@ILogLevelService private readonly logLevelService: ILogLevelService,
|
||||
@IOutputService private readonly outputService: IOutputService
|
||||
@IOutputService private readonly outputService: IOutputService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
override async run(): Promise<void> {
|
||||
const logger = await this.selectLogger();
|
||||
if (!isUndefined(logger)) {
|
||||
await this.selectLogLevel(logger);
|
||||
const logChannel = await this.selectLogChannel();
|
||||
if (!isUndefined(logChannel)) {
|
||||
await this.selectLogLevel(logChannel);
|
||||
}
|
||||
}
|
||||
|
||||
private async selectLogger(): Promise<string | undefined | null> {
|
||||
private async selectLogChannel(): Promise<IOutputChannelDescriptor | undefined | null> {
|
||||
const extensionLogs = [], logs = [];
|
||||
for (const channel of this.outputService.getChannelDescriptors()) {
|
||||
if (!channel.log || channel.id === telemetryLogChannelId || channel.id === extensionTelemetryLogChannelId) {
|
||||
@@ -50,55 +53,65 @@ export class SetLogLevelAction extends Action {
|
||||
logs.push(channel);
|
||||
}
|
||||
}
|
||||
const entries: ({ id?: string; label: string } | IQuickPickSeparator)[] = [];
|
||||
const entries: ({ label: string; channel?: IOutputChannelDescriptor } | IQuickPickSeparator)[] = [];
|
||||
entries.push({ label: nls.localize('all', "All") });
|
||||
entries.push({ type: 'separator', label: nls.localize('loggers', "Logs") });
|
||||
for (const { id, label } of logs.sort((a, b) => a.label.localeCompare(b.label))) {
|
||||
entries.push({ id, label });
|
||||
for (const channel of logs.sort((a, b) => a.label.localeCompare(b.label))) {
|
||||
entries.push({ label: channel.label, channel });
|
||||
}
|
||||
if (extensionLogs.length && logs.length) {
|
||||
entries.push({ type: 'separator', label: nls.localize('extensionLogs', "Extension Logs") });
|
||||
}
|
||||
for (const { id, label } of extensionLogs.sort((a, b) => a.label.localeCompare(b.label))) {
|
||||
entries.push({ id, label });
|
||||
for (const channel of extensionLogs.sort((a, b) => a.label.localeCompare(b.label))) {
|
||||
entries.push({ label: channel.label, channel });
|
||||
}
|
||||
const entry = await this.quickInputService.pick(entries, { placeHolder: nls.localize('selectlog', "Select Log") });
|
||||
return entry ? entry.id ?? null : undefined;
|
||||
return entry ? entry.channel ?? null : undefined;
|
||||
}
|
||||
|
||||
private async selectLogLevel(logger: string | null): Promise<void> {
|
||||
const current = (logger ? this.logLevelService.getLogLevel(logger) : undefined) ?? this.logService.getLevel();
|
||||
private async selectLogLevel(logChannel: IOutputChannelDescriptor | null): Promise<void> {
|
||||
const defaultLogLevel = this.getDefaultLogLevel(logChannel);
|
||||
const current = logChannel ? this.logLevelService.getLogLevel(logChannel.id) ?? defaultLogLevel : this.logService.getLevel();
|
||||
const entries = [
|
||||
{ label: nls.localize('trace', "Trace"), level: LogLevel.Trace, description: this.getDescription(LogLevel.Trace, current) },
|
||||
{ label: nls.localize('debug', "Debug"), level: LogLevel.Debug, description: this.getDescription(LogLevel.Debug, current) },
|
||||
{ label: nls.localize('info', "Info"), level: LogLevel.Info, description: this.getDescription(LogLevel.Info, current) },
|
||||
{ label: nls.localize('warn', "Warning"), level: LogLevel.Warning, description: this.getDescription(LogLevel.Warning, current) },
|
||||
{ label: nls.localize('err', "Error"), level: LogLevel.Error, description: this.getDescription(LogLevel.Error, current) },
|
||||
{ label: nls.localize('critical', "Critical"), level: LogLevel.Critical, description: this.getDescription(LogLevel.Critical, current) },
|
||||
{ label: nls.localize('off', "Off"), level: LogLevel.Off, description: this.getDescription(LogLevel.Off, current) },
|
||||
{ label: this.getLabel(nls.localize('trace', "Trace"), LogLevel.Trace, current), level: LogLevel.Trace, description: this.getDescription(LogLevel.Trace, defaultLogLevel) },
|
||||
{ label: this.getLabel(nls.localize('debug', "Debug"), LogLevel.Debug, current), level: LogLevel.Debug, description: this.getDescription(LogLevel.Debug, defaultLogLevel) },
|
||||
{ label: this.getLabel(nls.localize('info', "Info"), LogLevel.Info, current), level: LogLevel.Info, description: this.getDescription(LogLevel.Info, defaultLogLevel) },
|
||||
{ label: this.getLabel(nls.localize('warn', "Warning"), LogLevel.Warning, current), level: LogLevel.Warning, description: this.getDescription(LogLevel.Warning, defaultLogLevel) },
|
||||
{ label: this.getLabel(nls.localize('err', "Error"), LogLevel.Error, current), level: LogLevel.Error, description: this.getDescription(LogLevel.Error, defaultLogLevel) },
|
||||
{ label: this.getLabel(nls.localize('critical', "Critical"), LogLevel.Critical, current), level: LogLevel.Critical, description: this.getDescription(LogLevel.Critical, defaultLogLevel) },
|
||||
{ label: this.getLabel(nls.localize('off', "Off"), LogLevel.Off, current), level: LogLevel.Off, description: this.getDescription(LogLevel.Off, defaultLogLevel) },
|
||||
];
|
||||
|
||||
const entry = await this.quickInputService.pick(entries, { placeHolder: logger ? nls.localize('selectLogLevelFor', " {0}: Select log level", this.outputService.getChannelDescriptor(logger)?.label) : nls.localize('selectLogLevel', "Select log level"), activeItem: entries[this.logService.getLevel()] });
|
||||
const entry = await this.quickInputService.pick(entries, { placeHolder: logChannel ? nls.localize('selectLogLevelFor', " {0}: Select log level", logChannel?.label) : nls.localize('selectLogLevel', "Select log level"), activeItem: entries[this.logService.getLevel()] });
|
||||
if (entry) {
|
||||
if (logger) {
|
||||
this.logLevelService.setLogLevel(logger, entry.level);
|
||||
if (logChannel) {
|
||||
this.logLevelService.setLogLevel(logChannel.id, entry.level);
|
||||
} else {
|
||||
this.logService.setLevel(entry.level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private getDescription(level: LogLevel, current: LogLevel): string | undefined {
|
||||
if (DEFAULT_LOG_LEVEL === level && current === level) {
|
||||
return nls.localize('default and current', "Default & Current");
|
||||
private getLabel(label: string, level: LogLevel, current: LogLevel): string {
|
||||
if (level === current) {
|
||||
return `$(check) ${label}`;
|
||||
}
|
||||
if (DEFAULT_LOG_LEVEL === level) {
|
||||
return nls.localize('default', "Default");
|
||||
return label;
|
||||
}
|
||||
|
||||
private getDescription(level: LogLevel, defaultLogLevel: LogLevel): string | undefined {
|
||||
return defaultLogLevel === level ? nls.localize('default', "Default") : undefined;
|
||||
}
|
||||
|
||||
private getDefaultLogLevel(outputChannel: IOutputChannelDescriptor | null): LogLevel {
|
||||
let logLevel: LogLevel | undefined;
|
||||
if (outputChannel?.extensionId) {
|
||||
const logLevelValue = this.environmentService.extensionLogLevel?.find(([id]) => areSameExtensions({ id }, { id: outputChannel.extensionId! }))?.[1];
|
||||
if (logLevelValue) {
|
||||
logLevel = parseLogLevel(logLevelValue);
|
||||
}
|
||||
}
|
||||
if (current === level) {
|
||||
return nls.localize('current', "Current");
|
||||
}
|
||||
return undefined;
|
||||
return logLevel ?? getLogLevel(this.environmentService);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import { LogLevelToString } from 'vs/platform/log/common/log';
|
||||
import { isUndefined } from 'vs/base/common/types';
|
||||
import { refineServiceDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITextEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { EXTENSION_IDENTIFIER_WITH_LOG_REGEX } from 'vs/platform/environment/common/environmentService';
|
||||
|
||||
export const IBrowserWorkbenchEnvironmentService = refineServiceDecorator<IEnvironmentService, IBrowserWorkbenchEnvironmentService>(IEnvironmentService);
|
||||
|
||||
@@ -47,7 +48,28 @@ export class BrowserWorkbenchEnvironmentService implements IBrowserWorkbenchEnvi
|
||||
get logsPath(): string { return this.logsHome.path; }
|
||||
|
||||
@memoize
|
||||
get logLevel(): string | undefined { return this.payload?.get('logLevel') || (this.options.developmentOptions?.logLevel !== undefined ? LogLevelToString(this.options.developmentOptions?.logLevel) : undefined); }
|
||||
get logLevel(): string | undefined {
|
||||
const logLevelFromPayload = this.payload?.get('logLevel');
|
||||
if (logLevelFromPayload) {
|
||||
return logLevelFromPayload.split(',').find(entry => !EXTENSION_IDENTIFIER_WITH_LOG_REGEX.test(entry));
|
||||
}
|
||||
return this.options.developmentOptions?.logLevel !== undefined ? LogLevelToString(this.options.developmentOptions?.logLevel) : undefined;
|
||||
}
|
||||
|
||||
get extensionLogLevel(): [string, string][] | undefined {
|
||||
const logLevelFromPayload = this.payload?.get('logLevel');
|
||||
if (logLevelFromPayload) {
|
||||
const result: [string, string][] = [];
|
||||
for (const entry of logLevelFromPayload.split(',')) {
|
||||
const matches = EXTENSION_IDENTIFIER_WITH_LOG_REGEX.exec(entry);
|
||||
if (matches && matches[1] && matches[2]) {
|
||||
result.push([matches[1], matches[2]]);
|
||||
}
|
||||
}
|
||||
return result.length ? result : undefined;
|
||||
}
|
||||
return this.options.developmentOptions?.extensionLogLevel !== undefined ? this.options.developmentOptions?.extensionLogLevel.map(([extension, logLevel]) => ([extension, LogLevelToString(logLevel)])) : undefined;
|
||||
}
|
||||
|
||||
@memoize
|
||||
get logFile(): URI { return joinPath(this.logsHome, 'window.log'); }
|
||||
|
||||
@@ -298,6 +298,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
||||
extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI,
|
||||
globalStorageHome: this._userDataProfilesService.defaultProfile.globalStorageHome,
|
||||
workspaceStorageHome: this._environmentService.workspaceStorageHome,
|
||||
extensionLogLevel: this._environmentService.extensionLogLevel
|
||||
},
|
||||
workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : {
|
||||
configuration: workspace.configuration || undefined,
|
||||
|
||||
@@ -54,6 +54,7 @@ export interface IEnvironment {
|
||||
workspaceStorageHome: URI;
|
||||
useHostProxy?: boolean;
|
||||
skipWorkspaceStorageLock?: boolean;
|
||||
extensionLogLevel?: [string, string][];
|
||||
}
|
||||
|
||||
export interface IStaticWorkspaceData {
|
||||
|
||||
@@ -226,7 +226,8 @@ export class RemoteExtensionHost extends Disposable implements IExtensionHost {
|
||||
extensionDevelopmentLocationURI: this._environmentService.extensionDevelopmentLocationURI,
|
||||
extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI,
|
||||
globalStorageHome: remoteInitData.globalStorageHome,
|
||||
workspaceStorageHome: remoteInitData.workspaceStorageHome
|
||||
workspaceStorageHome: remoteInitData.workspaceStorageHome,
|
||||
extensionLogLevel: this._environmentService.extensionLogLevel
|
||||
},
|
||||
workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? null : {
|
||||
configuration: workspace.configuration,
|
||||
|
||||
@@ -450,6 +450,7 @@ export class SandboxLocalProcessExtensionHost implements IExtensionHost {
|
||||
extensionTestsLocationURI: this._environmentService.extensionTestsLocationURI,
|
||||
globalStorageHome: this._userDataProfilesService.defaultProfile.globalStorageHome,
|
||||
workspaceStorageHome: this._environmentService.workspaceStorageHome,
|
||||
extensionLogLevel: this._environmentService.extensionLogLevel
|
||||
},
|
||||
workspace: this._contextService.getWorkbenchState() === WorkbenchState.EMPTY ? undefined : {
|
||||
configuration: withNullAsUndefined(workspace.configuration),
|
||||
|
||||
Reference in New Issue
Block a user