Skip to content

Commit 9f4a2c6

Browse files
Proper analytics and error reporting IDE-77 (#63)
* add TODOs for analytics and error reporting * Improve telemetry with handle uri flow * Identify connection type * Add telemetry for local ssh config * Add retry for telemetry inside proxy * Correct gitpod host option --------- Co-authored-by: mustard <[email protected]>
1 parent 118d18d commit 9f4a2c6

File tree

8 files changed

+168
-151
lines changed

8 files changed

+168
-151
lines changed

src/extension.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export async function activate(context: vscode.ExtensionContext) {
7272
hostService = new HostService(context, notificationService, logger);
7373
context.subscriptions.push(hostService);
7474

75-
const localSSHService = new LocalSSHService(context, hostService, logger);
75+
const localSSHService = new LocalSSHService(context, hostService, telemetryService, logger);
7676
context.subscriptions.push(localSSHService);
7777

7878
const sessionService = new SessionService(hostService, logger);
@@ -130,14 +130,18 @@ export async function activate(context: vscode.ExtensionContext) {
130130
instanceId: remoteConnectionInfo?.connectionInfo.instanceId || '',
131131
gitpodHost: remoteConnectionInfo?.connectionInfo.gitpodHost || '',
132132
debugWorkspace: remoteConnectionInfo ? String(!!remoteConnectionInfo.connectionInfo.debugWorkspace) : '',
133+
connType: remoteConnectionInfo?.connectionInfo.connType || '',
133134
success: String(success)
134135
};
135136
const gitpodHost = rawActivateProperties.gitpodHost || hostService?.gitpodHost || Configuration.getGitpodHost();
136137
logger?.info('Activation properties:', JSON.stringify(rawActivateProperties, undefined, 2));
137-
telemetryService?.sendTelemetryEvent(gitpodHost, 'vscode_desktop_activate', {
138+
const properties: Record<string, string> = {
138139
...rawActivateProperties,
140+
isRemoteSSH: String(vscode.env.remoteName === 'remote-ssh'),
139141
remoteUri: String(!!rawActivateProperties.remoteUri)
140-
});
142+
};
143+
delete properties.remoteName;
144+
telemetryService?.sendTelemetryEvent(gitpodHost, 'vscode_desktop_activate', properties);
141145
}
142146
}
143147

src/local-ssh/ipc/extensionServiceServer.ts

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { ExtensionServiceDefinition, ExtensionServiceImplementation, GetWorkspaceAuthInfoRequest, GetWorkspaceAuthInfoResponse, SendErrorReportRequest, SendLocalSSHUserFlowStatusRequest, SendLocalSSHUserFlowStatusRequest_Code, SendLocalSSHUserFlowStatusRequest_ConnType, SendLocalSSHUserFlowStatusRequest_Status } from '../../proto/typescript/ipc/v1/ipc';
6+
import { ExtensionServiceDefinition, ExtensionServiceImplementation, GetWorkspaceAuthInfoRequest, GetWorkspaceAuthInfoResponse, SendErrorReportRequest, SendLocalSSHUserFlowStatusRequest } from '../../proto/typescript/ipc/v1/ipc';
77
import { Disposable } from '../../common/dispose';
88
export { ExtensionServiceDefinition } from '../../proto/typescript/ipc/v1/ipc';
99
import { withServerApi } from '../../internalApi';
@@ -49,28 +49,28 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
4949

5050
}
5151

