Re-use LogLevel enum from VS Code API (#15645)
* Re-use LogLevel enum from VS Code API * Fix formatting * Fix errors
This commit is contained in:
Родитель
e85320600d
Коммит
f6e4b43295
|
@ -1479,14 +1479,13 @@
|
|||
},
|
||||
"jupyter.logging.level": {
|
||||
"type": "string",
|
||||
"default": "debug",
|
||||
"default": "info",
|
||||
"enum": [
|
||||
"off",
|
||||
"error",
|
||||
"warn",
|
||||
"info",
|
||||
"debug",
|
||||
"verbose"
|
||||
"debug"
|
||||
],
|
||||
"description": "%jupyter.configuration.jupyter.logging.level.description%"
|
||||
},
|
||||
|
|
|
@ -14,32 +14,41 @@ import {
|
|||
type Memento,
|
||||
type Disposable,
|
||||
type ProgressOptions,
|
||||
ProgressLocation
|
||||
ProgressLocation,
|
||||
commands
|
||||
} from 'vscode';
|
||||
import {
|
||||
STANDARD_OUTPUT_CHANNEL,
|
||||
JUPYTER_OUTPUT_CHANNEL,
|
||||
PylanceExtension,
|
||||
PythonExtension
|
||||
PythonExtension,
|
||||
Telemetry
|
||||
} from './platform/common/constants';
|
||||
import { getDisplayPath } from './platform/common/platform/fs-paths';
|
||||
import {
|
||||
GLOBAL_MEMENTO,
|
||||
IConfigurationService,
|
||||
IDisposableRegistry,
|
||||
IExperimentService,
|
||||
IExtensionContext,
|
||||
IFeaturesManager,
|
||||
IMemento,
|
||||
IOutputChannel,
|
||||
WORKSPACE_MEMENTO
|
||||
} from './platform/common/types';
|
||||
import { Common, OutputChannelNames } from './platform/common/utils/localize';
|
||||
import { IServiceContainer, IServiceManager } from './platform/ioc/types';
|
||||
import { registerLogger, traceError } from './platform/logging';
|
||||
import { registerLogger, setLoggingLevel, traceError } from './platform/logging';
|
||||
import { OutputChannelLogger } from './platform/logging/outputChannelLogger';
|
||||
import { getJupyterOutputChannel } from './standalone/devTools/jupyterOutputChannel';
|
||||
import { isUsingPylance } from './standalone/intellisense/notebookPythonPathService';
|
||||
import { noop } from './platform/common/utils/misc';
|
||||
import { sendErrorTelemetry } from './platform/telemetry/startupTelemetry';
|
||||
import { createDeferred } from './platform/common/utils/async';
|
||||
import { StopWatch } from './platform/common/utils/stopWatch';
|
||||
import { sendTelemetryEvent } from './telemetry';
|
||||
import { IExtensionActivationManager } from './platform/activation/types';
|
||||
import { getVSCodeChannel } from './platform/common/application/applicationEnvironment';
|
||||
|
||||
export function addOutputChannel(
|
||||
context: IExtensionContext,
|
||||
|
@ -143,3 +152,38 @@ function notifyUser(msg: string) {
|
|||
traceError('failed to notify user', ex);
|
||||
}
|
||||
}
|
||||
|
||||
export async function postActivateLegacy(
|
||||
context: IExtensionContext,
|
||||
serviceManager: IServiceManager,
|
||||
serviceContainer: IServiceContainer
|
||||
) {
|
||||
// Load the two data science experiments that we need to register types
|
||||
// Await here to keep the register method sync
|
||||
const experimentService = serviceContainer.get<IExperimentService>(IExperimentService);
|
||||
// This must be done first, this guarantees all experiment information has loaded & all telemetry will contain experiment info.
|
||||
const stopWatch = new StopWatch();
|
||||
await experimentService.activate();
|
||||
const duration = stopWatch.elapsedTime;
|
||||
sendTelemetryEvent(Telemetry.ExperimentLoad, { duration });
|
||||
|
||||
const configuration = serviceManager.get<IConfigurationService>(IConfigurationService);
|
||||
|
||||
// We should start logging using the log level as soon as possible, so set it as soon as we can access the level.
|
||||
// `IConfigurationService` may depend any of the registered types, so doing it after all registrations are finished.
|
||||
// XXX Move this *after* abExperiments is activated?
|
||||
const settings = configuration.getSettings();
|
||||
setLoggingLevel(settings.logging.level, settings.logging.widgets);
|
||||
context.subscriptions.push(
|
||||
settings.onDidChange(() => setLoggingLevel(settings.logging.level, settings.logging.widgets))
|
||||
);
|
||||
|
||||
// "initialize" "services"
|
||||
commands.executeCommand('setContext', 'jupyter.vscode.channel', getVSCodeChannel()).then(noop, noop);
|
||||
|
||||
// "activate" everything else
|
||||
serviceContainer.get<IExtensionActivationManager>(IExtensionActivationManager).activate();
|
||||
const featureManager = serviceContainer.get<IFeaturesManager>(IFeaturesManager);
|
||||
featureManager.initialize();
|
||||
context.subscriptions.push(featureManager);
|
||||
}
|
||||
|
|
|
@ -38,14 +38,7 @@ import './platform/logging';
|
|||
import { commands, env, ExtensionMode, UIKind, workspace } from 'vscode';
|
||||
import { buildApi, IExtensionApi } from './standalone/api';
|
||||
import { setHomeDirectory, traceError } from './platform/logging';
|
||||
import {
|
||||
IAsyncDisposableRegistry,
|
||||
IConfigurationService,
|
||||
IExperimentService,
|
||||
IExtensionContext,
|
||||
IFeaturesManager,
|
||||
IsDevMode
|
||||
} from './platform/common/types';
|
||||
import { IAsyncDisposableRegistry, IExtensionContext, IsDevMode } from './platform/common/types';
|
||||
import { IServiceContainer, IServiceManager } from './platform/ioc/types';
|
||||
import { sendStartupTelemetry } from './platform/telemetry/startupTelemetry';
|
||||
import { noop } from './platform/common/utils/misc';
|
||||
|
@ -55,16 +48,8 @@ import { registerTypes as registerNotebookTypes } from './notebooks/serviceRegis
|
|||
import { registerTypes as registerInteractiveTypes } from './interactive-window/serviceRegistry.node';
|
||||
import { registerTypes as registerStandaloneTypes } from './standalone/serviceRegistry.node';
|
||||
import { registerTypes as registerWebviewTypes } from './webviews/extension-side/serviceRegistry.node';
|
||||
import { IExtensionActivationManager } from './platform/activation/types';
|
||||
import {
|
||||
Exiting,
|
||||
isCI,
|
||||
isTestExecution,
|
||||
setIsCodeSpace,
|
||||
setIsWebExtension,
|
||||
Telemetry
|
||||
} from './platform/common/constants';
|
||||
import { registerLogger, setLoggingLevel } from './platform/logging';
|
||||
import { Exiting, isCI, isTestExecution, setIsCodeSpace, setIsWebExtension } from './platform/common/constants';
|
||||
import { registerLogger } from './platform/logging';
|
||||
import { ConsoleLogger } from './platform/logging/consoleLogger';
|
||||
import { initializeGlobals as initializeTelemetryGlobals } from './platform/telemetry/telemetry';
|
||||
import { IInterpreterPackages } from './platform/interpreter/types';
|
||||
|
@ -77,9 +62,13 @@ import {
|
|||
} from './standalone/executionAnalysis/extension';
|
||||
import { activate as activateChat, deactivate as deactivateChat } from './standalone/chat/extesnion';
|
||||
import { setDisposableTracker } from './platform/common/utils/lifecycle';
|
||||
import { sendTelemetryEvent } from './telemetry';
|
||||
import { getVSCodeChannel } from './platform/common/application/applicationEnvironment';
|
||||
import { addOutputChannel, displayProgress, handleError, initializeGlobals } from './extension.common';
|
||||
import {
|
||||
addOutputChannel,
|
||||
displayProgress,
|
||||
handleError,
|
||||
initializeGlobals,
|
||||
postActivateLegacy
|
||||
} from './extension.common';
|
||||
import { activateNotebookTelemetry } from './kernels/telemetry/notebookTelemetry';
|
||||
|
||||
durations.codeLoadingTime = stopWatch.elapsedTime;
|
||||
|
@ -276,32 +265,5 @@ async function activateLegacy(
|
|||
registerStandaloneTypes(context, serviceManager, isDevMode);
|
||||
registerWebviewTypes(serviceManager);
|
||||
|
||||
// Load the two data science experiments that we need to register types
|
||||
// Await here to keep the register method sync
|
||||
const experimentService = serviceContainer.get<IExperimentService>(IExperimentService);
|
||||
// This must be done first, this guarantees all experiment information has loaded & all telemetry will contain experiment info.
|
||||
const stopWatch = new StopWatch();
|
||||
await experimentService.activate();
|
||||
const duration = stopWatch.elapsedTime;
|
||||
sendTelemetryEvent(Telemetry.ExperimentLoad, { duration });
|
||||
const configuration = serviceManager.get<IConfigurationService>(IConfigurationService);
|
||||
|
||||
// We should start logging using the log level as soon as possible, so set it as soon as we can access the level.
|
||||
// `IConfigurationService` may depend any of the registered types, so doing it after all registrations are finished.
|
||||
// XXX Move this *after* abExperiments is activated?
|
||||
const settings = configuration.getSettings();
|
||||
setLoggingLevel(settings.logging.level, settings.logging.widgets);
|
||||
settings.onDidChange(() => {
|
||||
setLoggingLevel(settings.logging.level, settings.logging.widgets);
|
||||
});
|
||||
|
||||
// "initialize" "services"
|
||||
commands.executeCommand('setContext', 'jupyter.vscode.channel', getVSCodeChannel()).then(noop, noop);
|
||||
|
||||
// "activate" everything else
|
||||
serviceContainer.get<IExtensionActivationManager>(IExtensionActivationManager).activate();
|
||||
|
||||
const featureManager = serviceContainer.get<IFeaturesManager>(IFeaturesManager);
|
||||
featureManager.initialize();
|
||||
context.subscriptions.push(featureManager);
|
||||
await postActivateLegacy(context, serviceManager, serviceContainer);
|
||||
}
|
||||
|
|
|
@ -49,14 +49,7 @@ import './platform/logging';
|
|||
import { commands, env, ExtensionMode, UIKind, workspace } from 'vscode';
|
||||
import { buildApi, IExtensionApi } from './standalone/api';
|
||||
import { traceError } from './platform/logging';
|
||||
import {
|
||||
IAsyncDisposableRegistry,
|
||||
IConfigurationService,
|
||||
IExperimentService,
|
||||
IExtensionContext,
|
||||
IFeaturesManager,
|
||||
IsDevMode
|
||||
} from './platform/common/types';
|
||||
import { IAsyncDisposableRegistry, IExtensionContext, IsDevMode } from './platform/common/types';
|
||||
import { IServiceContainer, IServiceManager } from './platform/ioc/types';
|
||||
import { sendStartupTelemetry } from './platform/telemetry/startupTelemetry';
|
||||
import { noop } from './platform/common/utils/misc';
|
||||
|
@ -67,22 +60,18 @@ import { registerTypes as registerInteractiveTypes } from './interactive-window/
|
|||
import { registerTypes as registerTerminalTypes } from './platform/terminals/serviceRegistry.web';
|
||||
import { registerTypes as registerStandaloneTypes } from './standalone/serviceRegistry.web';
|
||||
import { registerTypes as registerWebviewTypes } from './webviews/extension-side/serviceRegistry.web';
|
||||
import { IExtensionActivationManager } from './platform/activation/types';
|
||||
import {
|
||||
Exiting,
|
||||
isCI,
|
||||
isTestExecution,
|
||||
setIsCodeSpace,
|
||||
setIsWebExtension,
|
||||
Telemetry
|
||||
} from './platform/common/constants';
|
||||
import { registerLogger, setLoggingLevel } from './platform/logging';
|
||||
import { Exiting, isCI, isTestExecution, setIsCodeSpace, setIsWebExtension } from './platform/common/constants';
|
||||
import { registerLogger } from './platform/logging';
|
||||
import { ConsoleLogger } from './platform/logging/consoleLogger';
|
||||
import { initializeGlobals as initializeTelemetryGlobals } from './platform/telemetry/telemetry';
|
||||
import { setDisposableTracker } from './platform/common/utils/lifecycle';
|
||||
import { sendTelemetryEvent } from './telemetry';
|
||||
import { getVSCodeChannel } from './platform/common/application/applicationEnvironment';
|
||||
import { addOutputChannel, displayProgress, handleError, initializeGlobals } from './extension.common';
|
||||
import {
|
||||
addOutputChannel,
|
||||
displayProgress,
|
||||
handleError,
|
||||
initializeGlobals,
|
||||
postActivateLegacy
|
||||
} from './extension.common';
|
||||
import { activateNotebookTelemetry } from './kernels/telemetry/notebookTelemetry';
|
||||
|
||||
durations.codeLoadingTime = stopWatch.elapsedTime;
|
||||
|
@ -234,32 +223,5 @@ async function activateLegacy(
|
|||
registerStandaloneTypes(context, serviceManager, isDevMode);
|
||||
registerWebviewTypes(serviceManager);
|
||||
|
||||
// Load the two data science experiments that we need to register types
|
||||
// Await here to keep the register method sync
|
||||
const experimentService = serviceContainer.get<IExperimentService>(IExperimentService);
|
||||
// This must be done first, this guarantees all experiment information has loaded & all telemetry will contain experiment info.
|
||||
const stopWatch = new StopWatch();
|
||||
await experimentService.activate();
|
||||
const duration = stopWatch.elapsedTime;
|
||||
sendTelemetryEvent(Telemetry.ExperimentLoad, { duration });
|
||||
|
||||
const configuration = serviceManager.get<IConfigurationService>(IConfigurationService);
|
||||
|
||||
// We should start logging using the log level as soon as possible, so set it as soon as we can access the level.
|
||||
// `IConfigurationService` may depend any of the registered types, so doing it after all registrations are finished.
|
||||
// XXX Move this *after* abExperiments is activated?
|
||||
const settings = configuration.getSettings();
|
||||
setLoggingLevel(settings.logging.level, settings.logging.widgets);
|
||||
settings.onDidChange(() => {
|
||||
setLoggingLevel(settings.logging.level, settings.logging.widgets);
|
||||
});
|
||||
|
||||
// "initialize" "services"
|
||||
commands.executeCommand('setContext', 'jupyter.vscode.channel', getVSCodeChannel()).then(noop, noop);
|
||||
|
||||
// "activate" everything else
|
||||
serviceContainer.get<IExtensionActivationManager>(IExtensionActivationManager).activate();
|
||||
const featureManager = serviceContainer.get<IFeaturesManager>(IFeaturesManager);
|
||||
featureManager.initialize();
|
||||
context.subscriptions.push(featureManager);
|
||||
await postActivateLegacy(context, serviceManager, serviceContainer);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,8 @@ import {
|
|||
ViewColumn,
|
||||
workspace,
|
||||
WorkspaceEdit,
|
||||
window
|
||||
window,
|
||||
LogLevel
|
||||
} from 'vscode';
|
||||
import { IKernelProvider, KernelConnectionMetadata } from '../../kernels/types';
|
||||
import { ICommandNameArgumentTypeMapping } from '../../commands';
|
||||
|
@ -232,7 +233,7 @@ export class CommandRegistry implements IDisposable, IExtensionSyncActivationSer
|
|||
|
||||
private async enableDebugLogging() {
|
||||
const previousValue = this.configService.getSettings().logging.level;
|
||||
if (previousValue !== 'debug') {
|
||||
if (previousValue !== LogLevel.Debug) {
|
||||
await this.configService.updateSetting('logging.level', 'debug', undefined, ConfigurationTarget.Global);
|
||||
commands.executeCommand('jupyter.reloadVSCode', DataScience.reloadRequired).then(noop, noop);
|
||||
}
|
||||
|
@ -240,7 +241,7 @@ export class CommandRegistry implements IDisposable, IExtensionSyncActivationSer
|
|||
|
||||
private async resetLoggingLevel() {
|
||||
const previousValue = this.configService.getSettings().logging.level;
|
||||
if (previousValue !== 'error') {
|
||||
if (previousValue !== LogLevel.Error) {
|
||||
await this.configService.updateSetting('logging.level', 'error', undefined, ConfigurationTarget.Global);
|
||||
commands.executeCommand('jupyter.reloadVSCode', DataScience.reloadRequired).then(noop, noop);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
NotebookCellOutputItem,
|
||||
TextDocument
|
||||
} from 'vscode';
|
||||
import { traceInfo, traceVerbose } from '../../platform/logging';
|
||||
import { traceVerbose } from '../../platform/logging';
|
||||
import { IKernelController } from '../types';
|
||||
import { noop } from '../../platform/common/utils/misc';
|
||||
import { getNotebookTelemetryTracker } from '../telemetry/notebookTelemetry';
|
||||
|
@ -78,7 +78,7 @@ export class NotebookCellExecutionWrapper implements NotebookCellExecution {
|
|||
if (this._endCallback) {
|
||||
try {
|
||||
this._impl.end(success, endTime, this.errorInfo);
|
||||
traceInfo(
|
||||
traceVerbose(
|
||||
`Cell ${this.cell.index} completed in ${
|
||||
((endTime || 0) - (this._startTime || 0)) / 1000
|
||||
}s (start: ${this._startTime}, end: ${endTime})`
|
||||
|
|
|
@ -61,17 +61,13 @@ export class JupyterServerHelper implements IJupyterServerHelper {
|
|||
}
|
||||
|
||||
public async dispose(): Promise<void> {
|
||||
traceInfo(`Disposing HostJupyterExecution`);
|
||||
if (!this._disposed) {
|
||||
this._disposed = true;
|
||||
traceVerbose(`Disposing super HostJupyterExecution`);
|
||||
this.disposed = true;
|
||||
|
||||
// Cleanup on dispose. We are going away permanently
|
||||
traceVerbose(`Cleaning up server cache`);
|
||||
await this.cache?.then((s) => s.dispose()).catch(noop);
|
||||
}
|
||||
traceVerbose(`Finished disposing HostJupyterExecution`);
|
||||
}
|
||||
|
||||
public async startServer(resource: Resource, cancelToken: CancellationToken): Promise<IJupyterConnection> {
|
||||
|
@ -162,7 +158,7 @@ export class JupyterServerHelper implements IJupyterServerHelper {
|
|||
private async startImpl(resource: Resource, cancelToken: CancellationToken): Promise<IJupyterConnection> {
|
||||
// If our uri is undefined or if it's set to local launch we need to launch a server locally
|
||||
// If that works, then attempt to start the server
|
||||
traceInfo(`Launching server`);
|
||||
traceVerbose(`Launching server`);
|
||||
const settings = this.configuration.getSettings(resource);
|
||||
const useDefaultConfig = settings.useDefaultConfigForJupyter;
|
||||
const workingDir = await computeWorkingDirectory(resource);
|
||||
|
|
|
@ -65,7 +65,7 @@ export class JupyterServerStarter implements IJupyterServerStarter {
|
|||
workingDirectory: Uri,
|
||||
cancelToken: CancellationToken
|
||||
): Promise<IJupyterConnection> {
|
||||
traceInfo('Starting Notebook');
|
||||
traceInfo('Starting Jupyter Server');
|
||||
// Now actually launch it
|
||||
let exitCode: number | null = 0;
|
||||
let starter: JupyterConnectionWaiter | undefined;
|
||||
|
@ -87,7 +87,6 @@ export class JupyterServerStarter implements IJupyterServerStarter {
|
|||
Cancellation.throwIfCanceled(cancelToken);
|
||||
|
||||
// Then use this to launch our notebook process.
|
||||
traceVerbose('Starting Jupyter Notebook');
|
||||
const [launchResult, tempDir, interpreter] = await Promise.all([
|
||||
this.jupyterInterpreterService.startNotebook(args || [], {
|
||||
throwOnStdErr: false,
|
||||
|
@ -256,7 +255,7 @@ export class JupyterServerStarter implements IJupyterServerStarter {
|
|||
// as starting jupyter with all of the defaults.
|
||||
const configFile = path.join(tempDir.path, 'jupyter_notebook_config.py');
|
||||
await this.fs.writeFile(Uri.file(configFile), '');
|
||||
traceInfo(`Generating custom default config at ${configFile}`);
|
||||
traceVerbose(`Generating custom default config at ${configFile}`);
|
||||
|
||||
// Create extra args based on if we have a config or not
|
||||
return `--config=${configFile}`;
|
||||
|
|
|
@ -237,7 +237,7 @@ export class NotebookKernelExecution implements INotebookKernelExecution {
|
|||
.finally(() => {
|
||||
completed = true;
|
||||
!token.isCancellationRequested &&
|
||||
traceInfo(`Execution of code ${result.executionId} completed in ${stopWatch.elapsedTime}ms`);
|
||||
traceVerbose(`Execution of code ${result.executionId} completed in ${stopWatch.elapsedTime}ms`);
|
||||
if (extensionId !== JVSC_EXTENSION_ID) {
|
||||
sendKernelTelemetryEvent(
|
||||
this.kernel.resourceUri,
|
||||
|
|
|
@ -392,7 +392,7 @@ export class VSCodeNotebookController implements Disposable, IVSCodeNotebookCont
|
|||
if (!workspace.isTrusted) {
|
||||
return;
|
||||
}
|
||||
traceInfo(`Handle Execution of Cells ${cells.map((c) => c.index)} for ${getDisplayPath(notebook.uri)}`);
|
||||
traceVerbose(`Handle Execution of Cells ${cells.map((c) => c.index)} for ${getDisplayPath(notebook.uri)}`);
|
||||
await initializeInteractiveOrNotebookTelemetryBasedOnUserAction(notebook.uri, this.connection);
|
||||
telemetryTracker?.stop();
|
||||
// Notebook is trusted. Continue to execute cells
|
||||
|
|
|
@ -21,7 +21,7 @@ import { sendTelemetryEvent } from '../../telemetry';
|
|||
import { isCI, PythonExtension, Telemetry } from '../common/constants';
|
||||
import { IDisposableRegistry, IExtensionContext } from '../common/types';
|
||||
import { createDeferred, sleep } from '../common/utils/async';
|
||||
import { traceError, traceInfo, traceInfoIfCI, traceVerbose, traceWarning } from '../logging';
|
||||
import { traceError, traceInfoIfCI, traceVerbose, traceWarning } from '../logging';
|
||||
import { getDisplayPath, getFilePath } from '../common/platform/fs-paths';
|
||||
import { IInterpreterService } from '../interpreter/contracts';
|
||||
import { areInterpreterPathsSame, getInterpreterHash } from '../pythonEnvironments/info/interpreter';
|
||||
|
@ -448,7 +448,7 @@ export class InterpreterService implements IInterpreterService {
|
|||
}
|
||||
this.lastLoggedResourceAndInterpreterId = key;
|
||||
const version = getCachedVersion(item);
|
||||
traceInfo(
|
||||
traceVerbose(
|
||||
`Active Interpreter ${resource ? `for '${getDisplayPath(resource)}' ` : ''}is ${getDisplayPath(
|
||||
item?.id
|
||||
)} (${item && getEnvironmentType(item)}, '${
|
||||
|
|
|
@ -7,11 +7,11 @@ import {
|
|||
Disposable,
|
||||
Event,
|
||||
EventEmitter,
|
||||
LogLevel,
|
||||
Uri,
|
||||
WorkspaceConfiguration,
|
||||
workspace
|
||||
} from 'vscode';
|
||||
import { LogLevel } from '../logging/types';
|
||||
import { isTestExecution } from './constants';
|
||||
import {
|
||||
IExperiments,
|
||||
|
@ -41,7 +41,7 @@ export class JupyterSettings implements IWatchableJupyterSettings {
|
|||
|
||||
private static jupyterSettings: Map<string, JupyterSettings> = new Map<string, JupyterSettings>();
|
||||
public experiments!: IExperiments;
|
||||
public logging: ILoggingSettings = { level: 'error' };
|
||||
public logging: ILoggingSettings = { level: LogLevel.Error };
|
||||
public allowUnauthorizedRemoteConnection: boolean = false;
|
||||
public jupyterInterruptTimeout: number = 10_000;
|
||||
public jupyterLaunchTimeout: number = 60_000;
|
||||
|
@ -291,19 +291,16 @@ function convertSettingTypeToLogLevel(setting: LoggingLevelSettingType | undefin
|
|||
return LogLevel.Info;
|
||||
}
|
||||
case 'warn': {
|
||||
return LogLevel.Warn;
|
||||
return LogLevel.Warning;
|
||||
}
|
||||
case 'off': {
|
||||
return 'off';
|
||||
}
|
||||
case 'debug': {
|
||||
return LogLevel.Debug;
|
||||
}
|
||||
case 'verbose': {
|
||||
return LogLevel.Trace;
|
||||
case 'error': {
|
||||
return LogLevel.Error;
|
||||
}
|
||||
default: {
|
||||
return LogLevel.Error;
|
||||
return LogLevel.Debug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Memento, workspace } from 'vscode';
|
|||
import { getExperimentationService, IExperimentationService, TargetPopulation } from 'vscode-tas-client';
|
||||
import { IApplicationEnvironment } from '../application/types';
|
||||
import { JVSC_EXTENSION_ID, isPreReleaseVersion } from '../constants';
|
||||
import { traceInfo, traceVerbose } from '../../logging';
|
||||
import { traceInfo } from '../../logging';
|
||||
import { GLOBAL_MEMENTO, IConfigurationService, IExperimentService, IJupyterSettings, IMemento } from '../types';
|
||||
import { Experiments } from '../utils/localize';
|
||||
import { Experiments as ExperimentGroups } from '../types';
|
||||
|
@ -78,7 +78,6 @@ export class ExperimentService implements IExperimentService {
|
|||
|
||||
public async activate() {
|
||||
if (this.experimentationService && this.enabled) {
|
||||
traceVerbose(`Experimentation service retrieved: ${this.experimentationService}`);
|
||||
await this.experimentationService.initializePromise;
|
||||
if (this.getFeatures().length === 0) {
|
||||
// Only await on this if we don't have anything in cache.
|
||||
|
|
|
@ -1,7 +1,16 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import { ConfigurationTarget, Disposable, Event, ExtensionContext, OutputChannel, Uri, Range } from 'vscode';
|
||||
import {
|
||||
ConfigurationTarget,
|
||||
Disposable,
|
||||
Event,
|
||||
ExtensionContext,
|
||||
OutputChannel,
|
||||
Uri,
|
||||
Range,
|
||||
type LogLevel
|
||||
} from 'vscode';
|
||||
import { PythonEnvironment } from '../pythonEnvironments/info';
|
||||
import { CommandIds } from '../../commands';
|
||||
import { ISystemVariables } from './variables/types';
|
||||
|
@ -107,10 +116,10 @@ export interface IWatchableJupyterSettings extends IJupyterSettings {
|
|||
createSystemVariables(resource: Resource): ISystemVariables;
|
||||
}
|
||||
|
||||
export type LoggingLevelSettingType = 'off' | 'error' | 'warn' | 'info' | 'debug' | 'verbose';
|
||||
export type LoggingLevelSettingType = 'off' | 'error' | 'warn' | 'info' | 'debug';
|
||||
|
||||
export interface ILoggingSettings {
|
||||
readonly level: LoggingLevelSettingType | 'off';
|
||||
readonly level: LogLevel;
|
||||
readonly widgets?: LoggingLevelSettingType | 'off';
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,10 @@
|
|||
|
||||
import { isTestExecution } from '../constants';
|
||||
import { DataWithExpiry, getCacheKeyFromFunctionArgs, getGlobalCacheStore } from './cacheUtils';
|
||||
import { noop, TraceInfo, tracing } from './misc';
|
||||
import { traceError, traceVerbose } from '../../logging';
|
||||
import { noop } from './misc';
|
||||
import { traceError, traceVerbose, type TraceInfo } from '../../logging';
|
||||
import { StopWatch } from './stopWatch';
|
||||
import { isPromise } from './async';
|
||||
|
||||
type PromiseFunctionWithAnyArgs = (...any: any) => Promise<any>;
|
||||
const cacheStoreForMethods = getGlobalCacheStore();
|
||||
|
@ -88,6 +90,39 @@ export type CallInfo = {
|
|||
target: Object;
|
||||
};
|
||||
|
||||
// Call run(), call log() with the trace info, and return the result.
|
||||
function tracing<T>(log: (t: TraceInfo) => void, run: () => T, logBeforeCall?: boolean): T {
|
||||
const timer = new StopWatch();
|
||||
try {
|
||||
if (logBeforeCall) {
|
||||
log(undefined);
|
||||
}
|
||||
// eslint-disable-next-line no-invalid-this, @typescript-eslint/no-use-before-define,
|
||||
const result = run();
|
||||
|
||||
// If method being wrapped returns a promise then wait for it.
|
||||
if (isPromise(result)) {
|
||||
// eslint-disable-next-line
|
||||
(result as Promise<void>)
|
||||
.then((data) => {
|
||||
log({ elapsed: timer.elapsedTime, returnValue: data });
|
||||
return data;
|
||||
})
|
||||
.catch((ex) => {
|
||||
log({ elapsed: timer.elapsedTime, err: ex });
|
||||
// eslint-disable-next-line
|
||||
// TODO(GH-11645) Re-throw the error like we do
|
||||
// in the non-Promise case.
|
||||
});
|
||||
} else {
|
||||
log({ elapsed: timer.elapsedTime, returnValue: result });
|
||||
}
|
||||
return result;
|
||||
} catch (ex) {
|
||||
log({ elapsed: timer.elapsedTime, err: ex });
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
// Return a decorator that traces the decorated function.
|
||||
export function trace(log: (c: CallInfo, t: TraceInfo) => void, logBeforeCall?: boolean) {
|
||||
// eslint-disable-next-line , @typescript-eslint/no-explicit-any
|
||||
|
|
|
@ -5,7 +5,6 @@ import type { TextDocument, Uri } from 'vscode';
|
|||
import { NotebookCellScheme } from '../constants';
|
||||
import { InterpreterUri, Resource } from '../types';
|
||||
import { isPromise } from './async';
|
||||
import { StopWatch } from './stopWatch';
|
||||
import { Environment } from '@vscode/python-extension';
|
||||
|
||||
// eslint-disable-next-line no-empty,@typescript-eslint/no-empty-function
|
||||
|
@ -60,51 +59,6 @@ export type ExcludeType<T, Value> = {
|
|||
[P in keyof T as T[P] extends Value ? never : P]: T[P];
|
||||
};
|
||||
|
||||
// Information about a traced function/method call.
|
||||
export type TraceInfo =
|
||||
| {
|
||||
elapsed: number; // milliseconds
|
||||
// Either returnValue or err will be set.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
returnValue?: any;
|
||||
err?: Error;
|
||||
}
|
||||
| undefined;
|
||||
|
||||
// Call run(), call log() with the trace info, and return the result.
|
||||
export function tracing<T>(log: (t: TraceInfo) => void, run: () => T, logBeforeCall?: boolean): T {
|
||||
const timer = new StopWatch();
|
||||
try {
|
||||
if (logBeforeCall) {
|
||||
log(undefined);
|
||||
}
|
||||
// eslint-disable-next-line no-invalid-this, @typescript-eslint/no-use-before-define,
|
||||
const result = run();
|
||||
|
||||
// If method being wrapped returns a promise then wait for it.
|
||||
if (isPromise(result)) {
|
||||
// eslint-disable-next-line
|
||||
(result as Promise<void>)
|
||||
.then((data) => {
|
||||
log({ elapsed: timer.elapsedTime, returnValue: data });
|
||||
return data;
|
||||
})
|
||||
.catch((ex) => {
|
||||
log({ elapsed: timer.elapsedTime, err: ex });
|
||||
// eslint-disable-next-line
|
||||
// TODO(GH-11645) Re-throw the error like we do
|
||||
// in the non-Promise case.
|
||||
});
|
||||
} else {
|
||||
log({ elapsed: timer.elapsedTime, returnValue: result });
|
||||
}
|
||||
return result;
|
||||
} catch (ex) {
|
||||
log({ elapsed: timer.elapsedTime, err: ex });
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking whether something is a Resource (Uri/undefined).
|
||||
* Using `instanceof Uri` doesn't always work as the object is not an instance of Uri (at least not in tests).
|
||||
|
|
|
@ -4,11 +4,10 @@
|
|||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
import { Disposable, Uri } from 'vscode';
|
||||
import { Disposable, Uri, LogLevel } from 'vscode';
|
||||
import { isCI } from '../common/constants';
|
||||
import { Arguments, ILogger, LogLevel, TraceDecoratorType, TraceOptions } from './types';
|
||||
import { Arguments, ILogger, TraceDecoratorType, TraceOptions } from './types';
|
||||
import { CallInfo, trace as traceDecorator } from '../common/utils/decorators';
|
||||
import { TraceInfo, tracing as _tracing } from '../common/utils/misc';
|
||||
import { argsToLogString, returnValueToLogString } from './util';
|
||||
import { LoggingLevelSettingType } from '../common/types';
|
||||
import { splitLines } from '../common/helpers';
|
||||
|
@ -16,6 +15,17 @@ import { getDisplayPath } from '../common/platform/fs-paths';
|
|||
let homeAsLowerCase = '';
|
||||
const DEFAULT_OPTS: TraceOptions = TraceOptions.Arguments | TraceOptions.ReturnValue;
|
||||
|
||||
// Information about a traced function/method call.
|
||||
export type TraceInfo =
|
||||
| {
|
||||
elapsed: number; // milliseconds
|
||||
// Either returnValue or err will be set.
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
returnValue?: any;
|
||||
err?: Error;
|
||||
}
|
||||
| undefined;
|
||||
|
||||
let loggers: ILogger[] = [];
|
||||
export function registerLogger(logger: ILogger): Disposable {
|
||||
loggers.push(logger);
|
||||
|
@ -26,24 +36,11 @@ export function registerLogger(logger: ILogger): Disposable {
|
|||
};
|
||||
}
|
||||
|
||||
const logLevelMap: Map<string | undefined, LogLevel> = new Map([
|
||||
['error', LogLevel.Error],
|
||||
['warn', LogLevel.Warn],
|
||||
['info', LogLevel.Info],
|
||||
['debug', LogLevel.Debug],
|
||||
['none', LogLevel.Off],
|
||||
['off', LogLevel.Off],
|
||||
[undefined, LogLevel.Error]
|
||||
]);
|
||||
|
||||
let globalLoggingLevel: LogLevel = LogLevel.Debug;
|
||||
let _enabledWidgetLogging: LoggingLevelSettingType = 'off';
|
||||
export function setLoggingLevel(
|
||||
level?: LoggingLevelSettingType | number,
|
||||
enabledWidgetLogging?: LoggingLevelSettingType
|
||||
): void {
|
||||
export function setLoggingLevel(level: LogLevel, enabledWidgetLogging?: LoggingLevelSettingType): void {
|
||||
_enabledWidgetLogging = enabledWidgetLogging || 'off';
|
||||
globalLoggingLevel = typeof level === 'number' ? level : logLevelMap.get(level) ?? LogLevel.Error;
|
||||
globalLoggingLevel = level;
|
||||
}
|
||||
|
||||
export function setHomeDirectory(homeDir: string) {
|
||||
|
@ -52,7 +49,7 @@ export function setHomeDirectory(homeDir: string) {
|
|||
|
||||
function formatErrors(...args: Arguments) {
|
||||
// Format the error message, if showing verbose then include all of the error stack & other details.
|
||||
const formatError = globalLoggingLevel <= LogLevel.Trace ? false : true;
|
||||
const formatError = globalLoggingLevel <= LogLevel.Debug ? false : true;
|
||||
if (!formatError) {
|
||||
return args;
|
||||
}
|
||||
|
@ -121,7 +118,7 @@ export function traceError(message: string, ...args: Arguments): void {
|
|||
}
|
||||
|
||||
export function traceWarning(message: string, ...args: Arguments): void {
|
||||
if (globalLoggingLevel <= LogLevel.Warn) {
|
||||
if (globalLoggingLevel <= LogLevel.Warning) {
|
||||
args = formatErrors(...args);
|
||||
loggers.forEach((l) => l.traceWarn(message, ...args));
|
||||
}
|
||||
|
@ -139,12 +136,12 @@ export function traceInfoWidgets(message: string, ...args: Arguments): void {
|
|||
}
|
||||
|
||||
export function traceVerbose(message: string, ...args: Arguments): void {
|
||||
if (globalLoggingLevel <= LogLevel.Trace) {
|
||||
if (globalLoggingLevel <= LogLevel.Debug) {
|
||||
loggers.forEach((l) => l.traceVerbose(message, ...args));
|
||||
}
|
||||
}
|
||||
export function traceVerboseWidgets(message: string, ...args: Arguments): void {
|
||||
if (_enabledWidgetLogging !== 'off' && globalLoggingLevel <= LogLevel.Trace) {
|
||||
if (_enabledWidgetLogging !== 'off' && globalLoggingLevel <= LogLevel.Debug) {
|
||||
loggers.forEach((l) => l.traceVerbose(message, ...args));
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +170,7 @@ export function traceInfoIfCI(arg1: any, ...args: Arguments): void {
|
|||
/** Logging Decorators go here */
|
||||
|
||||
export function traceDecoratorVerbose(message: string, opts: TraceOptions = DEFAULT_OPTS): TraceDecoratorType {
|
||||
return createTracingDecorator({ message, opts, level: LogLevel.Trace });
|
||||
return createTracingDecorator({ message, opts, level: LogLevel.Debug });
|
||||
}
|
||||
export function traceDecoratorError(message: string): TraceDecoratorType {
|
||||
return createTracingDecorator({ message, opts: DEFAULT_OPTS, level: LogLevel.Error });
|
||||
|
@ -182,7 +179,7 @@ export function traceDecoratorInfo(message: string): TraceDecoratorType {
|
|||
return createTracingDecorator({ message, opts: DEFAULT_OPTS, level: LogLevel.Info });
|
||||
}
|
||||
export function traceDecoratorWarn(message: string): TraceDecoratorType {
|
||||
return createTracingDecorator({ message, opts: DEFAULT_OPTS, level: LogLevel.Warn });
|
||||
return createTracingDecorator({ message, opts: DEFAULT_OPTS, level: LogLevel.Warning });
|
||||
}
|
||||
|
||||
type ParameterLogInformation =
|
||||
|
@ -249,11 +246,6 @@ export function createTracingDecorator(logInfo: LogInfo) {
|
|||
);
|
||||
}
|
||||
|
||||
// This is like a "context manager" that logs tracing info.
|
||||
export function tracing<T>(logInfo: LogInfo, run: () => T, call?: CallInfo): T {
|
||||
return _tracing((traced) => logResult(logInfo, traced, call), run, (logInfo.opts & TraceOptions.BeforeCall) > 0);
|
||||
}
|
||||
|
||||
export type LogInfo = {
|
||||
opts: TraceOptions;
|
||||
message: string;
|
||||
|
@ -324,7 +316,7 @@ function formatMessages(info: LogInfo, traced: TraceInfo, call?: CallInfo): stri
|
|||
messages[messages.length - 1] = `${messages[messages.length - 1]} (started execution)`;
|
||||
}
|
||||
if ((info.opts & TraceOptions.Arguments) === TraceOptions.Arguments) {
|
||||
if (info.level === LogLevel.Trace) {
|
||||
if (info.level === LogLevel.Debug) {
|
||||
// This is slower, hence do this only when user enables trace logging.
|
||||
messages.push(
|
||||
argsToLogString(
|
||||
|
@ -363,20 +355,18 @@ function logResult(info: LogInfo, traced: TraceInfo, call?: CallInfo) {
|
|||
}
|
||||
}
|
||||
|
||||
export function logTo(logLevel: LogLevel, message: string, ...args: Arguments): void {
|
||||
function logTo(logLevel: LogLevel, message: string, ...args: Arguments): void {
|
||||
switch (logLevel) {
|
||||
case LogLevel.Error:
|
||||
traceError(message, ...args);
|
||||
break;
|
||||
case LogLevel.Warn:
|
||||
case LogLevel.Warning:
|
||||
traceWarning(message, ...args);
|
||||
break;
|
||||
case LogLevel.Info:
|
||||
traceInfo(message, ...args);
|
||||
break;
|
||||
case LogLevel.Debug:
|
||||
traceVerbose(message, ...args);
|
||||
break;
|
||||
case LogLevel.Trace:
|
||||
traceVerbose(message, ...args);
|
||||
break;
|
||||
|
|
|
@ -4,16 +4,6 @@
|
|||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
export enum LogLevel {
|
||||
// Larger numbers are higher priority.
|
||||
Error = 40,
|
||||
Warn = 30,
|
||||
Info = 20,
|
||||
Debug = 10,
|
||||
Trace = 5,
|
||||
Off = 100
|
||||
}
|
||||
|
||||
export type Arguments = unknown[];
|
||||
|
||||
export interface ILogger {
|
||||
|
|
|
@ -218,7 +218,7 @@ export class ControllerPreferredService {
|
|||
|
||||
// If we found a preferred kernel, set the association on the NotebookController
|
||||
if (preferredSearchToken.token.isCancellationRequested && !preferredConnection) {
|
||||
traceInfo('Find preferred kernel cancelled');
|
||||
traceVerbose('Find preferred kernel cancelled');
|
||||
return {};
|
||||
}
|
||||
if (!preferredConnection) {
|
||||
|
|
|
@ -133,7 +133,7 @@ async function createSettings(): Promise<string> {
|
|||
const settingsFile = path.join(userDataDirectory, 'User', 'settings.json');
|
||||
const defaultSettings: Record<string, string | boolean | string[]> = {
|
||||
'python.insidersChannel': 'off',
|
||||
'jupyter.logging.level': 'verbose',
|
||||
'jupyter.logging.level': 'debug',
|
||||
'python.logging.level': 'debug',
|
||||
'files.autoSave': 'off',
|
||||
'python.experiments.enabled': true,
|
||||
|
|
|
@ -180,6 +180,7 @@ mockedVSCode.NotebookRendererScript = vscodeMocks.vscMockExtHostedTypes.Notebook
|
|||
mockedVSCode.NotebookEdit = vscodeMocks.vscMockExtHostedTypes.NotebookEdit;
|
||||
mockedVSCode.NotebookRange = vscodeMocks.vscMockExtHostedTypes.NotebookRange;
|
||||
mockedVSCode.QuickPickItemKind = vscodeMocks.vscMockExtHostedTypes.QuickPickItemKind;
|
||||
(mockedVSCode as any).LogLevel = vscodeMocks.vscMockExtHostedTypes.LogLevel;
|
||||
(mockedVSCode.NotebookCellData as any) = vscodeMocks.vscMockExtHostedTypes.NotebookCellData;
|
||||
(mockedVSCode as any).NotebookCellKind = vscodeMocks.vscMockExtHostedTypes.NotebookCellKind;
|
||||
(mockedVSCode as any).NotebookCellRunState = vscodeMocks.vscMockExtHostedTypes.NotebookCellRunState;
|
||||
|
|
|
@ -9,7 +9,7 @@ export function getDefaultSettings(): IJupyterExtraSettings {
|
|||
const result: Partial<IJupyterExtraSettings> = {
|
||||
experiments: { enabled: true, optInto: [], optOutFrom: [] },
|
||||
logging: {
|
||||
level: 'off'
|
||||
level: 5 // Not used in react side, should be removed later.
|
||||
},
|
||||
jupyterLaunchTimeout: 10,
|
||||
jupyterLaunchRetries: 3,
|
||||
|
|
Загрузка…
Ссылка в новой задаче