Skip to content

Commit 5ae88f6

Browse files
authored
chore: add import/export telemetry COMPASS-5199 (#2547)
Also adds infrastructure that enables us to easily observe these events in the end-to-end test suite.
1 parent c8f106f commit 5ae88f6

File tree

7 files changed

+82
-9
lines changed

7 files changed

+82
-9
lines changed

packages/compass-e2e-tests/helpers/commands/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ exports.addCommands = function (app) {
3232
add('setValidation', './set-validation');
3333
add('waitForAnimations', './wait-for-animations');
3434
add('setOrClearValue', './set-or-clear-value');
35+
add('listenForTelemetryEvents', './listen-for-telemetry-events');
3536
};
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
module.exports = function (app) {
2+
return async function (telemetry) {
3+
const existingEventCount = telemetry.events().length;
4+
const { client } = app;
5+
6+
function lookupNewEvent(eventName) {
7+
const newEvents = telemetry.events().slice(existingEventCount);
8+
return newEvents.find((entry) => entry.event === eventName);
9+
}
10+
11+
return async (eventName) => {
12+
await client.waitUntil(
13+
async () => {
14+
await client.execute(() => {
15+
const { ipcRenderer } = require('electron');
16+
ipcRenderer.send('compass:usage:flush');
17+
});
18+
return !!lookupNewEvent(eventName);
19+
},
20+
{ timeout: 20000 }
21+
);
22+
23+
const ev = lookupNewEvent(eventName);
24+
const properties = { ...ev.properties };
25+
delete properties.compass_version;
26+
return properties;
27+
};
28+
};
29+
};

packages/compass-e2e-tests/tests/smoke.test.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const { promises: fs } = require('fs');
33
const _ = require('lodash');
44
const chai = require('chai');
55
const chaiAsPromised = require('chai-as-promised');
6+
const { startTelemetryServer } = require('../helpers/telemetry');
67

78
const { expect } = chai;
89

@@ -25,16 +26,19 @@ describe('Smoke tests', function () {
2526
/** @type {import('../helpers/compass').ExtendedApplication} */
2627
let compass;
2728
let client;
29+
let telemetry;
2830

2931
before(async function () {
32+
telemetry = await startTelemetryServer();
3033
compass = await beforeTests();
3134
client = compass.client;
3235

3336
await client.connectWithConnectionString('mongodb://localhost:27018/test');
3437
});
3538

36-
after(function () {
37-
return afterTests(compass);
39+
after(async function () {
40+
await afterTests(compass);
41+
await telemetry.stop();
3842
});
3943

4044
afterEach(async function () {
@@ -504,6 +508,7 @@ describe('Smoke tests', function () {
504508
});
505509

506510
it('supports collection to CSV with a query filter', async function () {
511+
const telemetryEntry = await client.listenForTelemetryEvents(telemetry);
507512
await client.runFindOperation('Documents', '{ i: 5 }');
508513
await client.clickVisible(Selectors.ExportCollectionButton);
509514
const exportModal = await client.$(Selectors.ExportModal);
@@ -581,6 +586,15 @@ describe('Smoke tests', function () {
581586
const fields = lines[1].split(',');
582587
// first field is an id, so always different
583588
expect(fields[1]).to.equal('5');
589+
590+
const exportCompletedEvent = await telemetryEntry('Export Completed');
591+
expect(exportCompletedEvent).to.deep.equal({
592+
all_docs: false,
593+
file_type: 'csv',
594+
all_fields: true,
595+
number_of_docs: 1,
596+
success: true,
597+
});
584598
});
585599

586600
it('supports full collection to CSV');

packages/compass-import-export/src/modules/export.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ import createLoggerAndTelemetry from '@mongodb-js/compass-logging';
1616
import { createCSVFormatter, createJSONFormatter } from '../utils/formatters';
1717
import { loadFields, getSelectableFields } from './load-fields';
1818

19-
const { log, mongoLogId, debug } = createLoggerAndTelemetry('COMPASS-IMPORT-EXPORT-UI');
19+
const { log, mongoLogId, debug, track } = createLoggerAndTelemetry(
20+
'COMPASS-IMPORT-EXPORT-UI'
21+
);
2022

2123
const PREFIX = 'import-export/export';
2224

@@ -367,6 +369,7 @@ const fetchDocumentCount = async(dataService, ns, query) => {
367369
*/
368370
export const openExport = (count) => {
369371
return async(dispatch, getState) => {
372+
track('Export Opened');
370373
const {
371374
ns,
372375
exportData,
@@ -490,6 +493,15 @@ export const startExport = () => {
490493
debug('executing pipeline');
491494
dispatch(onStarted(source, dest, numDocsToExport));
492495
stream.pipeline(source, progress, formatter, dest, function(err) {
496+
track('Export Completed', {
497+
all_docs: exportData.isFullCollection,
498+
file_type: exportData.fileType,
499+
all_fields: Object.values(exportData.fields).every(
500+
(checked) => checked === 1
501+
),
502+
number_of_docs: numDocsToExport,
503+
success: !err,
504+
});
493505
if (err) {
494506
log.error(mongoLogId(1001000085), 'Export', 'Export failed', {
495507
ns,

packages/compass-import-export/src/modules/import.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ import { transformProjectedTypesStream } from '../utils/import-apply-types-and-p
4646

4747
import createLoggerAndTelemetry from '@mongodb-js/compass-logging';
4848

49-
const { log, mongoLogId, debug } = createLoggerAndTelemetry('COMPASS-IMPORT-EXPORT-UI');
49+
const { log, mongoLogId, debug, track } = createLoggerAndTelemetry(
50+
'COMPASS-IMPORT-EXPORT-UI'
51+
);
5052

5153
/**
5254
* ## Action names
@@ -278,6 +280,13 @@ export const startImport = () => {
278280
dest,
279281
function onStreamEnd(err) {
280282
console.timeEnd('import');
283+
track('Import Completed', {
284+
file_type: fileType,
285+
all_fields: exclude.length === 0,
286+
stop_on_error_selected: stopOnErrors,
287+
number_of_docs: dest.docsWritten,
288+
success: !err,
289+
});
281290

282291
/**
283292
* Refresh data (docs, aggregations) regardless of whether we have a
@@ -623,9 +632,12 @@ export const setIgnoreBlanks = ignoreBlanks => ({
623632
* Open the import modal.
624633
* @api public
625634
*/
626-
export const openImport = () => ({
627-
type: OPEN
628-
});
635+
export const openImport = () => {
636+
track('Import Opened');
637+
return {
638+
type: OPEN,
639+
};
640+
};
629641

630642
/**
631643
* Close the import modal.

packages/compass-logging/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ export function createLoggerAndTelemetry(component: string): {
2121
log: ReturnType<MongoLogWriter['bindComponent']>;
2222
mongoLogId: typeof mongoLogId;
2323
debug: ReturnType<typeof createDebug>;
24-
track: (event: string, properties: Record<string, any>) => void;
24+
track: (event: string, properties?: Record<string, any>) => void;
2525
} {
2626
// This application may not be running in an Node.js/Electron context.
2727
const ipc: HadronIpcRenderer | null = isElectronRenderer
@@ -43,7 +43,7 @@ export function createLoggerAndTelemetry(component: string): {
4343
} as Writable;
4444
const writer = new MongoLogWriter('', null, target);
4545

46-
const track = (event: string, properties: Record<string, any>): void => {
46+
const track = (event: string, properties: Record<string, any> = {}): void => {
4747
emit(ipc, 'compass:track', { event, properties });
4848
};
4949

packages/compass/src/main/telemetry.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ class CompassTelemetry {
104104
this.state = 'disabled';
105105
});
106106

107+
// only used in tests
108+
ipcMain.respondTo('compass:usage:flush', () => {
109+
this.analytics?.flush();
110+
});
111+
107112
if (telemetryCapableEnvironment) {
108113
this.analytics = new Analytics(SEGMENT_API_KEY, { host: SEGMENT_HOST });
109114

0 commit comments

Comments
 (0)