Skip to content

Commit

Permalink
Show more informative log and link to logfile on Console crash (#3309)
Browse files Browse the repository at this point in the history
* use openTextDocument for logfiles

* only show if error in line

* button should say show logfile

* remove unused logfile

* Update src/vs/workbench/services/runtimeStartup/common/runtimeStartup.ts

Co-authored-by: Wasim Lorgat <mwlorgat@gmail.com>
Signed-off-by: Isabel Zimmerman <54685329+isabelizimm@users.noreply.github.com>

* open output channels rather than logfiles

* format fix

* unify button language

* create consoleExit grammar as backup

* Update extensions/jupyter-adapter/src/LanguageRuntimeAdapter.ts

Co-authored-by: Davis Vaughan <davis@rstudio.com>
Signed-off-by: Isabel Zimmerman <54685329+isabelizimm@users.noreply.github.com>

* call it a KernelLogFile

* sync all .d.ts files

* add to impl

* actually, don't need it in implApi

* format fix

---------

Signed-off-by: Isabel Zimmerman <54685329+isabelizimm@users.noreply.github.com>
  • Loading branch information
isabelizimm authored Jun 5, 2024
1 parent dc21268 commit 3afe3c3
Show file tree
Hide file tree
Showing 9 changed files with 73 additions and 4 deletions.
4 changes: 4 additions & 0 deletions extensions/jupyter-adapter/src/JupyterKernel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ export class JupyterKernel extends EventEmitter implements vscode.Disposable {
return this.establishSocketListeners();
}

public getKernelLogFilePath() {
return this._session!.logFile;
}

private handleIopubMsg(args: any[]) {
// Deserialize the message
const msg = deserializeJupyterMessage(args, this._session!.key, this._channel);
Expand Down
4 changes: 4 additions & 0 deletions extensions/jupyter-adapter/src/JupyterSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ export class JupyterSession implements vscode.Disposable {
return this.state.sessionId;
}

get logFile(): string {
return this.state.logFile;
}

get portsInUse(): Array<number> {
return [
this.spec.control_port,
Expand Down
4 changes: 4 additions & 0 deletions extensions/jupyter-adapter/src/LanguageRuntimeAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1029,4 +1029,8 @@ export class LanguageRuntimeSessionAdapter
// Tell the kernel to shut down
await this._kernel.dispose();
}

public getKernelLogFile(): string {
return this._kernel.getKernelLogFilePath()
}
}
5 changes: 5 additions & 0 deletions extensions/jupyter-adapter/src/jupyter-adapter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ export interface JupyterLanguageRuntimeSession extends positron.LanguageRuntimeS
* response.
*/
callMethod(method: string, ...args: Array<any>): Promise<any>;

/**
* Return logfile path
*/
getKernelLogFile(): string;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -530,3 +530,9 @@ export namespace CreateEnv {
);
}
}

// --- Start Positron ---
export namespace Console {
export const consoleExit = l10n.t('Console exited unexpectedly. View logs for more info.');
}
// --- End Positron ---
5 changes: 5 additions & 0 deletions extensions/positron-python/src/client/jupyter-adapter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ export interface JupyterLanguageRuntimeSession extends positron.LanguageRuntimeS
* response.
*/
callMethod(method: string, ...args: Array<any>): Promise<any>;

/**
* Return logfile path
*/
getKernelLogFile(): string;
}

