@webex/internal-plugin-metrics 3.4.0 → 3.5.0-next.10
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.
- package/dist/behavioral-metrics.js +63 -0
- package/dist/behavioral-metrics.js.map +1 -0
- package/dist/business-metrics.js +169 -0
- package/dist/business-metrics.js.map +1 -0
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +27 -11
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +14 -4
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +13 -3
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/{behavioral/behavioral-metrics.js → generic-metrics.js} +77 -92
- package/dist/generic-metrics.js.map +1 -0
- package/dist/index.js +22 -1
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/new-metrics.js +124 -24
- package/dist/new-metrics.js.map +1 -1
- package/dist/operational-metrics.js +56 -0
- package/dist/operational-metrics.js.map +1 -0
- package/dist/rtcMetrics/constants.js +11 -0
- package/dist/rtcMetrics/constants.js.map +1 -0
- package/dist/rtcMetrics/index.js +202 -0
- package/dist/rtcMetrics/index.js.map +1 -0
- package/dist/types/behavioral-metrics.d.ts +25 -0
- package/dist/types/business-metrics.d.ts +47 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +27 -6
- package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +2 -1
- package/dist/types/call-diagnostic/config.d.ts +3 -0
- package/dist/types/generic-metrics.d.ts +63 -0
- package/dist/types/index.d.ts +5 -2
- package/dist/types/metrics.types.d.ts +27 -14
- package/dist/types/new-metrics.d.ts +42 -9
- package/dist/types/operational-metrics.d.ts +19 -0
- package/dist/types/rtcMetrics/constants.d.ts +4 -0
- package/dist/types/rtcMetrics/index.d.ts +71 -0
- package/package.json +12 -12
- package/src/behavioral-metrics.ts +40 -0
- package/src/business-metrics.ts +118 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +1 -1
- package/src/call-diagnostic/call-diagnostic-metrics.ts +30 -9
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +17 -4
- package/src/call-diagnostic/config.ts +12 -0
- package/src/generic-metrics.ts +146 -0
- package/src/index.ts +7 -1
- package/src/metrics.types.ts +32 -16
- package/src/new-metrics.ts +100 -13
- package/src/operational-metrics.ts +24 -0
- package/src/rtcMetrics/constants.ts +3 -0
- package/src/rtcMetrics/index.ts +186 -0
- package/test/unit/spec/behavioral/behavioral-metrics.ts +51 -10
- package/test/unit/spec/business/business-metrics.ts +182 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +2 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +4 -6
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +418 -12
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +22 -8
- package/test/unit/spec/new-metrics.ts +32 -3
- package/test/unit/spec/operational/operational-metrics.ts +115 -0
- package/test/unit/spec/prelogin-metrics-batcher.ts +3 -1
- package/test/unit/spec/rtcMetrics/index.ts +155 -0
- package/dist/behavioral/behavioral-metrics.js.map +0 -1
- package/dist/behavioral/config.js +0 -11
- package/dist/behavioral/config.js.map +0 -1
- package/dist/types/behavioral/behavioral-metrics.d.ts +0 -63
- package/dist/types/behavioral/config.d.ts +0 -1
- package/src/behavioral/behavioral-metrics.ts +0 -179
- package/src/behavioral/config.ts +0 -3
|
@@ -235,6 +235,8 @@ describe('internal-plugin-metrics', () => {
|
|
|
235
235
|
});
|
|
236
236
|
|
|
237
237
|
describe('getBuildType', () => {
|
|
238
|
+
const webex = {internal: {metrics: {config: {}}}};
|
|
239
|
+
|
|
238
240
|
beforeEach(() => {
|
|
239
241
|
process.env.NODE_ENV = 'production';
|
|
240
242
|
});
|
|
@@ -246,25 +248,33 @@ describe('internal-plugin-metrics', () => {
|
|
|
246
248
|
['https://web.webex.com', true, 'test'],
|
|
247
249
|
].forEach(([webClientDomain, markAsTestEvent, expected]) => {
|
|
248
250
|
it(`returns expected result for ${webClientDomain}`, () => {
|
|
249
|
-
assert.deepEqual(getBuildType(webClientDomain, markAsTestEvent as any), expected);
|
|
251
|
+
assert.deepEqual(getBuildType(webex, webClientDomain, markAsTestEvent as any), expected);
|
|
250
252
|
});
|
|
251
253
|
});
|
|
252
254
|
|
|
253
255
|
it('returns "test" for NODE_ENV "foo"', () => {
|
|
254
256
|
process.env.NODE_ENV = 'foo';
|
|
255
|
-
assert.deepEqual(getBuildType('production'), 'test');
|
|
257
|
+
assert.deepEqual(getBuildType(webex, 'production'), 'test');
|
|
256
258
|
});
|
|
257
259
|
|
|
258
260
|
it('returns "test" for NODE_ENV "production" and markAsTestEvent = true', () => {
|
|
259
261
|
process.env.NODE_ENV = 'production';
|
|
260
|
-
assert.deepEqual(getBuildType('my.domain', true), 'test');
|
|
262
|
+
assert.deepEqual(getBuildType(webex, 'my.domain', true), 'test');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('returns "test" for NODE_ENV "production" when webex.caBuildType = "test"', () => {
|
|
266
|
+
process.env.NODE_ENV = 'production';
|
|
267
|
+
assert.deepEqual(
|
|
268
|
+
getBuildType({internal: {metrics: {config: {caBuildType: 'test'}}}}, 'my.domain'),
|
|
269
|
+
'test'
|
|
270
|
+
);
|
|
261
271
|
});
|
|
262
272
|
});
|
|
263
273
|
|
|
264
274
|
describe('prepareDiagnosticMetricItem', () => {
|
|
265
275
|
let webex: any;
|
|
266
276
|
|
|
267
|
-
const check = (eventName: string, expectedEvent: any) => {
|
|
277
|
+
const check = (eventName: string, expectedEvent: any, expectedUpgradeChannel: string) => {
|
|
268
278
|
const eventPayload = {event: {name: eventName}};
|
|
269
279
|
const item = prepareDiagnosticMetricItem(webex, {
|
|
270
280
|
eventPayload,
|
|
@@ -276,6 +286,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
276
286
|
origin: {
|
|
277
287
|
buildType: 'prod',
|
|
278
288
|
networkType: 'unknown',
|
|
289
|
+
upgradeChannel: expectedUpgradeChannel
|
|
279
290
|
},
|
|
280
291
|
event: {name: eventName, ...expectedEvent},
|
|
281
292
|
},
|
|
@@ -407,19 +418,19 @@ describe('internal-plugin-metrics', () => {
|
|
|
407
418
|
],
|
|
408
419
|
].forEach(([eventName, expectedEvent]) => {
|
|
409
420
|
it(`returns expected result for ${eventName}`, () => {
|
|
410
|
-
check(eventName as string, expectedEvent);
|
|
421
|
+
check(eventName as string, expectedEvent, 'gold');
|
|
411
422
|
});
|
|
412
423
|
});
|
|
413
424
|
|
|
414
|
-
it('
|
|
425
|
+
it('sets buildType and upgradeChannel correctly', () => {
|
|
415
426
|
const item: any = {
|
|
416
427
|
eventPayload: {
|
|
417
428
|
event: {
|
|
418
429
|
name: 'client.exit.app',
|
|
419
430
|
eventData: {
|
|
420
431
|
markAsTestEvent: true,
|
|
421
|
-
webClientDomain: 'https://web.webex.com'
|
|
422
|
-
}
|
|
432
|
+
webClientDomain: 'https://web.webex.com',
|
|
433
|
+
},
|
|
423
434
|
},
|
|
424
435
|
},
|
|
425
436
|
type: ['diagnostic-event'],
|
|
@@ -428,11 +439,14 @@ describe('internal-plugin-metrics', () => {
|
|
|
428
439
|
// just submit any event
|
|
429
440
|
prepareDiagnosticMetricItem(webex, item);
|
|
430
441
|
assert.deepEqual(item.eventPayload.origin.buildType, 'test');
|
|
442
|
+
assert.deepEqual(item.eventPayload.origin.upgradeChannel, 'test');
|
|
431
443
|
|
|
432
444
|
delete item.eventPayload.origin.buildType;
|
|
445
|
+
delete item.eventPayload.origin.upgradeChannel;
|
|
433
446
|
item.eventPayload.event.eventData.markAsTestEvent = false;
|
|
434
447
|
prepareDiagnosticMetricItem(webex, item);
|
|
435
448
|
assert.deepEqual(item.eventPayload.origin.buildType, 'prod');
|
|
449
|
+
assert.deepEqual(item.eventPayload.origin.upgradeChannel, 'gold');
|
|
436
450
|
});
|
|
437
451
|
});
|
|
438
452
|
|
|
@@ -11,9 +11,6 @@ describe('internal-plugin-metrics', () => {
|
|
|
11
11
|
newMetrics: NewMetrics,
|
|
12
12
|
},
|
|
13
13
|
meetings: {
|
|
14
|
-
meetingCollection: {
|
|
15
|
-
get: sinon.stub(),
|
|
16
|
-
},
|
|
17
14
|
},
|
|
18
15
|
request: sinon.stub().resolves({}),
|
|
19
16
|
logger: {
|
|
@@ -73,6 +70,38 @@ describe('internal-plugin-metrics', () => {
|
|
|
73
70
|
sinon.restore();
|
|
74
71
|
})
|
|
75
72
|
|
|
73
|
+
it('lazy metrics backend initialization when checking if backend ready', () => {
|
|
74
|
+
assert.isUndefined(webex.internal.newMetrics.behavioralMetrics);
|
|
75
|
+
webex.internal.newMetrics.isReadyToSubmitBehavioralEvents();
|
|
76
|
+
assert.isDefined(webex.internal.newMetrics.behavioralMetrics);
|
|
77
|
+
|
|
78
|
+
assert.isUndefined(webex.internal.newMetrics.operationalMetrics);
|
|
79
|
+
webex.internal.newMetrics.isReadyToSubmitOperationalEvents();
|
|
80
|
+
assert.isDefined(webex.internal.newMetrics.operationalMetrics);
|
|
81
|
+
|
|
82
|
+
assert.isUndefined(webex.internal.newMetrics.businessMetrics)
|
|
83
|
+
webex.internal.newMetrics.isReadyToSubmitBusinessEvents();
|
|
84
|
+
assert.isDefined(webex.internal.newMetrics.businessMetrics);
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it('passes the table through to the business metrics', () => {
|
|
88
|
+
assert.isUndefined(webex.internal.newMetrics.businessMetrics)
|
|
89
|
+
webex.internal.newMetrics.isReadyToSubmitBusinessEvents();
|
|
90
|
+
assert.isDefined(webex.internal.newMetrics.businessMetrics);
|
|
91
|
+
webex.internal.newMetrics.businessMetrics.submitBusinessEvent = sinon.stub();
|
|
92
|
+
webex.internal.newMetrics.submitBusinessEvent({
|
|
93
|
+
name: 'foobar',
|
|
94
|
+
payload: {},
|
|
95
|
+
table: 'test',
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
assert.calledWith(webex.internal.newMetrics.businessMetrics.submitBusinessEvent, {
|
|
99
|
+
name: 'foobar',
|
|
100
|
+
payload: {},
|
|
101
|
+
table: 'test',
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
|
|
76
105
|
it('submits Client Event successfully', () => {
|
|
77
106
|
webex.internal.newMetrics.submitClientEvent({
|
|
78
107
|
name: 'client.alert.displayed',
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import sinon from 'sinon';
|
|
2
|
+
import {assert} from '@webex/test-helper-chai';
|
|
3
|
+
import {BrowserDetection} from '@webex/common';
|
|
4
|
+
import {OperationalMetrics, config, getOSNameInternal} from '@webex/internal-plugin-metrics';
|
|
5
|
+
import uuid from 'uuid';
|
|
6
|
+
|
|
7
|
+
//@ts-ignore
|
|
8
|
+
global.window = {location: {hostname: 'whatever'}, navigator: {language: 'language'}};
|
|
9
|
+
process.env.NODE_ENV = 'test';
|
|
10
|
+
|
|
11
|
+
const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
|
|
12
|
+
|
|
13
|
+
describe('internal-plugin-metrics', () => {
|
|
14
|
+
describe('OperationalMetrics', () => {
|
|
15
|
+
let webex;
|
|
16
|
+
let now;
|
|
17
|
+
let operationalMetrics: OperationalMetrics;
|
|
18
|
+
|
|
19
|
+
const tags = {key: 'val'};
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
now = new Date();
|
|
23
|
+
|
|
24
|
+
webex = {
|
|
25
|
+
canAuthorize: true,
|
|
26
|
+
version: 'webex-version',
|
|
27
|
+
internal: {
|
|
28
|
+
services: {
|
|
29
|
+
get: () => 'locus-url',
|
|
30
|
+
},
|
|
31
|
+
metrics: {
|
|
32
|
+
submitClientMetrics: sinon.stub(),
|
|
33
|
+
config: {...config.metrics},
|
|
34
|
+
},
|
|
35
|
+
newMetrics: {},
|
|
36
|
+
device: {
|
|
37
|
+
userId: 'userId',
|
|
38
|
+
url: 'https://wdm-intb.ciscospark.com/wdm/api/v1/devices/deviceId',
|
|
39
|
+
orgId: 'orgId',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
meetings: {
|
|
43
|
+
config: {
|
|
44
|
+
metrics: {
|
|
45
|
+
clientType: 'TEAMS_CLIENT',
|
|
46
|
+
subClientType: 'WEB_APP',
|
|
47
|
+
clientName: 'Cantina',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
geoHintInfo: {
|
|
51
|
+
clientAddress: '1.3.4.5',
|
|
52
|
+
countryCode: 'UK',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
credentials: {
|
|
56
|
+
isUnverifiedGuest: false,
|
|
57
|
+
},
|
|
58
|
+
prepareFetchOptions: sinon.stub().callsFake((opts: any) => ({...opts, foo: 'bar'})),
|
|
59
|
+
request: sinon.stub().resolves({body: {}}),
|
|
60
|
+
logger: {
|
|
61
|
+
log: sinon.stub(),
|
|
62
|
+
error: sinon.stub(),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
sinon.createSandbox();
|
|
67
|
+
sinon.useFakeTimers(now.getTime());
|
|
68
|
+
operationalMetrics = new OperationalMetrics({}, {parent: webex});
|
|
69
|
+
sinon.stub(uuid, 'v4').returns('my-fake-id');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
sinon.restore();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('#sendEvent', () => {
|
|
77
|
+
it('should send correctly shaped operational event (check name building and internal tagged event building)', () => {
|
|
78
|
+
// For some reasons `jest` isn't available when testing form build server - so can't use `jest.fn()` here...
|
|
79
|
+
const requestCalls = [];
|
|
80
|
+
const request = function(arg) { requestCalls.push(arg) }
|
|
81
|
+
|
|
82
|
+
operationalMetrics.clientMetricsBatcher.request = request;
|
|
83
|
+
|
|
84
|
+
assert.equal(requestCalls.length, 0)
|
|
85
|
+
operationalMetrics.submitOperationalEvent({ name: "foobar", payload: {bar:"gee"} })
|
|
86
|
+
assert.equal(requestCalls.length, 1)
|
|
87
|
+
assert.deepEqual(requestCalls[0], {
|
|
88
|
+
context: {
|
|
89
|
+
app: {version: 'webex-version'},
|
|
90
|
+
device: {id: 'deviceId'},
|
|
91
|
+
locale: 'language',
|
|
92
|
+
os: {
|
|
93
|
+
name: getOSNameInternal(),
|
|
94
|
+
version: getOSVersion(),
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
metricName: 'foobar',
|
|
98
|
+
tags: {
|
|
99
|
+
browser: getBrowserName(),
|
|
100
|
+
browserHeight: window.innerHeight,
|
|
101
|
+
browserVersion: getBrowserVersion(),
|
|
102
|
+
browserWidth: window.innerWidth,
|
|
103
|
+
domain: window.location.hostname,
|
|
104
|
+
inIframe: false,
|
|
105
|
+
locale: window.navigator.language,
|
|
106
|
+
os: getOSNameInternal(),
|
|
107
|
+
bar: "gee"
|
|
108
|
+
},
|
|
109
|
+
timestamp: requestCalls[0].timestamp, // This is to bypass time check, which is correctly tested in behavioral-metrics tests.
|
|
110
|
+
type: ['operational'],
|
|
111
|
+
});
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -82,6 +82,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
82
82
|
origin: {
|
|
83
83
|
buildType: 'test',
|
|
84
84
|
networkType: 'unknown',
|
|
85
|
+
upgradeChannel: 'test',
|
|
85
86
|
},
|
|
86
87
|
originTime: {
|
|
87
88
|
sent: dateAfterBatcherWait.toISOString(),
|
|
@@ -211,7 +212,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
211
212
|
// item also gets assigned a delay property but the key is a Symbol and haven't been able to test that..
|
|
212
213
|
assert.deepEqual(calls.args[0].eventPayload, {
|
|
213
214
|
event: 'my.event',
|
|
214
|
-
origin: {buildType: 'test', networkType: 'unknown'},
|
|
215
|
+
origin: {buildType: 'test', networkType: 'unknown', upgradeChannel: 'test'},
|
|
215
216
|
});
|
|
216
217
|
|
|
217
218
|
assert.deepEqual(calls.args[0].type, ['diagnostic-event']);
|
|
@@ -225,6 +226,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
225
226
|
origin: {
|
|
226
227
|
buildType: 'test',
|
|
227
228
|
networkType: 'unknown',
|
|
229
|
+
upgradeChannel: 'test',
|
|
228
230
|
},
|
|
229
231
|
});
|
|
230
232
|
assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].type, ['diagnostic-event']);
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import 'jsdom-global/register';
|
|
2
|
+
import RtcMetrics from '../../../../src/rtcMetrics';
|
|
3
|
+
import MockWebex from '@webex/test-helper-mock-webex';
|
|
4
|
+
import {assert} from '@webex/test-helper-chai';
|
|
5
|
+
import sinon from 'sinon';
|
|
6
|
+
import RTC_METRICS from '../../../../src/rtcMetrics/constants';
|
|
7
|
+
|
|
8
|
+
const FAKE_METRICS_ITEM = {payload: ['{"type":"string","value":"fake-metrics","id":""}']};
|
|
9
|
+
const FAILURE_METRICS_ITEM = {
|
|
10
|
+
name: "onconnectionstatechange",
|
|
11
|
+
payload: ['{"type":"string","value":"failed","id":""}'],
|
|
12
|
+
timestamp: 1707929986667
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const STATS_WITH_IP = '{"id":"RTCIceCandidate_/kQs0ZNU","type":"remote-candidate","transportId":"RTCTransport_0_1","isRemote":true,"ip":"11.22.111.255","address":"11.22.111.255","port":5004,"protocol":"udp","candidateType":"host","priority":2130706431}';
|
|
16
|
+
const STATS_WITH_IP_RESULT = '{"id":"RTCIceCandidate_/kQs0ZNU","type":"remote-candidate","transportId":"RTCTransport_0_1","isRemote":true,"ip":"11.22.111.240","address":"11.22.111.240","port":5004,"protocol":"udp","candidateType":"host","priority":2130706431}';
|
|
17
|
+
|
|
18
|
+
describe('RtcMetrics', () => {
|
|
19
|
+
let metrics: RtcMetrics;
|
|
20
|
+
let webex: MockWebex;
|
|
21
|
+
let clock;
|
|
22
|
+
let anonymizeIpSpy;
|
|
23
|
+
|
|
24
|
+
const sandbox = sinon.createSandbox();
|
|
25
|
+
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
clock = sinon.useFakeTimers();
|
|
28
|
+
window.setInterval = setInterval;
|
|
29
|
+
webex = new MockWebex();
|
|
30
|
+
metrics = new RtcMetrics(webex, 'mock-meeting-id', 'mock-correlation-id');
|
|
31
|
+
anonymizeIpSpy = sandbox.spy(metrics, 'anonymizeIp');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterEach(() => {
|
|
35
|
+
sandbox.restore();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('sendMetrics should send a webex request', () => {
|
|
39
|
+
assert.notCalled(webex.request);
|
|
40
|
+
|
|
41
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
42
|
+
(metrics as any).sendMetrics();
|
|
43
|
+
|
|
44
|
+
assert.callCount(webex.request, 1);
|
|
45
|
+
assert.calledWithMatch(webex.request, sinon.match.has('headers', {
|
|
46
|
+
type: 'webrtcMedia',
|
|
47
|
+
appId: RTC_METRICS.APP_ID,
|
|
48
|
+
}));
|
|
49
|
+
assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].data[0].payload', FAKE_METRICS_ITEM.payload));
|
|
50
|
+
assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].meetingId', 'mock-meeting-id'));
|
|
51
|
+
assert.calledWithMatch(webex.request, sinon.match.hasNested('body.metrics[0].correlationId', 'mock-correlation-id'));
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should have a defined sendMetricsInQueue function which is public', () => {
|
|
55
|
+
assert.isDefined(metrics.sendMetricsInQueue);
|
|
56
|
+
assert.isFunction(metrics.sendMetricsInQueue);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it('should send metrics requests over time', () => {
|
|
60
|
+
assert.notCalled(webex.request);
|
|
61
|
+
|
|
62
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
63
|
+
assert.deepEqual(metrics.metricsQueue, [FAKE_METRICS_ITEM]);
|
|
64
|
+
clock.tick(60 * 1000);
|
|
65
|
+
|
|
66
|
+
assert.callCount(webex.request, 1);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('should not send requests with no items in the queue', () => {
|
|
70
|
+
clock.tick(60 * 1000);
|
|
71
|
+
assert.notCalled(webex.request);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('sendMetricsInQueue should send metrics if any exist in the queue', () => {
|
|
75
|
+
assert.notCalled(webex.request);
|
|
76
|
+
|
|
77
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
78
|
+
(metrics as any).sendMetricsInQueue();
|
|
79
|
+
|
|
80
|
+
assert.callCount(webex.request, 1);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should clear out metrics on close', () => {
|
|
84
|
+
assert.notCalled(webex.request);
|
|
85
|
+
|
|
86
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
87
|
+
metrics.closeMetrics();
|
|
88
|
+
|
|
89
|
+
assert.callCount(webex.request, 1);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should clear out metrics on failure', () => {
|
|
93
|
+
assert.notCalled(webex.request);
|
|
94
|
+
|
|
95
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
96
|
+
|
|
97
|
+
assert.callCount(webex.request, 1);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it('should have the same connectionId on success', () => {
|
|
101
|
+
const originalId = metrics.connectionId;
|
|
102
|
+
|
|
103
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
104
|
+
|
|
105
|
+
assert.strictEqual(originalId, metrics.connectionId);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it('should have a new connectionId on failure', () => {
|
|
109
|
+
const originalId = metrics.connectionId;
|
|
110
|
+
|
|
111
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
112
|
+
|
|
113
|
+
assert.notEqual(originalId, metrics.connectionId);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('should anonymize IP addresses', () => {
|
|
117
|
+
assert.strictEqual(metrics.anonymizeIp(STATS_WITH_IP), STATS_WITH_IP_RESULT);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('should call anonymizeIp', () => {
|
|
121
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
122
|
+
assert.calledOnce(anonymizeIpSpy);
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
it('should send metrics on first stats-report', () => {
|
|
126
|
+
assert.callCount(webex.request, 0);
|
|
127
|
+
|
|
128
|
+
metrics.addMetrics(FAKE_METRICS_ITEM);
|
|
129
|
+
assert.callCount(webex.request, 0);
|
|
130
|
+
|
|
131
|
+
// first stats-report should trigger a call to webex.request
|
|
132
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
133
|
+
assert.callCount(webex.request, 1);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it('should send metrics on first stats-report after a new connection', () => {
|
|
137
|
+
assert.callCount(webex.request, 0);
|
|
138
|
+
|
|
139
|
+
// first stats-report should trigger a call to webex.request
|
|
140
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
141
|
+
assert.callCount(webex.request, 1);
|
|
142
|
+
|
|
143
|
+
// subsequent stats-report doesn't trigger it
|
|
144
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
145
|
+
assert.callCount(webex.request, 1);
|
|
146
|
+
|
|
147
|
+
// now, simulate a failure - that triggers a new connection and upload of the metrics
|
|
148
|
+
metrics.addMetrics(FAILURE_METRICS_ITEM);
|
|
149
|
+
assert.callCount(webex.request, 2);
|
|
150
|
+
|
|
151
|
+
// and another stats-report should trigger another upload of the metrics
|
|
152
|
+
metrics.addMetrics({ name: 'stats-report', payload: [STATS_WITH_IP] });
|
|
153
|
+
assert.callCount(webex.request, 3);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_lodash","require","_common","_webexCore","_metrics","_config","_clientMetricsBatcher","_interopRequireDefault","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","_BrowserDetection","BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","BehavioralMetrics","exports","_StatelessWebexPlugin","_inherits2","_super","_this","_classCallCheck2","_len","length","args","Array","_key","concat","_defineProperty2","_assertThisInitialized2","logger","webex","device","internal","version","clientMetricsBatcher","ClientMetricsBatcher","parent","_createClass2","key","value","getDeviceId","url","n","lastIndexOf","substring","getContext","context","app","id","locale","window","navigator","language","os","name","getOSNameInternal","getDefaultTags","tags","browser","browserHeight","innerHeight","browserVersion","browserWidth","innerWidth","domain","location","hostname","inIframe","self","top","createEventObject","_ref","product","agent","target","verb","payload","metricName","allTags","merge","event","timestamp","_now","type","isReadyToSubmitBehavioralEvents","deviceId","submitBehavioralEvent","_ref2","log","BEHAVIORAL_LOG_IDENTIFIER","behavioralEvent","request","StatelessWebexPlugin"],"sources":["behavioral-metrics.ts"],"sourcesContent":["import {merge} from 'lodash';\nimport {BrowserDetection} from '@webex/common';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\nimport {getOSNameInternal} from '../metrics';\nimport {BEHAVIORAL_LOG_IDENTIFIER} from './config';\nimport {\n MetricEventProduct,\n MetricEventAgent,\n MetricEventVerb,\n BehavioralEventContext,\n BehavioralEvent,\n BehavioralEventPayload,\n} from '../metrics.types';\nimport ClientMetricsBatcher from '../client-metrics-batcher';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\n/**\n * @description Util class to handle Behavioral Metrics\n * @export\n * @class BehavioralMetrics\n */\nexport default class BehavioralMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private clientMetricsBatcher: ClientMetricsBatcher;\n private logger: any; // to avoid adding @ts-ignore everywhere\n private device: any;\n private version: string;\n\n /**\n * Constructor\n * @param {any[]} args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.logger = this.webex.logger;\n // @ts-ignore\n this.device = this.webex.internal.device;\n // @ts-ignore\n this.version = this.webex.version;\n // @ts-ignore\n this.clientMetricsBatcher = new ClientMetricsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the deviceId from our registration with WDM.\n * @returns {string} deviceId or empty string\n */\n private getDeviceId(): string {\n const {url} = this.device;\n if (url && url.length !== 0) {\n const n = url.lastIndexOf('/');\n if (n !== -1) {\n return url.substring(n + 1);\n }\n }\n\n return '';\n }\n\n /**\n * Returns the context object to be submitted with all behavioral metrics.\n * @returns {BehavioralEventContext}\n */\n private getContext(): BehavioralEventContext {\n const context: BehavioralEventContext = {\n app: {\n version: this.version,\n },\n device: {\n id: this.getDeviceId(),\n },\n locale: window.navigator.language,\n os: {\n name: getOSNameInternal(),\n version: getOSVersion(),\n },\n };\n\n return context;\n }\n\n /**\n * Returns the default tags to be included with all behavioral metrics.\n * @returns {BehavioralEventPayload}\n */\n private getDefaultTags(): BehavioralEventPayload {\n const tags = {\n browser: getBrowserName(),\n browserHeight: window.innerHeight,\n browserVersion: getBrowserVersion(),\n browserWidth: window.innerWidth,\n domain: window.location.hostname,\n inIframe: window.self !== window.top,\n locale: window.navigator.language,\n os: getOSNameInternal(),\n };\n\n return tags;\n }\n\n /**\n * Creates the object to send to our metrics endpoint for a behavioral event\n * @param {MetricEventProduct} product\n * @param {MetricEventAgent} agent\n * @param {string} target\n * @param {MetricEventVerb} verb\n * @returns {BehavioralEventPayload}\n */\n private createEventObject({\n product,\n agent,\n target,\n verb,\n payload,\n }: {\n product: MetricEventProduct;\n agent: MetricEventAgent;\n target: string;\n verb: MetricEventVerb;\n payload?: BehavioralEventPayload;\n }): BehavioralEvent {\n const metricName = `${product}.${agent}.${target}.${verb}`;\n let allTags: BehavioralEventPayload = payload;\n allTags = merge(allTags, this.getDefaultTags());\n\n const event: BehavioralEvent = {\n context: this.getContext(),\n metricName,\n tags: allTags,\n timestamp: Date.now(),\n type: ['behavioral'],\n };\n\n return event;\n }\n\n /**\n * Returns true once we're ready to submit behavioral metrics, after startup.\n * @returns {boolean} true when deviceId is defined and non-empty\n */\n public isReadyToSubmitBehavioralEvents(): boolean {\n const deviceId = this.getDeviceId();\n\n return deviceId && deviceId.length !== 0;\n }\n\n /**\n * Submit a behavioral metric to our metrics endpoint.\n * @param {MetricEventProduct} product the product from which the metric is being submitted, e.g. 'webex' web client, 'wxcc_desktop'\n * @param {MetricEventAgent} agent the source of the action for this metric\n * @param {string} target the 'thing' that this metric includes information about\n * @param {MetricEventVerb} verb the action that this metric includes information about\n * @param {BehavioralEventPayload} payload information specific to this event. This should be flat, i.e. it should not include nested objects.\n * @returns {Promise<any>}\n */\n public submitBehavioralEvent({\n product,\n agent,\n target,\n verb,\n payload,\n }: {\n product: MetricEventProduct;\n agent: MetricEventAgent;\n target: string;\n verb: MetricEventVerb;\n payload?: BehavioralEventPayload;\n }) {\n this.logger.log(\n BEHAVIORAL_LOG_IDENTIFIER,\n `BehavioralMetrics: @submitBehavioralEvent. Submit Behavioral event: ${product}.${agent}.${target}.${verb}`\n );\n const behavioralEvent = this.createEventObject({product, agent, target, verb, payload});\n\n return this.clientMetricsBatcher.request(behavioralEvent);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
4
|
-
_Object$defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.BEHAVIORAL_LOG_IDENTIFIER = void 0;
|
|
8
|
-
/* eslint-disable import/prefer-default-export */
|
|
9
|
-
|
|
10
|
-
var BEHAVIORAL_LOG_IDENTIFIER = exports.BEHAVIORAL_LOG_IDENTIFIER = 'behavioral-events -> ';
|
|
11
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["BEHAVIORAL_LOG_IDENTIFIER","exports"],"sources":["config.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\n\nexport const BEHAVIORAL_LOG_IDENTIFIER = 'behavioral-events -> ';\n"],"mappings":";;;;;;;AAAA;;AAEO,IAAMA,yBAAyB,GAAAC,OAAA,CAAAD,yBAAA,GAAG,uBAAuB"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { StatelessWebexPlugin } from '@webex/webex-core';
|
|
2
|
-
import { MetricEventProduct, MetricEventAgent, MetricEventVerb, BehavioralEventPayload } from '../metrics.types';
|
|
3
|
-
/**
|
|
4
|
-
* @description Util class to handle Behavioral Metrics
|
|
5
|
-
* @export
|
|
6
|
-
* @class BehavioralMetrics
|
|
7
|
-
*/
|
|
8
|
-
export default class BehavioralMetrics extends StatelessWebexPlugin {
|
|
9
|
-
private clientMetricsBatcher;
|
|
10
|
-
private logger;
|
|
11
|
-
private device;
|
|
12
|
-
private version;
|
|
13
|
-
/**
|
|
14
|
-
* Constructor
|
|
15
|
-
* @param {any[]} args
|
|
16
|
-
*/
|
|
17
|
-
constructor(...args: any[]);
|
|
18
|
-
/**
|
|
19
|
-
* Returns the deviceId from our registration with WDM.
|
|
20
|
-
* @returns {string} deviceId or empty string
|
|
21
|
-
*/
|
|
22
|
-
private getDeviceId;
|
|
23
|
-
/**
|
|
24
|
-
* Returns the context object to be submitted with all behavioral metrics.
|
|
25
|
-
* @returns {BehavioralEventContext}
|
|
26
|
-
*/
|
|
27
|
-
private getContext;
|
|
28
|
-
/**
|
|
29
|
-
* Returns the default tags to be included with all behavioral metrics.
|
|
30
|
-
* @returns {BehavioralEventPayload}
|
|
31
|
-
*/
|
|
32
|
-
private getDefaultTags;
|
|
33
|
-
/**
|
|
34
|
-
* Creates the object to send to our metrics endpoint for a behavioral event
|
|
35
|
-
* @param {MetricEventProduct} product
|
|
36
|
-
* @param {MetricEventAgent} agent
|
|
37
|
-
* @param {string} target
|
|
38
|
-
* @param {MetricEventVerb} verb
|
|
39
|
-
* @returns {BehavioralEventPayload}
|
|
40
|
-
*/
|
|
41
|
-
private createEventObject;
|
|
42
|
-
/**
|
|
43
|
-
* Returns true once we're ready to submit behavioral metrics, after startup.
|
|
44
|
-
* @returns {boolean} true when deviceId is defined and non-empty
|
|
45
|
-
*/
|
|
46
|
-
isReadyToSubmitBehavioralEvents(): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Submit a behavioral metric to our metrics endpoint.
|
|
49
|
-
* @param {MetricEventProduct} product the product from which the metric is being submitted, e.g. 'webex' web client, 'wxcc_desktop'
|
|
50
|
-
* @param {MetricEventAgent} agent the source of the action for this metric
|
|
51
|
-
* @param {string} target the 'thing' that this metric includes information about
|
|
52
|
-
* @param {MetricEventVerb} verb the action that this metric includes information about
|
|
53
|
-
* @param {BehavioralEventPayload} payload information specific to this event. This should be flat, i.e. it should not include nested objects.
|
|
54
|
-
* @returns {Promise<any>}
|
|
55
|
-
*/
|
|
56
|
-
submitBehavioralEvent({ product, agent, target, verb, payload, }: {
|
|
57
|
-
product: MetricEventProduct;
|
|
58
|
-
agent: MetricEventAgent;
|
|
59
|
-
target: string;
|
|
60
|
-
verb: MetricEventVerb;
|
|
61
|
-
payload?: BehavioralEventPayload;
|
|
62
|
-
}): any;
|
|
63
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const BEHAVIORAL_LOG_IDENTIFIER = "behavioral-events -> ";
|