From 449b50cc3bef34201e22065f3485addf1534c8be Mon Sep 17 00:00:00 2001 From: Sergey Petushkov Date: Mon, 20 Nov 2023 17:17:12 +0100 Subject: [PATCH] chore(telemetry): set timestamp on telemetry event on created; always pass session_id --- .../logging/src/analytics-helpers.spec.ts | 38 ++++++++++++++----- packages/logging/src/analytics-helpers.ts | 18 +++++++-- .../src/setup-logger-and-telemetry.spec.ts | 21 +++++++++- .../logging/src/setup-logger-and-telemetry.ts | 34 ++++++++++------- 4 files changed, 82 insertions(+), 29 deletions(-) diff --git a/packages/logging/src/analytics-helpers.spec.ts b/packages/logging/src/analytics-helpers.spec.ts index 9f83063e3..04454db14 100644 --- a/packages/logging/src/analytics-helpers.spec.ts +++ b/packages/logging/src/analytics-helpers.spec.ts @@ -8,6 +8,8 @@ import { ToggleableAnalytics, ThrottledAnalytics } from './analytics-helpers'; const wait = promisify(setTimeout); +const timestamp = new Date(); + describe('analytics helpers', function () { let events: any[]; let target: MongoshAnalytics; @@ -32,11 +34,16 @@ describe('analytics helpers', function () { const toggleable = new ToggleableAnalytics(target); expect(events).to.have.lengthOf(0); - toggleable.identify({ userId: 'me', traits: { platform: '1234' } }); + toggleable.identify({ + userId: 'me', + traits: { platform: '1234', session_id: 'abc' }, + timestamp, + }); toggleable.track({ userId: 'me', event: 'something', - properties: { mongosh_version: '1.2.3' }, + properties: { mongosh_version: '1.2.3', session_id: 'abc' }, + timestamp, }); expect(events).to.have.lengthOf(0); @@ -46,7 +53,8 @@ describe('analytics helpers', function () { toggleable.track({ userId: 'me', event: 'something2', - properties: { mongosh_version: '1.2.3' }, + properties: { mongosh_version: '1.2.3', session_id: 'abc' }, + timestamp, }); expect(events).to.have.lengthOf(3); @@ -54,7 +62,8 @@ describe('analytics helpers', function () { toggleable.track({ userId: 'me', event: 'something3', - properties: { mongosh_version: '1.2.3' }, + properties: { mongosh_version: '1.2.3', session_id: 'abc' }, + timestamp, }); expect(events).to.have.lengthOf(3); @@ -63,13 +72,21 @@ describe('analytics helpers', function () { toggleable.enable(); expect(events).to.deep.equal([ - ['identify', { userId: 'me', traits: { platform: '1234' } }], + [ + 'identify', + { + userId: 'me', + traits: { platform: '1234', session_id: 'abc' }, + timestamp, + }, + ], [ 'track', { userId: 'me', event: 'something', - properties: { mongosh_version: '1.2.3' }, + properties: { mongosh_version: '1.2.3', session_id: 'abc' }, + timestamp, }, ], [ @@ -77,7 +94,8 @@ describe('analytics helpers', function () { { userId: 'me', event: 'something2', - properties: { mongosh_version: '1.2.3' }, + properties: { mongosh_version: '1.2.3', session_id: 'abc' }, + timestamp, }, ], ]); @@ -102,16 +120,16 @@ describe('analytics helpers', function () { describe('ThrottledAnalytics', function () { const metadataPath = os.tmpdir(); const userId = 'u-' + Date.now(); - const iEvt = { userId, traits: { platform: 'what' } }; + const iEvt = { userId, traits: { platform: 'what', session_id: 'abc' } }; const tEvt = { userId, event: 'hi', - properties: { mongosh_version: '1.2.3' }, + properties: { mongosh_version: '1.2.3', session_id: 'abc' }, }; const t2Evt = { userId, event: 'bye', - properties: { mongosh_version: '1.2.3' }, + properties: { mongosh_version: '1.2.3', session_id: 'abc' }, }; afterEach(async function () { diff --git a/packages/logging/src/analytics-helpers.ts b/packages/logging/src/analytics-helpers.ts index 13102ab82..546f3b85c 100644 --- a/packages/logging/src/analytics-helpers.ts +++ b/packages/logging/src/analytics-helpers.ts @@ -12,15 +12,18 @@ export type MongoshAnalyticsIdentity = }; type AnalyticsIdentifyMessage = MongoshAnalyticsIdentity & { - traits: { platform: string }; + traits: { platform: string; session_id: string }; + timestamp?: Date; }; type AnalyticsTrackMessage = MongoshAnalyticsIdentity & { event: string; properties: { mongosh_version: string; + session_id: string; [key: string]: any; }; + timestamp?: Date; }; /** @@ -90,6 +93,12 @@ type AnalyticsEventsQueueItem = | ['identify', Parameters] | ['track', Parameters]; +function addTimestamp( + message: T +): T & { timestamp: Date } { + return { ...message, timestamp: message.timestamp ?? new Date() }; +} + /** * An implementation of MongoshAnalytics that forwards to another implementation * and can be enabled/paused/disabled. @@ -112,12 +121,12 @@ export class ToggleableAnalytics implements MongoshAnalytics { identify(...args: Parameters): void { this._validateArgs(args); - this._queue.push(['identify', args]); + this._queue.push(['identify', [addTimestamp(args[0])]]); } track(...args: Parameters): void { this._validateArgs(args); - this._queue.push(['track', args]); + this._queue.push(['track', [addTimestamp(args[0])]]); } enable() { @@ -262,6 +271,7 @@ export class ThrottledAnalytics implements MongoshAnalytics { } identify(message: AnalyticsIdentifyMessage): void { + message = addTimestamp(message); if (this.currentUserId) { throw new Error('Identify can only be called once per user session'); } @@ -280,7 +290,7 @@ export class ThrottledAnalytics implements MongoshAnalytics { } track(message: AnalyticsTrackMessage): void { - this.trackQueue.push(message); + this.trackQueue.push(addTimestamp(message)); } // Tries to restore persisted throttle state and returns `true` if telemetry can diff --git a/packages/logging/src/setup-logger-and-telemetry.spec.ts b/packages/logging/src/setup-logger-and-telemetry.spec.ts index 168ea6113..51c1c0e3e 100644 --- a/packages/logging/src/setup-logger-and-telemetry.spec.ts +++ b/packages/logging/src/setup-logger-and-telemetry.spec.ts @@ -351,6 +351,7 @@ describe('setupLoggerAndTelemetry', function () { traits: { platform: process.platform, arch: process.arch, + session_id: '5fb3c20ee1507e894e5340f3', }, }, ], @@ -361,6 +362,7 @@ describe('setupLoggerAndTelemetry', function () { traits: { platform: process.platform, arch: process.arch, + session_id: '5fb3c20ee1507e894e5340f3', }, }, ], @@ -385,6 +387,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Error', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', name: 'MongoshInvalidInputError', code: 'CLIREPL-1005', scope: 'CLIREPL', @@ -399,6 +402,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Error', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', name: 'MongoshInvalidInputError', code: 'CLIREPL-1005', scope: 'CLIREPL', @@ -411,7 +415,10 @@ describe('setupLoggerAndTelemetry', function () { { anonymousId: '53defe995fa47e6c13102d9d', event: 'Use', - properties: { mongosh_version: '1.0.0' }, + properties: { + mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', + }, }, ], [ @@ -421,6 +428,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Show', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', method: 'dbs', }, }, @@ -431,6 +439,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Script Loaded CLI', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', nested: true, shell: true, }, @@ -443,6 +452,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Script Loaded', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', nested: false, }, anonymousId: '53defe995fa47e6c13102d9d', @@ -454,6 +464,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Mongoshrc Loaded', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', }, anonymousId: '53defe995fa47e6c13102d9d', }, @@ -464,6 +475,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Mongorc Warning', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', }, anonymousId: '53defe995fa47e6c13102d9d', }, @@ -474,6 +486,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Script Evaluated', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', shell: true, }, anonymousId: '53defe995fa47e6c13102d9d', @@ -486,6 +499,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Snippet Install', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', }, }, ], @@ -575,6 +589,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Deprecated Method', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', class: 'Database', method: 'cloneDatabase', }, @@ -587,6 +602,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Deprecated Method', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', class: 'Database', method: 'copyDatabase', }, @@ -599,6 +615,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'Deprecated Method', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', class: 'Database', method: 'mangleDatabase', }, @@ -611,6 +628,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'API Call', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', class: 'Database', method: 'cloneDatabase', count: 3, @@ -624,6 +642,7 @@ describe('setupLoggerAndTelemetry', function () { event: 'API Call', properties: { mongosh_version: '1.0.0', + session_id: '5fb3c20ee1507e894e5340f3', class: 'Database', method: 'copyDatabase', count: 1, diff --git a/packages/logging/src/setup-logger-and-telemetry.ts b/packages/logging/src/setup-logger-and-telemetry.ts index 7fd76f748..40968a248 100644 --- a/packages/logging/src/setup-logger-and-telemetry.ts +++ b/packages/logging/src/setup-logger-and-telemetry.ts @@ -72,10 +72,17 @@ export function setupLoggerAndTelemetry( userTraits: any, mongosh_version: string ): void { - const { logId } = log; + const { logId: session_id } = log; let userId: string; let telemetryAnonymousId: string; + userTraits = { ...userTraits, session_id }; + + const trackProperties = { + mongosh_version, + session_id, + }; + const getTelemetryUserIdentity = () => { if (telemetryAnonymousId) { return { @@ -115,7 +122,7 @@ export function setupLoggerAndTelemetry( // eslint-disable-next-line @typescript-eslint/no-unused-vars const { uri: _uri, ...argsWithoutUri } = args; const params = { - session_id: logId, + session_id, userId, telemetryAnonymousId, connectionUri, @@ -133,8 +140,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'New Connection', properties: { - mongosh_version, - session_id: logId, + ...trackProperties, ...argsWithoutUri, }, }); @@ -212,7 +218,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Error', properties: { - mongosh_version, + ...trackProperties, name: mongoshError.name, code: mongoshError.code, scope: mongoshError.scope, @@ -258,7 +264,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Use', properties: { - mongosh_version, + ...trackProperties, }, }); }); @@ -276,7 +282,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Show', properties: { - mongosh_version, + ...trackProperties, method: args.method, }, }); @@ -325,7 +331,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: hasStartedMongoshRepl ? 'Script Loaded' : 'Script Loaded CLI', properties: { - mongosh_version, + ...trackProperties, nested: args.nested, ...(hasStartedMongoshRepl ? {} : { shell: usesShellOption }), }, @@ -344,7 +350,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Script Evaluated', properties: { - mongosh_version, + ...trackProperties, shell: usesShellOption, }, }); @@ -362,7 +368,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Mongoshrc Loaded', properties: { - mongosh_version, + ...trackProperties, }, }); }); @@ -379,7 +385,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Mongorc Warning', properties: { - mongosh_version, + ...trackProperties, }, }); }); @@ -564,7 +570,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Snippet Install', properties: { - mongosh_version, + ...trackProperties, }, }); } @@ -616,7 +622,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'Deprecated Method', properties: { - mongosh_version, + ...trackProperties, ...entry, }, }); @@ -626,7 +632,7 @@ export function setupLoggerAndTelemetry( ...getTelemetryUserIdentity(), event: 'API Call', properties: { - mongosh_version, + ...trackProperties, ...entry, count, },