/**
Expand Down
28 changes: 27 additions & 1 deletion extensions/positron-python/src/client/positron/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

// eslint-disable-next-line import/no-unresolved
import * as positron from 'positron';
import * as fs from 'fs';
import * as vscode from 'vscode';
import PQueue from 'p-queue';
import { ProductNames } from '../common/installer/productNames';
Expand All @@ -32,6 +33,8 @@ import { JediLanguageServerAnalysisOptions } from '../activation/jedi/analysisOp
import { ILanguageServerOutputChannel } from '../activation/types';
import { IWorkspaceService } from '../common/application/types';
import { IInterpreterService } from '../interpreter/contracts';
import { showErrorMessage } from '../common/vscodeApis/windowApis';
import { Console } from '../common/utils/localize';

/**
* A Positron language runtime that wraps a Jupyter kernel and a Language Server
Expand Down Expand Up @@ -435,8 +438,11 @@ export class PythonRuntimeSession implements positron.LanguageRuntimeSession, vs
kernel.onDidReceiveRuntimeMessage((message) => {
this._messageEmitter.fire(message);
});
kernel.onDidEndSession((exit) => {
kernel.onDidEndSession(async (exit) => {
this._exitEmitter.fire(exit);
if (exit.exit_code !== 0) {
await this.showExitMessageWithLogs(kernel);
}
});
return kernel;
}
Expand Down Expand Up @@ -490,6 +496,26 @@ export class PythonRuntimeSession implements positron.LanguageRuntimeSession, vs
}
}
}

private async showExitMessageWithLogs(kernel: JupyterLanguageRuntimeSession): Promise<void> {
const logFilePath = kernel.getKernelLogFile();

if (fs.existsSync(logFilePath)) {
const lines = fs.readFileSync(logFilePath, 'utf8').split('\n');
// last line of logs before generated log tail
const lastLine = lines.length - 3;
const logFileContent = lines.slice(lastLine - 1, lastLine).join('\n');

// see if obvious error, otherwise use generic text to logs
const regex = /^(\w*Error)\b/m;
const errortext = regex.test(logFileContent) ? logFileContent : Console.consoleExit;

const res = await showErrorMessage(errortext, vscode.l10n.t('Open logs'));
if (res) {
kernel.showOutput();
}
}
}
}

export function createJupyterKernelExtra(): undefined {
Expand Down
5 changes: 5 additions & 0 deletions extensions/positron-r/src/jupyter-adapter.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ export interface JupyterLanguageRuntimeSession extends positron.LanguageRuntimeS
* response.
*/
callMethod(method: string, ...args: Array<any>): Promise<any>;

/**
* Return logfile path
*/
getKernelLogFile(): string;
}

/**
Expand Down
16 changes: 13 additions & 3 deletions src/vs/workbench/services/runtimeStartup/common/runtimeStartup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ import { ISettableObservable, observableValue } from 'vs/base/common/observableI
import { ExtensionsRegistry } from 'vs/workbench/services/extensions/common/extensionsRegistry';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { ILifecycleService, ShutdownReason, StartupKind } from 'vs/workbench/services/lifecycle/common/lifecycle';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { URI } from 'vs/base/common/uri';
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IPositronNewProjectService } from 'vs/workbench/services/positronNewProject/common/positronNewProject';
Expand Down Expand Up @@ -84,6 +85,7 @@ export class RuntimeStartupService extends Disposable implements IRuntimeStartup

constructor(
@IConfigurationService private readonly _configurationService: IConfigurationService,
@ICommandService commandService: ICommandService,
@IExtensionService private readonly _extensionService: IExtensionService,
@ILanguageService private readonly _languageService: ILanguageService,
@ILanguageRuntimeService private readonly _languageRuntimeService: ILanguageRuntimeService,
Expand Down Expand Up @@ -258,7 +260,6 @@ export class RuntimeStartupService extends Disposable implements IRuntimeStartup
}
}
});

// Register a shutdown event handler to clear the workspace sessions to
// prepare for a clean start of Positron next time.
this._lifecycleService.onBeforeShutdown((e) => {
Expand Down Expand Up @@ -825,7 +826,16 @@ export class RuntimeStartupService extends Disposable implements IRuntimeStartup
action,
exit.exit_code
);
this._notificationService.warn(msg);

this._notificationService.prompt(Severity.Warning, msg, [
{
label: nls.localize('openOutputLogs', 'Open logs'),
run: () => {
session.showOutput()
}
},
]);

}
}

Expand Down

0 comments on commit 3afe3c3

Please sign in to comment.