Log exit signal for desktop TS Servers

For #125852
This commit is contained in:
Matt Bierner
2021-06-11 16:45:07 -07:00
parent 28f0fc47d0
commit 53350bc666
4 changed files with 22 additions and 14 deletions

View File

@@ -23,9 +23,14 @@ export enum ExecutionTarget {
Syntax
}
export interface TypeScriptServerExitEvent {
readonly code: number | null;
readonly signal: string | null;
}
export interface ITypeScriptServer {
readonly onEvent: vscode.Event<Proto.Event>;
readonly onExit: vscode.Event<any>;
readonly onExit: vscode.Event<TypeScriptServerExitEvent>;
readonly onError: vscode.Event<any>;
readonly tsServerLogFile: string | undefined;
@@ -66,7 +71,7 @@ export interface TsServerProcess {
write(serverRequest: Proto.Request): void;
onData(handler: (data: Proto.Response) => void): void;
onExit(handler: (code: number | null) => void): void;
onExit(handler: (code: number | null, signal: string | null) => void): void;
onError(handler: (error: Error) => void): void;
kill(): void;
@@ -93,8 +98,8 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe
this.dispatchMessage(msg);
});
this._process.onExit(code => {
this._onExit.fire(code);
this._process.onExit((code, signal) => {
this._onExit.fire({ code, signal });
this._callbacks.destroy('server exited');
});
@@ -107,7 +112,7 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe
private readonly _onEvent = this._register(new vscode.EventEmitter<Proto.Event>());
public readonly onEvent = this._onEvent.event;
private readonly _onExit = this._register(new vscode.EventEmitter<any>());
private readonly _onExit = this._register(new vscode.EventEmitter<TypeScriptServerExitEvent>());
public readonly onExit = this._onExit.event;
private readonly _onError = this._register(new vscode.EventEmitter<any>());
@@ -449,7 +454,7 @@ export class GetErrRoutingTsServer extends Disposable implements ITypeScriptServ
private readonly _onEvent = this._register(new vscode.EventEmitter<Proto.Event>());
public readonly onEvent = this._onEvent.event;
private readonly _onExit = this._register(new vscode.EventEmitter<any>());
private readonly _onExit = this._register(new vscode.EventEmitter<TypeScriptServerExitEvent>());
public readonly onExit = this._onExit.event;
private readonly _onError = this._register(new vscode.EventEmitter<any>());

View File

@@ -36,7 +36,7 @@ export class WorkerServerProcess implements TsServerProcess {
private _onDataHandlers = new Set<(data: Proto.Response) => void>();
private _onErrorHandlers = new Set<(err: Error) => void>();
private _onExitHandlers = new Set<(code: number | null) => void>();
private _onExitHandlers = new Set<(code: number | null, signal: string | null) => void>();
public constructor(
private readonly worker: Worker,
@@ -73,7 +73,7 @@ export class WorkerServerProcess implements TsServerProcess {
// Todo: not implemented
}
onExit(handler: (code: number | null) => void): void {
onExit(handler: (code: number | null, signal: string | null) => void): void {
this._onExitHandlers.add(handler);
// Todo: not implemented
}

View File

@@ -226,7 +226,7 @@ export class ChildServerProcess extends Disposable implements TsServerProcess {
this._reader.onData(handler);
}
onExit(handler: (code: number | null) => void): void {
onExit(handler: (code: number | null, signal: string | null) => void): void {
this._process.on('exit', handler);
}

View File

@@ -12,7 +12,7 @@ import { EventName } from './protocol.const';
import BufferSyncSupport from './tsServer/bufferSyncSupport';
import { OngoingRequestCancellerFactory } from './tsServer/cancellation';
import { ILogDirectoryProvider } from './tsServer/logDirectoryProvider';
import { ITypeScriptServer, TsServerProcessFactory } from './tsServer/server';
import { ITypeScriptServer, TsServerProcessFactory, TypeScriptServerExitEvent } from './tsServer/server';
import { TypeScriptServerError } from './tsServer/serverError';
import { TypeScriptServerSpawner } from './tsServer/spawner';
import { TypeScriptVersionManager } from './tsServer/versionManager';
@@ -432,27 +432,30 @@ export default class TypeScriptServiceClient extends Disposable implements IType
this.serviceExited(false);
});
handle.onExit((code: any) => {
handle.onExit((data: TypeScriptServerExitEvent) => {
if (this.token !== mytoken) {
// this is coming from an old process
return;
}
const { code, signal } = data;
if (code === null || typeof code === 'undefined') {
this.info('TSServer exited');
this.info(`TSServer exited. Signal: ${signal}`);
} else {
// In practice, the exit code is an integer with no ties to any identity,
// so it can be classified as SystemMetaData, rather than CallstackOrException.
this.error(`TSServer exited with code: ${code}`);
this.error(`TSServer exited with code: ${code}. Signal: ${signal}`);
/* __GDPR__
"tsserver.exitWithCode" : {
"code" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"signal" : { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" },
"${include}": [
"${TypeScriptCommonProperties}"
]
}
*/
this.logTelemetry('tsserver.exitWithCode', { code: code });
this.logTelemetry('tsserver.exitWithCode', { code, signal: signal ?? undefined });
}
if (handle.tsServerLogFile) {