@webex/internal-plugin-metrics 3.12.0-next.9 → 3.12.0-webex-services-ready.1
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/batcher.js +3 -0
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js +23 -0
- package/dist/call-diagnostic/call-diagnostic-metrics-batcher.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js +29 -25
- package/dist/call-diagnostic/call-diagnostic-metrics-latencies.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.js +55 -8
- package/dist/call-diagnostic/call-diagnostic-metrics.js.map +1 -1
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js +5 -0
- package/dist/call-diagnostic/call-diagnostic-metrics.util.js.map +1 -1
- package/dist/call-diagnostic/config.js +14 -2
- package/dist/call-diagnostic/config.js.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/metrics.js +1 -1
- package/dist/metrics.types.js.map +1 -1
- package/dist/prelogin-metrics-batcher.js +23 -0
- package/dist/prelogin-metrics-batcher.js.map +1 -1
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +23 -0
- package/dist/types/call-diagnostic/config.d.ts +4 -0
- package/dist/types/config.d.ts +1 -0
- package/dist/types/metrics.types.d.ts +2 -2
- package/package.json +11 -11
- package/src/batcher.js +4 -0
- package/src/call-diagnostic/call-diagnostic-metrics-batcher.ts +26 -0
- package/src/call-diagnostic/call-diagnostic-metrics-latencies.ts +54 -38
- package/src/call-diagnostic/call-diagnostic-metrics.ts +46 -1
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +5 -0
- package/src/call-diagnostic/config.ts +13 -0
- package/src/config.js +1 -0
- package/src/metrics.types.ts +1 -1
- package/src/prelogin-metrics-batcher.ts +26 -0
- package/test/unit/spec/batcher.js +43 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-batcher.ts +145 -0
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics-latencies.ts +105 -95
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +680 -159
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +27 -0
- package/test/unit/spec/prelogin-metrics-batcher.ts +190 -36
|
@@ -78,6 +78,8 @@ const PreLoginMetricsBatcher = Batcher.extend({
|
|
|
78
78
|
`PreLoginMetricsBatcher: @submitHttpRequest#${batchId}. Request successful.`
|
|
79
79
|
);
|
|
80
80
|
|
|
81
|
+
this.handleHttpResponseStatus(res?.statusCode, payload);
|
|
82
|
+
|
|
81
83
|
return res;
|
|
82
84
|
})
|
|
83
85
|
.catch((err) => {
|
|
@@ -87,9 +89,33 @@ const PreLoginMetricsBatcher = Batcher.extend({
|
|
|
87
89
|
`error: ${generateCommonErrorMetadata(err)}`
|
|
88
90
|
);
|
|
89
91
|
|
|
92
|
+
this.handleHttpResponseStatus(err?.statusCode, payload);
|
|
93
|
+
|
|
90
94
|
return Promise.reject(err);
|
|
91
95
|
});
|
|
92
96
|
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* React to the HTTP status code returned by the prelogin metrics endpoint.
|
|
100
|
+
* Only items submitted with `markTelemetryOptOutOnResponse: true` opt into
|
|
101
|
+
* this behavior.
|
|
102
|
+
* @param {number | undefined} statusCode
|
|
103
|
+
* @param {any[]} payload Items flushed in this HTTP batch.
|
|
104
|
+
* @returns {void}
|
|
105
|
+
*/
|
|
106
|
+
handleHttpResponseStatus(statusCode: number | undefined, payload: any[]) {
|
|
107
|
+
const shouldMark =
|
|
108
|
+
Array.isArray(payload) &&
|
|
109
|
+
payload.some((item) => item?.markTelemetryOptOutOnResponse === true);
|
|
110
|
+
|
|
111
|
+
if (!shouldMark) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (statusCode === 200) {
|
|
116
|
+
this.webex.internal.newMetrics?.callDiagnosticMetrics?.setIsTelemetryOptOutAutomatic(true);
|
|
117
|
+
}
|
|
118
|
+
},
|
|
93
119
|
});
|
|
94
120
|
|
|
95
121
|
export default PreLoginMetricsBatcher;
|
|
@@ -177,6 +177,49 @@ describe('plugin-metrics', () => {
|
|
|
177
177
|
assert.lengthOf(webex.internal.metrics.batcher.queue, 0);
|
|
178
178
|
});
|
|
179
179
|
});
|
|
180
|
+
|
|
181
|
+
it('rejects the deferred without reenqueuing when batcherRetryOnNetworkError is false', () => {
|
|
182
|
+
webex.config.metrics = {...config.metrics, batcherRetryOnNetworkError: false};
|
|
183
|
+
|
|
184
|
+
webex.request = function () {
|
|
185
|
+
// noop
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
sinon.stub(webex, 'request').callsFake((options) => {
|
|
189
|
+
options.headers = {
|
|
190
|
+
trackingid: 'test-no-retry',
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
return Promise.reject(
|
|
194
|
+
new WebexHttpError.NetworkOrCORSError({
|
|
195
|
+
statusCode: 0,
|
|
196
|
+
options,
|
|
197
|
+
})
|
|
198
|
+
);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
const promise = webex.internal.metrics.batcher.request({
|
|
202
|
+
key: 'testMetric',
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
return promiseTick(50)
|
|
206
|
+
.then(() => assert.lengthOf(webex.internal.metrics.batcher.queue, 1))
|
|
207
|
+
.then(() => clock.tick(config.metrics.batcherWait))
|
|
208
|
+
.then(() => assert.calledOnce(webex.request))
|
|
209
|
+
.then(() => promiseTick(50))
|
|
210
|
+
.then(() =>
|
|
211
|
+
promise.then(
|
|
212
|
+
() => {
|
|
213
|
+
assert.fail('promise should have been rejected');
|
|
214
|
+
},
|
|
215
|
+
(reason) => {
|
|
216
|
+
assert.instanceOf(reason, WebexHttpError.NetworkOrCORSError);
|
|
217
|
+
assert.lengthOf(webex.internal.metrics.batcher.queue, 0);
|
|
218
|
+
assert.calledOnce(webex.request);
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
);
|
|
222
|
+
});
|
|
180
223
|
});
|
|
181
224
|
});
|
|
182
225
|
});
|
|
@@ -192,6 +192,12 @@ describe('plugin-metrics', () => {
|
|
|
192
192
|
webex.internal.newMetrics.callDiagnosticLatencies.getTotalJMTWithUserDelay = sinon
|
|
193
193
|
.stub()
|
|
194
194
|
.returns(64);
|
|
195
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getInterstitialToJoinOK = sinon
|
|
196
|
+
.stub()
|
|
197
|
+
.returns(10);
|
|
198
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getTotalJMT = sinon
|
|
199
|
+
.stub()
|
|
200
|
+
.returns(20);
|
|
195
201
|
const promise = webex.internal.newMetrics.callDiagnosticMetrics.submitToCallDiagnostics(
|
|
196
202
|
//@ts-ignore
|
|
197
203
|
{event: {name: 'client.locus.join.response'}}
|
|
@@ -349,6 +355,9 @@ describe('plugin-metrics', () => {
|
|
|
349
355
|
webex.internal.newMetrics.callDiagnosticLatencies.getStayLobbyTimeCappedBy = sinon
|
|
350
356
|
.stub()
|
|
351
357
|
.returns(1);
|
|
358
|
+
webex.internal.newMetrics.callDiagnosticLatencies.getTotalMediaJMT = sinon
|
|
359
|
+
.stub()
|
|
360
|
+
.returns(44);
|
|
352
361
|
webex.internal.newMetrics.callDiagnosticLatencies.getTotalMediaJMTWithUserDelay = sinon
|
|
353
362
|
.stub()
|
|
354
363
|
.returns(43);
|
|
@@ -507,5 +516,141 @@ describe('plugin-metrics', () => {
|
|
|
507
516
|
assert.deepEqual(prepareDiagnosticMetricItemCalls[0].args[1].type, ['diagnostic-event']);
|
|
508
517
|
});
|
|
509
518
|
});
|
|
519
|
+
|
|
520
|
+
describe('#submitHttpRequest', () => {
|
|
521
|
+
it('calls handleHttpResponseStatus with response status on success', async () => {
|
|
522
|
+
const payload = [
|
|
523
|
+
{
|
|
524
|
+
eventPayload: {event: 'my.event'},
|
|
525
|
+
type: ['diagnostic-event'],
|
|
526
|
+
},
|
|
527
|
+
];
|
|
528
|
+
|
|
529
|
+
webex.request = sinon.stub().resolves({statusCode: 200});
|
|
530
|
+
|
|
531
|
+
const handleHttpResponseStatusSpy = sinon.spy(
|
|
532
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher,
|
|
533
|
+
'handleHttpResponseStatus'
|
|
534
|
+
);
|
|
535
|
+
|
|
536
|
+
const promise =
|
|
537
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.submitHttpRequest(
|
|
538
|
+
payload
|
|
539
|
+
);
|
|
540
|
+
|
|
541
|
+
assert.deepEqual(handleHttpResponseStatusSpy.getCalls().length, 0);
|
|
542
|
+
|
|
543
|
+
await flushPromises();
|
|
544
|
+
clock.tick(config.metrics.batcherWait);
|
|
545
|
+
|
|
546
|
+
await promise;
|
|
547
|
+
|
|
548
|
+
assert.calledOnce(webex.request);
|
|
549
|
+
assert.deepEqual(handleHttpResponseStatusSpy.getCalls().length, 1);
|
|
550
|
+
assert.deepEqual(handleHttpResponseStatusSpy.args[0][0], 200);
|
|
551
|
+
assert.deepEqual(handleHttpResponseStatusSpy.args[0][1], payload);
|
|
552
|
+
});
|
|
553
|
+
|
|
554
|
+
it('calls handleHttpResponseStatus with error status on failure', async () => {
|
|
555
|
+
const payload = [
|
|
556
|
+
{
|
|
557
|
+
eventPayload: {event: 'my.event'},
|
|
558
|
+
type: ['diagnostic-event'],
|
|
559
|
+
},
|
|
560
|
+
];
|
|
561
|
+
|
|
562
|
+
webex.request = sinon.stub().rejects({statusCode: 503});
|
|
563
|
+
|
|
564
|
+
const handleHttpResponseStatusSpy = sinon.spy(
|
|
565
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher,
|
|
566
|
+
'handleHttpResponseStatus'
|
|
567
|
+
);
|
|
568
|
+
|
|
569
|
+
const promise =
|
|
570
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.submitHttpRequest(
|
|
571
|
+
payload
|
|
572
|
+
);
|
|
573
|
+
|
|
574
|
+
assert.deepEqual(handleHttpResponseStatusSpy.getCalls().length, 0);
|
|
575
|
+
|
|
576
|
+
await flushPromises();
|
|
577
|
+
clock.tick(config.metrics.batcherWait);
|
|
578
|
+
|
|
579
|
+
let error: any;
|
|
580
|
+
|
|
581
|
+
try {
|
|
582
|
+
await promise;
|
|
583
|
+
} catch (err) {
|
|
584
|
+
error = err;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
assert.deepEqual(error.statusCode, 503);
|
|
588
|
+
assert.calledOnce(webex.request);
|
|
589
|
+
assert.deepEqual(handleHttpResponseStatusSpy.getCalls().length, 1);
|
|
590
|
+
assert.deepEqual(handleHttpResponseStatusSpy.args[0][0], 503);
|
|
591
|
+
assert.deepEqual(handleHttpResponseStatusSpy.args[0][1], payload);
|
|
592
|
+
});
|
|
593
|
+
});
|
|
594
|
+
|
|
595
|
+
describe('#handleHttpResponseStatus', () => {
|
|
596
|
+
let setIsTelemetryOptOutAutomaticStub;
|
|
597
|
+
|
|
598
|
+
beforeEach(() => {
|
|
599
|
+
setIsTelemetryOptOutAutomaticStub = sinon.stub(
|
|
600
|
+
webex.internal.newMetrics.callDiagnosticMetrics,
|
|
601
|
+
'setIsTelemetryOptOutAutomatic'
|
|
602
|
+
);
|
|
603
|
+
});
|
|
604
|
+
|
|
605
|
+
[201, 400, 503, undefined].forEach((statusCode) => {
|
|
606
|
+
it(`does not call setIsTelemetryOptOutAutomatic() when statusCode is ${statusCode} and markTelemetryOptOutOnResponse is true`, () => {
|
|
607
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.handleHttpResponseStatus(
|
|
608
|
+
statusCode,
|
|
609
|
+
[{markTelemetryOptOutOnResponse: true}]
|
|
610
|
+
);
|
|
611
|
+
|
|
612
|
+
assert.notCalled(setIsTelemetryOptOutAutomaticStub);
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
it('calls setIsTelemetryOptOutAutomatic(true) when statusCode is 200 and markTelemetryOptOutOnResponse is true', () => {
|
|
617
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.handleHttpResponseStatus(
|
|
618
|
+
200,
|
|
619
|
+
[{markTelemetryOptOutOnResponse: true}]
|
|
620
|
+
);
|
|
621
|
+
|
|
622
|
+
assert.calledOnce(setIsTelemetryOptOutAutomaticStub);
|
|
623
|
+
assert.calledWithExactly(setIsTelemetryOptOutAutomaticStub, true);
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
[200, 201, 400, 503, undefined].forEach((statusCode) => {
|
|
627
|
+
it(`does not call setIsTelemetryOptOutAutomatic when shouldMark is false (statusCode: ${statusCode})`, () => {
|
|
628
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.handleHttpResponseStatus(
|
|
629
|
+
statusCode,
|
|
630
|
+
[{markTelemetryOptOutOnResponse: false}]
|
|
631
|
+
);
|
|
632
|
+
|
|
633
|
+
assert.notCalled(setIsTelemetryOptOutAutomaticStub);
|
|
634
|
+
});
|
|
635
|
+
});
|
|
636
|
+
|
|
637
|
+
it('does not call setIsTelemetryOptOutAutomatic when payload is empty', () => {
|
|
638
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.handleHttpResponseStatus(
|
|
639
|
+
200,
|
|
640
|
+
[]
|
|
641
|
+
);
|
|
642
|
+
|
|
643
|
+
assert.notCalled(setIsTelemetryOptOutAutomaticStub);
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
it('does not call setIsTelemetryOptOutAutomatic when payload is not an array', () => {
|
|
647
|
+
webex.internal.newMetrics.callDiagnosticMetrics.callDiagnosticEventsBatcher.handleHttpResponseStatus(
|
|
648
|
+
200,
|
|
649
|
+
null
|
|
650
|
+
);
|
|
651
|
+
|
|
652
|
+
assert.notCalled(setIsTelemetryOptOutAutomaticStub);
|
|
653
|
+
});
|
|
654
|
+
});
|
|
510
655
|
});
|
|
511
656
|
});
|