52-
private async getWorkspaceSSHKey(ownerToken:string,workspaceId: string, workspaceHost: string) {
53-
const workspaceUrl = `https://${workspaceId}.${workspaceHost}`;
54-
const metadata = new BrowserHeaders();
55-
metadata.append('x-gitpod-owner-token', ownerToken);
56-
const client = new ControlServiceClient(`${workspaceUrl}/_supervisor/v1`, { transport: NodeHttpTransport() });
57-
58-
const privateKey = await new Promise<string>((resolve, reject) => {
59-
client.createSSHKeyPair(new CreateSSHKeyPairRequest(), metadata, (err, resp) => {
60-
if (err) {
61-
return reject(err);
62-
}
63-
resolve(resp!.toObject().privateKey);
64-
});
65-
});
66-
67-
const parsedResult = ssh2.utils.parseKey(privateKey);
68-
if (parsedResult instanceof Error || !parsedResult) {
69-
throw new Error('Error while parsing workspace SSH private key');
70-
}
71-
72-
return (parsedResult as ParsedKey).getPrivatePEM();
73-
}
52+
private async getWorkspaceSSHKey(ownerToken: string, workspaceId: string, workspaceHost: string) {
53+
const workspaceUrl = `https://${workspaceId}.${workspaceHost}`;
54+
const metadata = new BrowserHeaders();
55+
metadata.append('x-gitpod-owner-token', ownerToken);
56+
const client = new ControlServiceClient(`${workspaceUrl}/_supervisor/v1`, { transport: NodeHttpTransport() });
57+
58+
const privateKey = await new Promise<string>((resolve, reject) => {
59+
client.createSSHKeyPair(new CreateSSHKeyPairRequest(), metadata, (err, resp) => {
60+
if (err) {
61+
return reject(err);
62+
}
63+
resolve(resp!.toObject().privateKey);
64+
});
65+
});
66+
67+
const parsedResult = ssh2.utils.parseKey(privateKey);
68+
if (parsedResult instanceof Error || !parsedResult) {
69+
throw new Error('Error while parsing workspace SSH private key');
70+
}
71+
72+
return (parsedResult as ParsedKey).getPrivatePEM();
73+
}
7474

7575
async getWorkspaceAuthInfo(request: GetWorkspaceAuthInfoRequest, _context: CallContext): Promise<GetWorkspaceAuthInfoResponse> {
7676
try {
@@ -90,7 +90,7 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
9090

9191
const phase = usePublicApi ? phaseMap[(workspace as Workspace).status?.instance?.status?.phase ?? WorkspaceInstanceStatus_Phase.UNSPECIFIED] : (workspace as WorkspaceInfo).latestInstance?.status.phase;
9292
if (phase !== 'running') {
93-
// TODO(lssh): extension child ipc broadcasts this error to all windows (window itself will figure it out if it needs to be shown)
93+
// TODO(lssh): notification?
9494
throw new ServerError(Status.UNAVAILABLE, 'workspace is not running, current phase: ' + phase);
9595
}
9696

@@ -102,7 +102,7 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
102102
const workspaceHost = url.host.substring(url.host.indexOf('.') + 1);
103103
const instanceId = (usePublicApi ? (workspace as Workspace).status?.instance?.instanceId : (workspace as WorkspaceInfo).latestInstance?.id) as string;
104104

105-
const sshkey = await this.getWorkspaceSSHKey(ownerToken,workspaceId,workspaceHost);
105+
const sshkey = await this.getWorkspaceSSHKey(ownerToken, workspaceId, workspaceHost);
106106

107107
return {
108108
gitpodHost,
@@ -121,22 +121,19 @@ class ExtensionServiceImpl implements ExtensionServiceImplementation {
121121

122122
// TODO remove from protocol, don't pass sensitive info back and forth, only once for auth, daemon should do telemetry directly
123123
async sendLocalSSHUserFlowStatus(request: SendLocalSSHUserFlowStatusRequest, _context: CallContext): Promise<{}> {
124+
if (!request.flowStatus || request.flowStatus === '') {
125+
return {};
126+
}
124127
const flow: UserFlowTelemetry = {
125-
flow: 'ssh',
126-
kind: 'local-ssh',
127-
connType: request.connType === SendLocalSSHUserFlowStatusRequest_ConnType.CONN_TYPE_SSH ? 'ssh' : 'tunnel',
128+
flow: 'local_ssh',
128129
workspaceId: request.workspaceId,
129130
instanceId: request.instanceId,
130131
daemonVersion: request.daemonVersion,
131132
userId: request.userId,
132133
gitpodHost: request.gitpodHost,
133-
// extensionVersion: request.extensionVersion,
134+
failureCode: request.flowFailureCode,
134135
};
135-
if (request.status !== SendLocalSSHUserFlowStatusRequest_Status.STATUS_SUCCESS && request.failureCode !== SendLocalSSHUserFlowStatusRequest_Code.CODE_UNSPECIFIED) {
136-
flow.reasonCode = SendLocalSSHUserFlowStatusRequest_Code[request.failureCode];
137-
}
138-
const status = request.status === SendLocalSSHUserFlowStatusRequest_Status.STATUS_SUCCESS ? 'local-ssh-success' : 'local-ssh-failure';
139-
this.telemetryService.sendUserFlowStatus(status, flow);
136+
this.telemetryService.sendUserFlowStatus(request.flowStatus, flow);
140137
return {};
141138
}
142139

0 commit comments

Comments
 (0)