Skip to content

Commit 47b6254

Browse files
committed
Set userId for telemetry events
1 parent 4c07ba2 commit 47b6254

File tree

2 files changed

+54
-32
lines changed

2 files changed

+54
-32
lines changed

extensions/gitpod/src/authentication.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,9 @@ export default class GitpodAuthenticationProvider extends Disposable implements
5656
// Contains the current state of the sessions we have available.
5757
this._sessionsPromise = this.readSessions();
5858

59+
// Update telemetry userId
60+
this._sessionsPromise.then(sessions => this._telemetry.setUserId(sessions.length ? sessions[0].id : undefined));
61+
5962
this._register(vscode.authentication.registerAuthenticationProvider('gitpod', 'Gitpod', this, { supportsMultipleAccounts: false }));
6063
this._register(this.context.secrets.onDidChange(() => this.checkForUpdates()));
6164
}
@@ -106,6 +109,9 @@ export default class GitpodAuthenticationProvider extends Disposable implements
106109
if (added.length || removed.length) {
107110
this._sessionChangeEmitter.fire({ added, removed, changed: [] });
108111
}
112+
113+
// Update telemetry userId
114+
this._telemetry.setUserId(storedSessions.length ? storedSessions[0].id : undefined);
109115
}
110116

111117
private async readSessions(): Promise<vscode.AuthenticationSession[]> {
@@ -179,6 +185,9 @@ export default class GitpodAuthenticationProvider extends Disposable implements
179185
this._sessionsPromise = Promise.resolve(sessions);
180186
await this._keychain.setToken(JSON.stringify(sessions));
181187
this._logger.info(`Stored ${sessions.length} sessions!`);
188+
189+
// Update telemetry userId
190+
this._telemetry.setUserId(sessions.length ? sessions[0].id : undefined);
182191
}
183192

184193
public async createSession(scopes: string[]): Promise<vscode.AuthenticationSession> {

extensions/gitpod/src/telemetryReporter.ts

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,57 @@ import SegmentAnalytics from 'analytics-node';
33
import * as os from 'os';
44
import * as vscode from 'vscode';
55

6-
const analyticsClientFactory = async (key: string): Promise<BaseTelemetryClient> => {
7-
let segmentAnalyticsClient = new SegmentAnalytics(key);
8-
9-
// Sets the analytics client into a standardized form
10-
const telemetryClient: BaseTelemetryClient = {
11-
logEvent: (eventName: string, data?: AppenderData) => {
12-
try {
13-
segmentAnalyticsClient.track({
14-
anonymousId: vscode.env.machineId,
15-
event: eventName,
16-
properties: data?.properties
17-
});
18-
} catch (e: any) {
19-
throw new Error('Failed to log event to app analytics!\n' + e.message);
20-
}
21-
},
22-
logException: (_exception: Error, _data?: AppenderData) => {
23-
throw new Error('Failed to log exception to app analytics!\n');
24-
},
25-
flush: async () => {
26-
try {
27-
// Types are oudated, flush does return a promise
28-
await segmentAnalyticsClient.flush();
29-
} catch (e: any) {
30-
throw new Error('Failed to flush app analytics!\n' + e.message);
31-
}
32-
}
33-
};
34-
return telemetryClient;
35-
};
36-
376
export default class TelemetryReporter extends BaseTelemetryReporter {
7+
8+
private _userId: string | undefined;
9+
3810
constructor(extensionId: string, extensionVersion: string, key: string) {
39-
const appender = new BaseTelemetryAppender(key, (key) => analyticsClientFactory(key));
11+
let resolveTelemetryClient: (value: Promise<BaseTelemetryClient>) => void;
12+
const telemetryClientPromise = new Promise<BaseTelemetryClient>((resolve, _reject) => resolveTelemetryClient = resolve);
13+
14+
const appender = new BaseTelemetryAppender(key, () => telemetryClientPromise);
4015
super(extensionId, extensionVersion, appender, {
4116
release: os.release(),
4217
platform: os.platform(),
4318
architecture: os.arch(),
4419
});
20+
21+
resolveTelemetryClient!(this.analyticsClientFactory(key));
22+
}
23+
24+
setUserId(id: string | undefined) {
25+
this._userId = id;
26+
}
27+
28+
async analyticsClientFactory(key: string): Promise<BaseTelemetryClient> {
29+
let segmentAnalyticsClient = new SegmentAnalytics(key);
30+
31+
// Sets the analytics client into a standardized form
32+
const telemetryClient: BaseTelemetryClient = {
33+
logEvent: (eventName: string, data?: AppenderData) => {
34+
try {
35+
segmentAnalyticsClient.track({
36+
userId: this._userId,
37+
anonymousId: vscode.env.machineId,
38+
event: eventName,
39+
properties: data?.properties
40+
});
41+
} catch (e: any) {
42+
throw new Error('Failed to log event to app analytics!\n' + e.message);
43+
}
44+
},
45+
logException: (_exception: Error, _data?: AppenderData) => {
46+
throw new Error('Failed to log exception to app analytics!\n');
47+
},
48+
flush: async () => {
49+
try {
50+
// Types are oudated, flush does return a promise
51+
await segmentAnalyticsClient.flush();
52+
} catch (e: any) {
53+
throw new Error('Failed to flush app analytics!\n' + e.message);
54+
}
55+
}
56+
};
57+
return telemetryClient;
4558
}
4659
}

0 commit comments

Comments
 (0)