Skip to content

Commit 96906c0

Browse files
chore: Anonymous usage tracking for Recorder, Generator, Validator (#771)
1 parent 317d44a commit 96906c0

File tree

9 files changed

+113
-2
lines changed

9 files changed

+113
-2
lines changed

src/components/Profile/GrafanaCloudSignIn/index.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Button, Flex } from '@radix-ui/themes'
22
import { useCallback, useEffect, useRef, useState } from 'react'
33

44
import { UserProfiles } from '@/schemas/profile'
5+
import { UsageEventName } from '@/services/usageTracking/types'
56
import { SignInProcessState, SignInResult, Stack } from '@/types/auth'
67
import { exhaustive } from '@/utils/typescript'
78

@@ -89,6 +90,9 @@ export function GrafanaCloudSignIn({
8990
switch (result.type) {
9091
case 'authenticated':
9192
onSignInRef.current(result.profiles)
93+
window.studio.app.trackEvent({
94+
event: UsageEventName.UserLoggedIn,
95+
})
9296
break
9397

9498
case 'timed-out':

src/handlers/app/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { ipcMain, app } from 'electron'
22

33
import { showWindow } from '@/main/window'
4+
import { trackEvent } from '@/services/usageTracking'
5+
import { UsageEvent } from '@/services/usageTracking/types'
46
import { browserWindowFromEvent } from '@/utils/electron'
57

68
import { AppHandler } from './types'
@@ -35,4 +37,8 @@ export function initialize() {
3537
showWindow(browserWindow)
3638
}
3739
})
40+
41+
ipcMain.on(AppHandler.TRACK_EVENT, (_, event: UsageEvent) => {
42+
trackEvent(event)
43+
})
3844
}

src/handlers/app/preload.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { ipcRenderer } from 'electron'
22

3+
import { UsageEvent } from '@/services/usageTracking/types'
4+
35
import { createListener } from '../utils'
46

57
import { AppHandler } from './types'
@@ -22,6 +24,10 @@ export function changeRoute(route: string) {
2224
return ipcRenderer.send(AppHandler.CHANGE_ROUTE, route)
2325
}
2426

27+
export function trackEvent(event: UsageEvent) {
28+
return ipcRenderer.send(AppHandler.TRACK_EVENT, event)
29+
}
30+
2531
export function onDeepLink(callback: (url: string) => void) {
2632
return createListener(AppHandler.DEEP_LINK, callback)
2733
}

src/handlers/app/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export enum AppHandler {
33
CHANGE_ROUTE = 'app:change-route',
44
SPLASHSCREEN_CLOSE = 'app:splashscreen-close',
55
DEEP_LINK = 'app:deep-link',
6+
TRACK_EVENT = 'app:track-event',
67
}

src/handlers/cloud/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import { basename, extname, isAbsolute, join } from 'path'
44

55
import { SCRIPTS_PATH } from '@/constants/workspace'
66
import { getTempScriptName } from '@/main/script'
7+
import { trackEvent } from '@/services/usageTracking'
8+
import { UsageEventName } from '@/services/usageTracking/types'
79
import { browserWindowFromEvent } from '@/utils/electron'
810
import { logError } from '@/utils/errors'
911

@@ -66,6 +68,9 @@ export function initialize() {
6668
const result = await stateMachine.run()
6769

6870
if (result.type === 'started') {
71+
trackEvent({
72+
event: UsageEventName.ScriptRunInCloud,
73+
})
6974
await shell.openExternal(result.testRunUrl)
7075
}
7176

src/handlers/generator/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import invariant from 'tiny-invariant'
66
import { INVALID_FILENAME_CHARS } from '@/constants/files'
77
import { GENERATORS_PATH } from '@/constants/workspace'
88
import { GeneratorFileDataSchema } from '@/schemas/generator'
9+
import { trackEvent } from '@/services/usageTracking'
10+
import { UsageEventName } from '@/services/usageTracking/types'
911
import { GeneratorFileData } from '@/types/generator'
1012
import { createFileWithUniqueName } from '@/utils/fileSystem'
1113
import { createNewGeneratorFile } from '@/utils/generator'
@@ -23,6 +25,10 @@ export function initialize() {
2325
prefix: 'Generator',
2426
})
2527

28+
trackEvent({
29+
event: UsageEventName.GeneratorCreated,
30+
})
31+
2632
return fileName
2733
})
2834

@@ -36,6 +42,10 @@ export function initialize() {
3642
path.join(GENERATORS_PATH, fileName),
3743
JSON.stringify(generator, null, 2)
3844
)
45+
46+
trackEvent({
47+
event: UsageEventName.GeneratorUpdated,
48+
})
3949
}
4050
)
4151

src/handlers/har/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { readFile, copyFile } from 'fs/promises'
33
import path from 'path'
44

