@mongosh/logging 3.6.0 → 3.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,6 +7,10 @@ import type { MongoshBus } from '@mongosh/types';
7
7
  import type { Writable } from 'stream';
8
8
  import type { MongoshLoggingAndTelemetry } from '.';
9
9
  import { setupLoggingAndTelemetry } from '.';
10
+ import type { LoggingAndTelemetry } from './logging-and-telemetry';
11
+ import { getDeviceId } from './logging-and-telemetry';
12
+ import sinon from 'sinon';
13
+ import type { MongoshLoggingAndTelemetryArguments } from './types';
10
14
 
11
15
  describe('MongoshLoggingAndTelemetry', function () {
12
16
  let logOutput: any[];
@@ -32,19 +36,25 @@ describe('MongoshLoggingAndTelemetry', function () {
32
36
 
33
37
  let loggingAndTelemetry: MongoshLoggingAndTelemetry;
34
38
 
39
+ const testLoggingArguments: Omit<MongoshLoggingAndTelemetryArguments, 'bus'> =
40
+ {
41
+ analytics,
42
+ deviceId: 'test-device',
43
+ userTraits: {
44
+ platform: process.platform,
45
+ arch: process.arch,
46
+ },
47
+ mongoshVersion: '1.0.0',
48
+ };
49
+
35
50
  beforeEach(function () {
36
51
  logOutput = [];
37
52
  analyticsOutput = [];
38
53
  bus = new EventEmitter();
39
54
 
40
55
  loggingAndTelemetry = setupLoggingAndTelemetry({
56
+ ...testLoggingArguments,
41
57
  bus,
42
- analytics,
43
- userTraits: {
44
- platform: process.platform,
45
- arch: process.arch,
46
- },
47
- mongoshVersion: '1.0.0',
48
58
  });
49
59
 
50
60
  logger = new MongoLogWriter(logId, `/tmp/${logId}_log`, {
@@ -76,9 +86,11 @@ describe('MongoshLoggingAndTelemetry', function () {
76
86
  expect(() => loggingAndTelemetry.attachLogger(logger)).does.not.throw();
77
87
  });
78
88
 
79
- it('tracks new local connection events', function () {
89
+ it('tracks new local connection events', async function () {
80
90
  loggingAndTelemetry.attachLogger(logger);
81
91
 
92
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
93
+
82
94
  expect(logOutput).to.have.lengthOf(0);
83
95
  expect(analyticsOutput).to.be.empty;
84
96
 
@@ -105,6 +117,7 @@ describe('MongoshLoggingAndTelemetry', function () {
105
117
  'identify',
106
118
  {
107
119
  anonymousId: userId,
120
+ deviceId: 'test-device',
108
121
  traits: {
109
122
  arch: process.arch,
110
123
  platform: process.platform,
@@ -116,6 +129,7 @@ describe('MongoshLoggingAndTelemetry', function () {
116
129
  'track',
117
130
  {
118
131
  anonymousId: userId,
132
+ deviceId: 'test-device',
119
133
  event: 'New Connection',
120
134
  properties: {
121
135
  mongosh_version: '1.0.0',
@@ -130,8 +144,9 @@ describe('MongoshLoggingAndTelemetry', function () {
130
144
  ]);
131
145
  });
132
146
 
133
- it('tracks new atlas connection events', function () {
147
+ it('tracks new atlas connection events', async function () {
134
148
  loggingAndTelemetry.attachLogger(logger);
149
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
135
150
 
136
151
  expect(logOutput).to.have.lengthOf(0);
137
152
  expect(analyticsOutput).to.be.empty;
@@ -163,6 +178,7 @@ describe('MongoshLoggingAndTelemetry', function () {
163
178
  'identify',
164
179
  {
165
180
  anonymousId: userId,
181
+ deviceId: 'test-device',
166
182
  traits: {
167
183
  arch: process.arch,
168
184
  platform: process.platform,
@@ -174,6 +190,7 @@ describe('MongoshLoggingAndTelemetry', function () {
174
190
  'track',
175
191
  {
176
192
  anonymousId: userId,
193
+ deviceId: 'test-device',
177
194
  event: 'New Connection',
178
195
  properties: {
179
196
  mongosh_version: '1.0.0',
@@ -188,8 +205,126 @@ describe('MongoshLoggingAndTelemetry', function () {
188
205
  ]);
189
206
  });
190
207
 
191
- it('detaching logger leads to no logging but persists analytics', function () {
208
+ describe('device ID', function () {
209
+ let bus: EventEmitter;
210
+ beforeEach(function () {
211
+ bus = new EventEmitter();
212
+ });
213
+
214
+ afterEach(function () {
215
+ sinon.restore();
216
+ });
217
+
218
+ it('uses device ID "unknown" and logs error if it fails to resolve it', async function () {
219
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
220
+ sinon
221
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
222
+ .stub(require('native-machine-id'), 'getMachineId')
223
+ .rejects(new Error('Test'));
224
+ const loggingAndTelemetry = setupLoggingAndTelemetry({
225
+ ...testLoggingArguments,
226
+ bus,
227
+ deviceId: undefined,
228
+ });
229
+ loggingAndTelemetry.attachLogger(logger);
230
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
231
+
232
+ bus.emit('mongosh:new-user', { userId, anonymousId: userId });
233
+
234
+ expect(analyticsOutput).deep.equal([
235
+ [
236
+ 'identify',
237
+ {
238
+ deviceId: 'unknown',
239
+ anonymousId: userId,
240
+ traits: {
241
+ platform: process.platform,
242
+ arch: process.arch,
243
+ session_id: logId,
244
+ },
245
+ },
246
+ ],
247
+ ]);
248
+ expect(logOutput[0]).contains({
249
+ c: 'MONGOSH',
250
+ id: 1000000006,
251
+ ctx: 'telemetry',
252
+ msg: 'Error: Test',
253
+ });
254
+ });
255
+
256
+ it('automatically sets up device ID for telemetry', async function () {
257
+ const loggingAndTelemetry = setupLoggingAndTelemetry({
258
+ ...testLoggingArguments,
259
+ bus,
260
+ deviceId: undefined,
261
+ });
262
+
263
+ loggingAndTelemetry.attachLogger(logger);
264
+
265
+ bus.emit('mongosh:new-user', { userId, anonymousId: userId });
266
+
267
+ const deviceId = await getDeviceId();
268
+
269
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
270
+
271
+ expect(analyticsOutput).deep.equal([
272
+ [
273
+ 'identify',
274
+ {
275
+ deviceId,
276
+ anonymousId: userId,
277
+ traits: {
278
+ platform: process.platform,
279
+ arch: process.arch,
280
+ session_id: logId,
281
+ },
282
+ },
283
+ ],
284
+ ]);
285
+ });
286
+
287
+ it('only delays analytic outputs, not logging', async function () {
288
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
289
+ let resolveTelemetry: (value: unknown) => void = () => {};
290
+ const delayedTelemetry = new Promise((resolve) => {
291
+ resolveTelemetry = (value) => resolve(value);
292
+ });
293
+ sinon
294
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
295
+ .stub(require('native-machine-id'), 'getMachineId')
296
+ .resolves(delayedTelemetry);
297
+
298
+ const loggingAndTelemetry = setupLoggingAndTelemetry({
299
+ ...testLoggingArguments,
300
+ bus,
301
+ deviceId: undefined,
302
+ });
303
+
304
+ loggingAndTelemetry.attachLogger(logger);
305
+
306
+ // This event has both analytics and logging
307
+ bus.emit('mongosh:use', { db: '' });
308
+
309
+ expect(logOutput).to.have.lengthOf(1);
310
+ expect(analyticsOutput).to.have.lengthOf(0);
311
+
312
+ resolveTelemetry('1234');
313
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
314
+
315
+ expect(logOutput).to.have.lengthOf(1);
316
+ expect(analyticsOutput).to.have.lengthOf(1);
317
+
318
+ // Hash created from machine ID 1234
319
+ expect(analyticsOutput[0][1].deviceId).equals(
320
+ '8c9f929608f0ef13bfd5a290e0233f283e2cc25ffefc2ad8d9ef0650eb224a52'
321
+ );
322
+ });
323
+ });
324
+
325
+ it('detaching logger leads to no logging but persists analytics', async function () {
192
326
  loggingAndTelemetry.attachLogger(logger);
327
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
193
328
 
194
329
  expect(logOutput).to.have.lengthOf(0);
195
330
  expect(analyticsOutput).to.have.lengthOf(0);
@@ -226,7 +361,7 @@ describe('MongoshLoggingAndTelemetry', function () {
226
361
  expect(logOutput).to.have.lengthOf(4);
227
362
  });
228
363
 
229
- it('detaching logger mid-way leads to no logging but persists analytics', function () {
364
+ it('detaching logger mid-way leads to no logging but persists analytics', async function () {
230
365
  loggingAndTelemetry.attachLogger(logger);
231
366
 
232
367
  expect(logOutput).to.have.lengthOf(0);
@@ -236,6 +371,8 @@ describe('MongoshLoggingAndTelemetry', function () {
236
371
  bus.emit('mongosh:use', { db: '' });
237
372
 
238
373
  expect(logOutput).to.have.lengthOf(1);
374
+
375
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
239
376
  expect(analyticsOutput).to.have.lengthOf(1);
240
377
 
241
378
  loggingAndTelemetry.detachLogger();
@@ -243,10 +380,11 @@ describe('MongoshLoggingAndTelemetry', function () {
243
380
  bus.emit('mongosh:use', { db: '' });
244
381
 
245
382
  expect(logOutput).to.have.lengthOf(1);
383
+
246
384
  expect(analyticsOutput).to.have.lengthOf(2);
247
385
  });
248
386
 
249
- it('detaching logger is recoverable', function () {
387
+ it('detaching logger is recoverable', async function () {
250
388
  loggingAndTelemetry.attachLogger(logger);
251
389
 
252
390
  expect(logOutput).to.have.lengthOf(0);
@@ -256,6 +394,8 @@ describe('MongoshLoggingAndTelemetry', function () {
256
394
  bus.emit('mongosh:use', { db: '' });
257
395
 
258
396
  expect(logOutput).to.have.lengthOf(1);
397
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
398
+
259
399
  expect(analyticsOutput).to.have.lengthOf(1);
260
400
 
261
401
  loggingAndTelemetry.detachLogger();
@@ -263,6 +403,7 @@ describe('MongoshLoggingAndTelemetry', function () {
263
403
  bus.emit('mongosh:use', { db: '' });
264
404
 
265
405
  expect(logOutput).to.have.lengthOf(1);
406
+
266
407
  expect(analyticsOutput).to.have.lengthOf(2);
267
408
 
268
409
  loggingAndTelemetry.attachLogger(logger);
@@ -270,11 +411,13 @@ describe('MongoshLoggingAndTelemetry', function () {
270
411
  bus.emit('mongosh:use', { db: '' });
271
412
 
272
413
  expect(logOutput).to.have.lengthOf(2);
414
+
273
415
  expect(analyticsOutput).to.have.lengthOf(3);
274
416
  });
275
417
 
276
- it('tracks a sequence of events', function () {
418
+ it('tracks a sequence of events', async function () {
277
419
  loggingAndTelemetry.attachLogger(logger);
420
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
278
421
 
279
422
  expect(logOutput).to.have.lengthOf(0);
280
423
  expect(analyticsOutput).to.be.empty;
@@ -575,7 +718,8 @@ describe('MongoshLoggingAndTelemetry', function () {
575
718
  [
576
719
  'identify',
577
720
  {
578
- anonymousId: '53defe995fa47e6c13102d9d',
721
+ anonymousId: userId,
722
+ deviceId: 'test-device',
579
723
  traits: {
580
724
  platform: process.platform,
581
725
  arch: process.arch,
@@ -586,7 +730,8 @@ describe('MongoshLoggingAndTelemetry', function () {
586
730
  [
587
731
  'identify',
588
732
  {
589
- anonymousId: '53defe995fa47e6c13102d9d',
733
+ anonymousId: userId,
734
+ deviceId: 'test-device',
590
735
  traits: {
591
736
  platform: process.platform,
592
737
  arch: process.arch,
@@ -597,7 +742,8 @@ describe('MongoshLoggingAndTelemetry', function () {
597
742
  [
598
743
  'track',
599
744
  {
600
- anonymousId: '53defe995fa47e6c13102d9d',
745
+ anonymousId: userId,
746
+ deviceId: 'test-device',
601
747
  event: 'Startup Time',
602
748
  properties: {
603
749
  is_interactive: true,
@@ -613,6 +759,7 @@ describe('MongoshLoggingAndTelemetry', function () {
613
759
  'track',
614
760
  {
615
761
  anonymousId: '53defe995fa47e6c13102d9d',
762
+ deviceId: 'test-device',
616
763
  event: 'Error',
617
764
  properties: {
618
765
  mongosh_version: '1.0.0',
@@ -628,6 +775,7 @@ describe('MongoshLoggingAndTelemetry', function () {
628
775
  'track',
629
776
  {
630
777
  anonymousId: '53defe995fa47e6c13102d9d',
778
+ deviceId: 'test-device',
631
779
  event: 'Error',
632
780
  properties: {
633
781
  mongosh_version: '1.0.0',
@@ -643,6 +791,7 @@ describe('MongoshLoggingAndTelemetry', function () {
643
791
  'track',
644
792
  {
645
793
  anonymousId: '53defe995fa47e6c13102d9d',
794
+ deviceId: 'test-device',
646
795
  event: 'Use',
647
796
  properties: {
648
797
  mongosh_version: '1.0.0',
@@ -654,6 +803,7 @@ describe('MongoshLoggingAndTelemetry', function () {
654
803
  'track',
655
804
  {
656
805
  anonymousId: '53defe995fa47e6c13102d9d',
806
+ deviceId: 'test-device',
657
807
  event: 'Show',
658
808
  properties: {
659
809
  mongosh_version: '1.0.0',
@@ -673,6 +823,7 @@ describe('MongoshLoggingAndTelemetry', function () {
673
823
  shell: true,
674
824
  },
675
825
  anonymousId: '53defe995fa47e6c13102d9d',
826
+ deviceId: 'test-device',
676
827
  },
677
828
  ],
678
829
  [
@@ -685,6 +836,7 @@ describe('MongoshLoggingAndTelemetry', function () {
685
836
  nested: false,
686
837
  },
687
838
  anonymousId: '53defe995fa47e6c13102d9d',
839
+ deviceId: 'test-device',
688
840
  },
689
841
  ],
690
842
  [
@@ -696,6 +848,7 @@ describe('MongoshLoggingAndTelemetry', function () {
696
848
  session_id: logId,
697
849
  },
698
850
  anonymousId: '53defe995fa47e6c13102d9d',
851
+ deviceId: 'test-device',
699
852
  },
700
853
  ],
701
854
  [
@@ -707,6 +860,7 @@ describe('MongoshLoggingAndTelemetry', function () {
707
860
  session_id: logId,
708
861
  },
709
862
  anonymousId: '53defe995fa47e6c13102d9d',
863
+ deviceId: 'test-device',
710
864
  },
711
865
  ],
712
866
  [
@@ -719,12 +873,14 @@ describe('MongoshLoggingAndTelemetry', function () {
719
873
  shell: true,
720
874
  },
721
875
  anonymousId: '53defe995fa47e6c13102d9d',
876
+ deviceId: 'test-device',
722
877
  },
723
878
  ],
724
879
  [
725
880
  'track',
726
881
  {
727
882
  anonymousId: '53defe995fa47e6c13102d9d',
883
+ deviceId: 'test-device',
728
884
  event: 'Snippet Install',
729
885
  properties: {
730
886
  mongosh_version: '1.0.0',
@@ -735,8 +891,9 @@ describe('MongoshLoggingAndTelemetry', function () {
735
891
  ]);
736
892
  });
737
893
 
738
- it('buffers deprecated API calls', function () {
894
+ it('buffers deprecated API calls', async function () {
739
895
  loggingAndTelemetry.attachLogger(logger);
896
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
740
897
 
741
898
  expect(logOutput).to.have.lengthOf(0);
742
899
  expect(analyticsOutput).to.be.empty;
@@ -819,6 +976,7 @@ describe('MongoshLoggingAndTelemetry', function () {
819
976
  'track',
820
977
  {
821
978
  anonymousId: '53defe995fa47e6c13102d9d',
979
+ deviceId: 'test-device',
822
980
  event: 'Deprecated Method',
823
981
  properties: {
824
982
  mongosh_version: '1.0.0',
@@ -832,6 +990,7 @@ describe('MongoshLoggingAndTelemetry', function () {
832
990
  'track',
833
991
  {
834
992
  anonymousId: '53defe995fa47e6c13102d9d',
993
+ deviceId: 'test-device',
835
994
  event: 'Deprecated Method',
836
995
  properties: {
837
996
  mongosh_version: '1.0.0',
@@ -845,6 +1004,7 @@ describe('MongoshLoggingAndTelemetry', function () {
845
1004
  'track',
846
1005
  {
847
1006
  anonymousId: '53defe995fa47e6c13102d9d',
1007
+ deviceId: 'test-device',
848
1008
  event: 'Deprecated Method',
849
1009
  properties: {
850
1010
  mongosh_version: '1.0.0',
@@ -858,6 +1018,7 @@ describe('MongoshLoggingAndTelemetry', function () {
858
1018
  'track',
859
1019
  {
860
1020
  anonymousId: '53defe995fa47e6c13102d9d',
1021
+ deviceId: 'test-device',
861
1022
  event: 'API Call',
862
1023
  properties: {
863
1024
  mongosh_version: '1.0.0',
@@ -872,6 +1033,7 @@ describe('MongoshLoggingAndTelemetry', function () {
872
1033
  'track',
873
1034
  {
874
1035
  anonymousId: '53defe995fa47e6c13102d9d',
1036
+ deviceId: 'test-device',
875
1037
  event: 'API Call',
876
1038
  properties: {
877
1039
  mongosh_version: '1.0.0',
@@ -885,6 +1047,7 @@ describe('MongoshLoggingAndTelemetry', function () {
885
1047
  ]);
886
1048
 
887
1049
  bus.emit('mongosh:new-user', { userId, anonymousId: userId });
1050
+
888
1051
  logOutput = [];
889
1052
  analyticsOutput = [];
890
1053
 
@@ -907,6 +1070,7 @@ describe('MongoshLoggingAndTelemetry', function () {
907
1070
  class: 'Database',
908
1071
  method: 'cloneDatabase',
909
1072
  });
1073
+
910
1074
  expect(analyticsOutput).to.have.lengthOf(2);
911
1075
  });
912
1076
 
@@ -934,11 +1098,12 @@ describe('MongoshLoggingAndTelemetry', function () {
934
1098
  expect(analyticsOutput).to.be.empty;
935
1099
  });
936
1100
 
937
- it('tracks custom logging events', function () {
1101
+ it('tracks custom logging events', async function () {
938
1102
  expect(logOutput).to.have.lengthOf(0);
939
1103
  expect(analyticsOutput).to.be.empty;
940
1104
 
941
1105
  loggingAndTelemetry.attachLogger(logger);
1106
+ await (loggingAndTelemetry as LoggingAndTelemetry).setupTelemetryPromise;
942
1107
 
943
1108
  bus.emit('mongosh:connect', {
944
1109
  uri: 'mongodb://localhost/',
@@ -1023,6 +1188,7 @@ describe('MongoshLoggingAndTelemetry', function () {
1023
1188
  'track',
1024
1189
  {
1025
1190
  anonymousId: undefined,
1191
+ deviceId: 'test-device',
1026
1192
  event: 'New Connection',
1027
1193
  properties: {
1028
1194
  mongosh_version: '1.0.0',
@@ -1036,4 +1202,13 @@ describe('MongoshLoggingAndTelemetry', function () {
1036
1202
  ],
1037
1203
  ]);
1038
1204
  });
1205
+
1206
+ describe('getDeviceId()', function () {
1207
+ it('is consistent on the same machine', async function () {
1208
+ const idA = await getDeviceId();
1209
+ const idB = await getDeviceId();
1210
+
1211
+ expect(idA).equals(idB);
1212
+ });
1213
+ });
1039
1214
  });