Skip to content

Commit 9a44f11

Browse files
committed
chore: enrich and improve telemetry events
1 parent 1d06af7 commit 9a44f11

File tree

8 files changed

+228
-63
lines changed

8 files changed

+228
-63
lines changed

src/extension.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ import statusBar from "./plugins/status-bar.ts";
1010
import { PluginManager } from "./plugins.ts";
1111
import { createContainerStatusTracker } from "./utils/container-status.ts";
1212
import { createLocalStackStatusTracker } from "./utils/localstack-status.ts";
13-
import { getOrCreateExtensionSessionId } from "./utils/manage.ts";
13+
import {
14+
getOrCreateExtensionSessionId,
15+
getOrCreateMachineId,
16+
} from "./utils/manage.ts";
1417
import { createSetupStatusTracker } from "./utils/setup-status.ts";
1518
import { createTelemetry } from "./utils/telemetry.ts";
1619
import { createTimeTracker } from "./utils/time-tracker.ts";
@@ -78,7 +81,8 @@ export async function activate(context: ExtensionContext) {
7881
const startTelemetry = Date.now();
7982
outputChannel.trace(`[telemetry]: Starting...`);
8083
const sessionId = await getOrCreateExtensionSessionId(context);
81-
const telemetry = createTelemetry(outputChannel, sessionId);
84+
const machineId = await getOrCreateMachineId(context);
85+
const telemetry = createTelemetry(outputChannel, sessionId, machineId);
8286
const endTelemetry = Date.now();
8387
outputChannel.trace(
8488
`[telemetry]: Completed in ${ms(endTelemetry - startTelemetry, {

src/plugins/setup.ts

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
checkIsAuthenticated,
66
requestAuthentication,
77
saveAuthToken,
8+
readAuthToken,
89
} from "../utils/authenticate.ts";
910
import { configureAwsProfiles } from "../utils/configure-aws.ts";
1011
import { runInstallProcess } from "../utils/install.ts";
@@ -38,26 +39,6 @@ export default createPlugin(
3839
payload: {
3940
namespace: "onboarding",
4041
origin: origin_trigger,
41-
expected_steps: [
42-
{
43-
name: "emulator_installed",
44-
is_first_step: true,
45-
is_last_step: false,
46-
position: 1,
47-
},
48-
{
49-
name: "auth_token_configured",
50-
is_first_step: false,
51-
is_last_step: false,
52-
position: 2,
53-
},
54-
{
55-
name: "aws_profile_configured",
56-
is_first_step: false,
57-
is_last_step: true,
58-
position: 3,
59-
},
60-
],
6142
},
6243
});
6344

@@ -84,7 +65,7 @@ export default createPlugin(
8465
payload: {
8566
namespace: "onboarding",
8667
origin: origin_trigger,
87-
position: 1,
68+
step_order: 1,
8869
started_at: installationStartedAt,
8970
ended_at: new Date().toISOString(),
9071
status: "CANCELLED",
@@ -113,8 +94,38 @@ export default createPlugin(
11394
name: "setup_ended",
11495
payload: {
11596
namespace: "onboarding",
116-
steps: [1, 2, 3],
97+
steps: [
98+
{
99+
name: "emulator_installed",
100+
is_first_step: true,
101+
is_last_step: false,
102+
step_order: 1,
103+
status: "COMPLETED",
104+
},
105+
{
106+
name: "auth_token_configured",
107+
is_first_step: false,
108+
is_last_step: false,
109+
step_order: 2,
110+
status: "CANCELLED",
111+
},
112+
{
113+
name: "license_setup_ended",
114+
is_first_step: false,
115+
is_last_step: false,
116+
step_order: 3,
117+
status: "SKIPPED",
118+
},
119+
{
120+
name: "aws_profile_configured",
121+
is_first_step: false,
122+
is_last_step: true,
123+
step_order: 4,
124+
status: "SKIPPED",
125+
},
126+
],
117127
status: "CANCELLED",
128+
auth_token: await readAuthToken(),
118129
},
119130
});
120131
return;
@@ -128,7 +139,7 @@ export default createPlugin(
128139
payload: {
129140
namespace: "onboarding",
130141
origin: origin_trigger,
131-
position: 2,
142+
step_order: 2,
132143
started_at: authStartedAuthAt,
133144
ended_at: new Date().toISOString(),
134145
status: "SKIPPED",
@@ -153,7 +164,7 @@ export default createPlugin(
153164
payload: {
154165
namespace: "onboarding",
155166
origin: origin_trigger,
156-
position: 2,
167+
step_order: 2,
157168
auth_token: authToken,
158169
started_at: authStartedAuthAt,
159170
ended_at: new Date().toISOString(),
@@ -174,7 +185,7 @@ export default createPlugin(
174185
payload: {
175186
namespace: "onboarding",
176187
origin: origin_trigger,
177-
position: 2,
188+
step_order: 2,
178189
auth_token: authToken,
179190
started_at: authStartedAuthAt,
180191
ended_at: new Date().toISOString(),
@@ -193,6 +204,7 @@ export default createPlugin(
193204
// then there will be no license info to be reported by `localstack license info`.
194205
// Also, an expired license could be cached.
195206
// Activating the license pre-emptively to know its state during the setup process.
207+
const licenseCheckStartedAt = new Date().toISOString();
196208
const licenseIsValid = await minDelay(
197209
activateLicense(outputChannel).then(() =>
198210
checkIsLicenseValid(outputChannel),
@@ -209,15 +221,28 @@ export default createPlugin(
209221
await activateLicenseUntilValid(
210222
outputChannel,
211223
cancellationToken,
224+
telemetry,
225+
origin_trigger,
226+
licenseCheckStartedAt,
212227
);
213228
}
214229

215230
if (cancellationToken.isCancellationRequested) {
231+
telemetry.track({
232+
name: "license_setup_ended",
233+
payload: {
234+
namespace: "onboarding",
235+
step_order: 3,
236+
origin: origin_trigger,
237+
auth_token: await readAuthToken(),
238+
started_at: licenseCheckStartedAt,
239+
ended_at: new Date().toISOString(),
240+
status: "COMPLETED",
241+
},
242+
});
216243
return;
217244
}
218245

219-
//TODO add telemetry
220-
221246
/////////////////////////////////////////////////////////////////////
222247
progress.report({
223248
message: "Configuring AWS profiles...",
@@ -284,8 +309,38 @@ export default createPlugin(
284309
name: "setup_ended",
285310
payload: {
286311
namespace: "onboarding",
287-
steps: [1, 2, 3],
312+
steps: [
313+
{
314+
name: "emulator_installed",
315+
is_first_step: true,
316+
is_last_step: false,
317+
step_order: 1,
318+
status: "COMPLETED",
319+
},
320+
{
321+
name: "auth_token_configured",
322+
is_first_step: false,
323+
is_last_step: false,
324+
step_order: 2,
325+
status: "COMPLETED",
326+
},
327+
{
328+
name: "license_setup_ended",
329+
is_first_step: false,
330+
is_last_step: false,
331+
step_order: 3,
332+
status: "COMPLETED",
333+
},
334+
{
335+
name: "aws_profile_configured",
336+
is_first_step: false,
337+
is_last_step: true,
338+
step_order: 4,
339+
status: "COMPLETED",
340+
},
341+
],
288342
status: "COMPLETED",
343+
auth_token: await readAuthToken(),
289344
},
290345
});
291346
},

src/utils/authenticate.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ export async function checkIsAuthenticated() {
143143
return false;
144144
}
145145
return true;
146-
} catch (error) {
146+
} catch {
147147
return false;
148148
}
149149
}
@@ -155,3 +155,21 @@ function isAuthTokenPresent(authObject: unknown) {
155155
AUTH_TOKEN_KEY in authObject
156156
);
157157
}
158+
159+
// Reads the auth token from the auth.json file for logging in the user
160+
export async function readAuthToken(): Promise<string> {
161+
try {
162+
const authJson = await fs.readFile(LOCALSTACK_AUTH_FILENAME, "utf-8");
163+
const authObject = JSON.parse(authJson) as unknown;
164+
if (!isAuthTokenPresent(authObject)) {
165+
return "";
166+
}
167+
const authToken = authObject[AUTH_TOKEN_KEY];
168+
if (typeof authToken !== "string") {
169+
return "";
170+
}
171+
return authToken;
172+
} catch {
173+
return "";
174+
}
175+
}

src/utils/configure-aws.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as path from "node:path";
55

66
import { window } from "vscode";
77

8+
import { readAuthToken } from "./authenticate.ts";
89
import { parseIni, serializeIni, updateIniSection } from "./ini-parser.ts";
910
import type { IniFile, IniSection } from "./ini-parser.ts";
1011
import type { Telemetry } from "./telemetry.ts";
@@ -310,6 +311,8 @@ export async function configureAwsProfiles(options: {
310311
const credentialsNeedsOverride =
311312
checkIfCredentialsNeedsOverride(credentialsSection);
312313

314+
const authToken = await readAuthToken();
315+
313316
// means sections exist, but we need to check what's inside
314317
if (credentialsSection && configSection) {
315318
if (!configNeedsOverride && !credentialsNeedsOverride) {
@@ -324,10 +327,11 @@ export async function configureAwsProfiles(options: {
324327
payload: {
325328
namespace: "onboarding",
326329
origin: trigger,
327-
position: 3,
330+
step_order: 4,
328331
started_at: startedAt,
329332
ended_at: new Date().toISOString(),
330333
status: "COMPLETED",
334+
auth_token: authToken,
331335
},
332336
});
333337
return;
@@ -357,10 +361,11 @@ export async function configureAwsProfiles(options: {
357361
payload: {
358362
namespace: "onboarding",
359363
origin: trigger,
360-
position: 3,
364+
step_order: 4,
361365
started_at: startedAt,
362366
ended_at: new Date().toISOString(),
363367
status: "SKIPPED",
368+
auth_token: authToken,
364369
},
365370
});
366371
return;
@@ -390,10 +395,11 @@ export async function configureAwsProfiles(options: {
390395
payload: {
391396
namespace: "onboarding",
392397
origin: trigger,
393-
position: 3,
398+
step_order: 4,
394399
started_at: startedAt,
395400
ended_at: new Date().toISOString(),
396401
status: "COMPLETED",
402+
auth_token: authToken,
397403
},
398404
});
399405
} else if (configNeedsOverride) {
@@ -412,10 +418,11 @@ export async function configureAwsProfiles(options: {
412418
payload: {
413419
namespace: "onboarding",
414420
origin: trigger,
415-
position: 3,
421+
step_order: 4,
416422
started_at: startedAt,
417423
ended_at: new Date().toISOString(),
418424
status: "COMPLETED",
425+
auth_token: authToken,
419426
},
420427
});
421428
} else if (credentialsNeedsOverride) {
@@ -434,10 +441,11 @@ export async function configureAwsProfiles(options: {
434441
payload: {
435442
namespace: "onboarding",
436443
origin: trigger,
437-
position: 3,
444+
step_order: 4,
438445
started_at: startedAt,
439446
ended_at: new Date().toISOString(),
440447
status: "COMPLETED",
448+
auth_token: authToken,
441449
},
442450
});
443451
}

src/utils/install.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export async function runInstallProcess(
6464
payload: {
6565
namespace: "onboarding",
6666
origin: origin_trigger,
67-
position: 1,
67+
step_order: 1,
6868
started_at: startedAt,
6969
ended_at: new Date().toISOString(),
7070
status: "SKIPPED",
@@ -148,7 +148,7 @@ export async function runInstallProcess(
148148
payload: {
149149
namespace: "onboarding",
150150
origin: origin_trigger,
151-
position: 1,
151+
step_order: 1,
152152
started_at: startedAt,
153153
ended_at: new Date().toISOString(),
154154
status: "FAILED",
@@ -177,7 +177,7 @@ export async function runInstallProcess(
177177
payload: {
178178
namespace: "onboarding",
179179
origin: origin_trigger,
180-
position: 1,
180+
step_order: 1,
181181
started_at: startedAt,
182182
ended_at: new Date().toISOString(),
183183
status: "FAILED",
@@ -194,7 +194,7 @@ export async function runInstallProcess(
194194
payload: {
195195
namespace: "onboarding",
196196
origin: origin_trigger,
197-
position: 1,
197+
step_order: 1,
198198
started_at: startedAt,
199199
ended_at: new Date().toISOString(),
200200
status: "COMPLETED",

src/utils/license.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import type { CancellationToken, LogOutputChannel } from "vscode";
22

3+
import { readAuthToken } from "./authenticate.ts";
34
import { execLocalStack } from "./cli.ts";
5+
import type { Telemetry } from "./telemetry.ts";
46

57
const LICENSE_VALIDITY_MARKER = "license validity: valid";
68

@@ -30,13 +32,28 @@ export async function activateLicense(outputChannel: LogOutputChannel) {
3032
export async function activateLicenseUntilValid(
3133
outputChannel: LogOutputChannel,
3234
cancellationToken: CancellationToken,
35+
telemetry: Telemetry,
36+
origin: "manual_trigger" | "extension_startup",
37+
startedAt: string,
3338
): Promise<void> {
3439
while (true) {
3540
if (cancellationToken.isCancellationRequested) {
3641
break;
3742
}
3843
const licenseIsValid = await checkIsLicenseValid(outputChannel);
3944
if (licenseIsValid) {
45+
telemetry.track({
46+
name: "license_setup_ended",
47+
payload: {
48+
namespace: "onboarding",
49+
step_order: 3,
50+
origin: origin,
51+
auth_token: await readAuthToken(),
52+
started_at: startedAt,
53+
ended_at: new Date().toISOString(),
54+
status: "COMPLETED",
55+
},
56+
});
4057
break;
4158
}
4259
await activateLicense(outputChannel);

0 commit comments

Comments
 (0)