55
import { RECORDINGS_PATH } from '@/constants/workspace'
6+
import { trackEvent } from '@/services/usageTracking'
7+
import { UsageEventName } from '@/services/usageTracking/types'
68
import { HarWithOptionalResponse } from '@/types/har'
79
import { browserWindowFromEvent } from '@/utils/electron'
810
import { createFileWithUniqueName } from '@/utils/fileSystem'
@@ -22,6 +24,10 @@ export function initialize() {
2224
prefix,
2325
})
2426

27+
trackEvent({
28+
event: UsageEventName.RecordingCreated,
29+
})
30+
2531
return fileName
2632
}
2733
)
@@ -63,6 +69,10 @@ export function initialize() {
6369
path.join(RECORDINGS_PATH, path.basename(filePath))
6470
)
6571

72+
trackEvent({
73+
event: UsageEventName.RecordingImported,
74+
})
75+
6676
return path.basename(filePath)
6777
})
6878
}

src/handlers/script/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
runScript,
1111
type K6Process,
1212
} from '@/main/script'
13+
import { trackEvent } from '@/services/usageTracking'
14+
import { UsageEventName } from '@/services/usageTracking/types'
1315
import { browserWindowFromEvent, sendToast } from '@/utils/electron'
1416

1517
import { ScriptHandler } from './types'
@@ -60,6 +62,10 @@ export function initialize() {
6062
proxyPort: k6StudioState.appSettings.proxy.port,
6163
usageReport: k6StudioState.appSettings.telemetry.usageReport,
6264
})
65+
66+
trackEvent({
67+
event: UsageEventName.ScriptValidated,
68+
})
6369
}
6470
)
6571

@@ -89,6 +95,10 @@ export function initialize() {
8995
usageReport: k6StudioState.appSettings.telemetry.usageReport,
9096
})
9197

98+
trackEvent({
99+
event: UsageEventName.ScriptValidated,
100+
})
101+
92102
await unlink(TEMP_GENERATOR_SCRIPT_PATH)
93103
}
94104
)
@@ -101,6 +111,10 @@ export function initialize() {
101111
try {
102112
const filePath = path.join(SCRIPTS_PATH, fileName)
103113
await writeFile(filePath, script)
114+
115+
trackEvent({
116+
event: UsageEventName.ScriptExported,
117+
})
104118
sendToast(browserWindow.webContents, {
105119
title: 'Script exported successfully',
106120
status: 'success',

src/services/usageTracking/types.ts

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,20 @@ import { Arch, Platform } from '@/types/electron'
33
export enum UsageEventName {
44
// General
55
AppInstalled = 'app_installed',
6+
UserLoggedIn = 'user_logged_in',
7+
8+
// Recorder
9+
RecordingCreated = 'recording_created',
10+
RecordingImported = 'recording_imported',
11+
12+
// Generator
13+
GeneratorCreated = 'generator_created',
14+
GeneratorUpdated = 'generator_updated',
15+
16+
// Script
17+
ScriptExported = 'script_exported',
18+
ScriptValidated = 'script_validated',
19+
ScriptRunInCloud = 'script_run_in_cloud',
620
}
721

822
export interface UsageEventMetadata {
@@ -13,10 +27,51 @@ export interface UsageEventMetadata {
1327
arch: Arch
1428
}
1529

16-
export interface AppInstalledEvent {
30+
interface AppInstalledEvent {
1731
event: UsageEventName.AppInstalled
1832
}
1933

20-
export type UsageEvent = AppInstalledEvent
34+
interface UserLoggedInEvent {
35+
event: UsageEventName.UserLoggedIn
36+
}
37+
38+
interface RecordingCreatedEvent {
39+
event: UsageEventName.RecordingCreated
40+
}
41+
42+
interface RecordingImportedEvent {
43+
event: UsageEventName.RecordingImported
44+
}
45+
46+
interface GeneratorCreatedEvent {
47+
event: UsageEventName.GeneratorCreated
48+
}
49+
50+
interface GeneratorUpdatedEvent {
51+
event: UsageEventName.GeneratorUpdated
52+
}
53+
54+
interface ScriptExportedEvent {
55+
event: UsageEventName.ScriptExported
56+
}
57+
58+
interface ScriptValidatedEvent {
59+
event: UsageEventName.ScriptValidated
60+
}
61+
62+
interface ScriptRunInCloudEvent {
63+
event: UsageEventName.ScriptRunInCloud
64+
}
65+
66+
export type UsageEvent =
67+
| AppInstalledEvent
68+
| UserLoggedInEvent
69+
| RecordingCreatedEvent
70+
| RecordingImportedEvent
71+
| GeneratorCreatedEvent
72+
| GeneratorUpdatedEvent
73+
| ScriptExportedEvent
74+
| ScriptValidatedEvent
75+
| ScriptRunInCloudEvent
2176

2277
export type UsageEventWithMetadata = UsageEvent & UsageEventMetadata

0 commit comments

Comments
 (0)