Skip to content

Commit 5cba079

Browse files
authored
Add event counter telemetry (#34)
1 parent f42d58a commit 5cba079

File tree

1 file changed

+76
-44
lines changed

1 file changed

+76
-44
lines changed

src/heartbeat.ts

Lines changed: 76 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,16 @@ import TelemetryReporter from './telemetryReporter';
1414
export class HeartbeatManager extends Disposable {
1515

1616
static HEARTBEAT_INTERVAL = 30000;
17+
static EVENT_COUNTER_INTERVAL = 3600000;
1718

1819
private lastActivity = new Date().getTime();
1920
private lastActivityEvent: string = 'init';
2021
private isWorkspaceRunning = true;
2122
private heartBeatHandle: NodeJS.Timer | undefined;
2223

24+
private eventCounterMap = new Map<string, number>();
25+
private eventCounterHandle: NodeJS.Timer | undefined;
26+
2327
constructor(
2428
readonly gitpodHost: string,
2529
readonly workspaceId: string,
@@ -31,49 +35,58 @@ export class HeartbeatManager extends Disposable {
3135
private readonly telemetry: TelemetryReporter
3236
) {
3337
super();
34-
this._register(vscode.window.onDidChangeActiveTextEditor(this.updateLastActivity('onDidChangeActiveTextEditor'), this));
35-
this._register(vscode.window.onDidChangeVisibleTextEditors(this.updateLastActivity('onDidChangeVisibleTextEditors'), this));
36-
this._register(vscode.window.onDidChangeTextEditorSelection(this.updateLastActivity('onDidChangeTextEditorSelection'), this));
37-
this._register(vscode.window.onDidChangeTextEditorVisibleRanges(this.updateLastActivity('onDidChangeTextEditorVisibleRanges'), this));
38-
this._register(vscode.window.onDidChangeTextEditorOptions(this.updateLastActivity('onDidChangeTextEditorOptions'), this));
39-
this._register(vscode.window.onDidChangeTextEditorViewColumn(this.updateLastActivity('onDidChangeTextEditorViewColumn'), this));
40-
this._register(vscode.window.onDidChangeActiveTerminal(this.updateLastActivity('onDidChangeActiveTerminal'), this));
41-
this._register(vscode.window.onDidOpenTerminal(this.updateLastActivity('onDidOpenTerminal'), this));
42-
this._register(vscode.window.onDidCloseTerminal(this.updateLastActivity('onDidCloseTerminal'), this));
43-
this._register(vscode.window.onDidChangeTerminalState(this.updateLastActivity('onDidChangeTerminalState'), this));
44-
this._register(vscode.window.onDidChangeWindowState(this.updateLastActivity('onDidChangeWindowState'), this));
45-
this._register(vscode.window.onDidChangeActiveColorTheme(this.updateLastActivity('onDidChangeActiveColorTheme'), this));
46-
this._register(vscode.authentication.onDidChangeSessions(this.updateLastActivity('onDidChangeSessions'), this));
47-
this._register(vscode.debug.onDidChangeActiveDebugSession(this.updateLastActivity('onDidChangeActiveDebugSession'), this));
48-
this._register(vscode.debug.onDidStartDebugSession(this.updateLastActivity('onDidStartDebugSession'), this));
49-
this._register(vscode.debug.onDidReceiveDebugSessionCustomEvent(this.updateLastActivity('onDidReceiveDebugSessionCustomEvent'), this));
50-
this._register(vscode.debug.onDidTerminateDebugSession(this.updateLastActivity('onDidTerminateDebugSession'), this));
51-
this._register(vscode.debug.onDidChangeBreakpoints(this.updateLastActivity('onDidChangeBreakpoints'), this));
52-
this._register(vscode.extensions.onDidChange(this.updateLastActivity('onDidChange'), this));
53-
this._register(vscode.languages.onDidChangeDiagnostics(this.updateLastActivity('onDidChangeDiagnostics'), this));
54-
this._register(vscode.tasks.onDidStartTask(this.updateLastActivity('onDidStartTask'), this));
55-
this._register(vscode.tasks.onDidStartTaskProcess(this.updateLastActivity('onDidStartTaskProcess'), this));
56-
this._register(vscode.tasks.onDidEndTask(this.updateLastActivity('onDidEndTask'), this));
57-
this._register(vscode.tasks.onDidEndTaskProcess(this.updateLastActivity('onDidEndTaskProcess'), this));
58-
this._register(vscode.workspace.onDidChangeWorkspaceFolders(this.updateLastActivity('onDidChangeWorkspaceFolders'), this));
59-
this._register(vscode.workspace.onDidOpenTextDocument(this.updateLastActivity('onDidOpenTextDocument'), this));
60-
this._register(vscode.workspace.onDidCloseTextDocument(this.updateLastActivity('onDidCloseTextDocument'), this));
61-
this._register(vscode.workspace.onDidChangeTextDocument(this.updateLastActivity('onDidChangeTextDocument'), this));
62-
this._register(vscode.workspace.onDidSaveTextDocument(this.updateLastActivity('onDidSaveTextDocument'), this));
63-
this._register(vscode.workspace.onDidChangeNotebookDocument(this.updateLastActivity('onDidChangeNotebookDocument'), this));
64-
this._register(vscode.workspace.onDidSaveNotebookDocument(this.updateLastActivity('onDidSaveNotebookDocument'), this));
65-
this._register(vscode.workspace.onDidOpenNotebookDocument(this.updateLastActivity('onDidOpenNotebookDocument'), this));
66-
this._register(vscode.workspace.onDidCloseNotebookDocument(this.updateLastActivity('onDidCloseNotebookDocument'), this));
67-
this._register(vscode.workspace.onWillCreateFiles(this.updateLastActivity('onWillCreateFiles'), this));
68-
this._register(vscode.workspace.onDidCreateFiles(this.updateLastActivity('onDidCreateFiles'), this));
69-
this._register(vscode.workspace.onWillDeleteFiles(this.updateLastActivity('onWillDeleteFiles'), this));
70-
this._register(vscode.workspace.onDidDeleteFiles(this.updateLastActivity('onDidDeleteFiles'), this));
71-
this._register(vscode.workspace.onWillRenameFiles(this.updateLastActivity('onWillRenameFiles'), this));
72-
this._register(vscode.workspace.onDidRenameFiles(this.updateLastActivity('onDidRenameFiles'), this));
73-
this._register(vscode.workspace.onDidChangeConfiguration(this.updateLastActivity('onDidChangeConfiguration'), this));
38+
this._register(vscode.window.onDidChangeActiveTextEditor(e => this.updateLastActivity('onDidChangeActiveTextEditor', e?.document)));
39+
this._register(vscode.window.onDidChangeVisibleTextEditors(() => this.updateLastActivity('onDidChangeVisibleTextEditors')));
40+
this._register(vscode.window.onDidChangeTextEditorSelection(e => {
41+
// Ignore `output` scheme as text editors from output panel autoscroll
42+
if (e.textEditor.document.uri.scheme === 'output') { return; }
43+
this.updateLastActivity('onDidChangeTextEditorSelection', e.textEditor.document);
44+
}));
45+
this._register(vscode.window.onDidChangeTextEditorVisibleRanges(e => {
46+
// Ignore `output` scheme as text editors from output panel autoscroll
47+
if (e.textEditor.document.uri.scheme === 'output') { return; }
48+
this.updateLastActivity('onDidChangeTextEditorVisibleRanges', e.textEditor.document);
49+
}));
50+
this._register(vscode.window.onDidChangeTextEditorOptions(e => this.updateLastActivity('onDidChangeTextEditorOptions', e.textEditor.document)));
51+
this._register(vscode.window.onDidChangeTextEditorViewColumn(e => this.updateLastActivity('onDidChangeTextEditorViewColumn', e.textEditor.document)));
52+
this._register(vscode.window.onDidChangeActiveNotebookEditor(() => this.updateLastActivity('onDidChangeActiveNotebookEditor')));
53+
this._register(vscode.window.onDidChangeVisibleNotebookEditors(() => this.updateLastActivity('onDidChangeVisibleNotebookEditors')));
54+
this._register(vscode.window.onDidChangeNotebookEditorSelection(() => this.updateLastActivity('onDidChangeNotebookEditorSelection')));
55+
this._register(vscode.window.onDidChangeNotebookEditorVisibleRanges(() => this.updateLastActivity('onDidChangeNotebookEditorVisibleRanges')));
56+
this._register(vscode.window.onDidChangeActiveTerminal(() => this.updateLastActivity('onDidChangeActiveTerminal')));
57+
this._register(vscode.window.onDidOpenTerminal(() => this.updateLastActivity('onDidOpenTerminal')));
58+
this._register(vscode.window.onDidCloseTerminal(() => this.updateLastActivity('onDidCloseTerminal')));
59+
this._register(vscode.window.onDidChangeTerminalState(() => this.updateLastActivity('onDidChangeTerminalState')));
60+
this._register(vscode.window.onDidChangeWindowState(() => this.updateLastActivity('onDidChangeWindowState')));
61+
this._register(vscode.window.onDidChangeActiveColorTheme(() => this.updateLastActivity('onDidChangeActiveColorTheme')));
62+
this._register(vscode.authentication.onDidChangeSessions(() => this.updateLastActivity('onDidChangeSessions')));
63+
this._register(vscode.debug.onDidChangeActiveDebugSession(() => this.updateLastActivity('onDidChangeActiveDebugSession')));
64+
this._register(vscode.debug.onDidStartDebugSession(() => this.updateLastActivity('onDidStartDebugSession')));
65+
this._register(vscode.debug.onDidReceiveDebugSessionCustomEvent(() => this.updateLastActivity('onDidReceiveDebugSessionCustomEvent')));
66+
this._register(vscode.debug.onDidTerminateDebugSession(() => this.updateLastActivity('onDidTerminateDebugSession')));
67+
this._register(vscode.debug.onDidChangeBreakpoints(() => this.updateLastActivity('onDidChangeBreakpoints')));
68+
this._register(vscode.extensions.onDidChange(() => this.updateLastActivity('onDidChangeExtensions')));
69+
this._register(vscode.languages.onDidChangeDiagnostics(() => this.updateLastActivity('onDidChangeDiagnostics')));
70+
this._register(vscode.tasks.onDidStartTask(() => this.updateLastActivity('onDidStartTask')));
71+
this._register(vscode.tasks.onDidStartTaskProcess(() => this.updateLastActivity('onDidStartTaskProcess')));
72+
this._register(vscode.tasks.onDidEndTask(() => this.updateLastActivity('onDidEndTask')));
73+
this._register(vscode.tasks.onDidEndTaskProcess(() => this.updateLastActivity('onDidEndTaskProcess')));
74+
this._register(vscode.workspace.onDidChangeWorkspaceFolders(() => this.updateLastActivity('onDidChangeWorkspaceFolders')));
75+
this._register(vscode.workspace.onDidSaveTextDocument(e => this.updateLastActivity('onDidSaveTextDocument', e)));
76+
this._register(vscode.workspace.onDidChangeNotebookDocument(() => this.updateLastActivity('onDidChangeNotebookDocument')));
77+
this._register(vscode.workspace.onDidSaveNotebookDocument(() => this.updateLastActivity('onDidSaveNotebookDocument')));
78+
this._register(vscode.workspace.onDidOpenNotebookDocument(() => this.updateLastActivity('onDidOpenNotebookDocument')));
79+
this._register(vscode.workspace.onDidCloseNotebookDocument(() => this.updateLastActivity('onDidCloseNotebookDocument')));
80+
this._register(vscode.workspace.onWillCreateFiles(() => this.updateLastActivity('onWillCreateFiles')));
81+
this._register(vscode.workspace.onDidCreateFiles(() => this.updateLastActivity('onDidCreateFiles')));
82+
this._register(vscode.workspace.onWillDeleteFiles(() => this.updateLastActivity('onWillDeleteFiles')));
83+
this._register(vscode.workspace.onDidDeleteFiles(() => this.updateLastActivity('onDidDeleteFiles')));
84+
this._register(vscode.workspace.onWillRenameFiles(() => this.updateLastActivity('onWillRenameFiles')));
85+
this._register(vscode.workspace.onDidRenameFiles(() => this.updateLastActivity('onDidRenameFiles')));
86+
this._register(vscode.workspace.onDidChangeConfiguration(() => this.updateLastActivity('onDidChangeConfiguration')));
7487
this._register(vscode.languages.registerHoverProvider('*', {
7588
provideHover: () => {
76-
this.updateLastActivity('registerHoverProvider')();
89+
this.updateLastActivity('registerHoverProvider');
7790
return null;
7891
}
7992
}));
@@ -92,13 +105,18 @@ export class HeartbeatManager extends Disposable {
92105

93106
this.sendHeartBeat();
94107
}, HeartbeatManager.HEARTBEAT_INTERVAL);
108+
109+
this.eventCounterHandle = setInterval(() => this.sendEventData(), HeartbeatManager.EVENT_COUNTER_INTERVAL);
95110
}
96111

97-
private updateLastActivity(event: string) {
98-
return () => {
112+
private updateLastActivity(event: string, document?: vscode.TextDocument) {
99113
this.lastActivity = new Date().getTime();
100114
this.lastActivityEvent = event;
101-
};
115+
116+
const eventName = document ? `${event}:${document.uri.scheme}` : event;
117+
118+
let counter = this.eventCounterMap.get(eventName) || 0;
119+
this.eventCounterMap.set(eventName, ++counter);
102120
}
103121

104122
private async sendHeartBeat(wasClosed?: true) {
@@ -138,7 +156,21 @@ export class HeartbeatManager extends Disposable {
138156
}
139157
}
140158

159+
private sendEventData() {
160+
this.telemetry.sendRawTelemetryEvent('vscode_desktop_heartbeat_delta', { events: Object.fromEntries(this.eventCounterMap) });
161+
this.eventCounterMap.clear();
162+
}
163+
164+
private stopEventCounter() {
165+
if (this.eventCounterHandle) {
166+
clearInterval(this.eventCounterHandle);
167+
this.eventCounterHandle = undefined;
168+
}
169+
}
170+
141171
public override async dispose(): Promise<void> {
172+
this.stopEventCounter();
173+
this.sendEventData();
142174
this.stopHeartbeat();
143175
if (this.isWorkspaceRunning) {
144176
await this.sendHeartBeat(true);

0 commit comments

Comments
 (0)