@webex/internal-plugin-metrics 3.0.0-beta.4 → 3.0.0-beta.41
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/README.md +1 -3
- package/dist/batcher.js +3 -22
- package/dist/batcher.js.map +1 -1
- package/dist/call-diagnostic-events-batcher.js +2 -12
- package/dist/call-diagnostic-events-batcher.js.map +1 -1
- package/dist/client-metrics-batcher.js +1 -7
- package/dist/client-metrics-batcher.js.map +1 -1
- package/dist/config.js +21 -5
- package/dist/config.js.map +1 -1
- package/dist/index.js +13 -10
- package/dist/index.js.map +1 -1
- package/dist/metrics.js +22 -54
- package/dist/metrics.js.map +1 -1
- package/package.json +8 -8
- package/src/batcher.js +33 -26
- package/src/call-diagnostic-events-batcher.js +5 -5
- package/src/client-metrics-batcher.js +3 -4
- package/src/config.js +25 -5
- package/src/index.js +2 -2
- package/src/metrics.js +31 -39
- package/test/unit/spec/batcher.js +26 -15
- package/test/unit/spec/call-diagnostic-events-batcher.js +39 -24
- package/test/unit/spec/client-metrics-batcher.js +26 -15
- package/test/unit/spec/metrics.js +22 -21
package/dist/metrics.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","getSparkUserAgent","webex","config","appName","appVersion","appPlatform","sparkUserAgent","CLIENT_NAME","Metrics","WebexPlugin","extend","children","batcher","Batcher","clientMetricsBatcher","ClientMetricsBatcher","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","namespace","submit","key","value","request","submitClientMetrics","eventName","props","preLoginId","Error","payload","metricName","tags","browser","os","domain","window","location","hostname","client_id","credentials","user_id","internal","device","userId","org_id","getOrgId","logger","info","fields","browser_version","os_version","sdk_version","version","platform","spark_user_agent","type","metrics","context","app","locale","name","eventPayload","timestamp","Date","valueOf","_payload","postPreLoginMetric","aliasUser","method","api","resource","headers","body","qs","alias","getClientToken","then","token","authorization","toString","submitCallDiagnosticEvents","event"],"sources":["metrics.js"],"sourcesContent":["/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\nimport {BrowserDetection} from '@webex/common';\
|
|
1
|
+
{"version":3,"names":["BrowserDetection","getOSName","getOSVersion","getBrowserName","getBrowserVersion","getOSNameInternal","OSMap","OS_NAME","OTHERS","getSparkUserAgent","webex","config","appName","appVersion","appPlatform","sparkUserAgent","CLIENT_NAME","Metrics","WebexPlugin","extend","children","batcher","Batcher","clientMetricsBatcher","ClientMetricsBatcher","callDiagnosticEventsBatcher","CallDiagnosticEventsBatcher","namespace","submit","key","value","request","submitClientMetrics","eventName","props","preLoginId","Error","payload","metricName","tags","browser","os","domain","window","location","hostname","client_id","credentials","user_id","internal","device","userId","org_id","getOrgId","logger","info","fields","browser_version","os_version","sdk_version","version","platform","spark_user_agent","type","metrics","context","app","locale","name","eventPayload","timestamp","Date","valueOf","_payload","postPreLoginMetric","aliasUser","method","api","resource","headers","body","qs","alias","getClientToken","then","token","authorization","toString","submitCallDiagnosticEvents","event"],"sources":["metrics.js"],"sourcesContent":["/* eslint-disable default-param-last */\n\n/*!\n * Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.\n */\n\nimport {WebexPlugin} from '@webex/webex-core';\nimport {BrowserDetection} from '@webex/common';\nimport {OS_NAME, OSMap, CLIENT_NAME} from './config';\n\nimport Batcher from './batcher';\nimport ClientMetricsBatcher from './client-metrics-batcher';\nimport CallDiagnosticEventsBatcher from './call-diagnostic-events-batcher';\n\nconst {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\nexport function getOSNameInternal() {\n return OSMap[getOSName()] ?? OS_NAME.OTHERS;\n}\n\nfunction getSparkUserAgent(webex) {\n const {appName, appVersion, appPlatform} = webex?.config ?? {};\n\n let sparkUserAgent = CLIENT_NAME;\n\n if (appName) {\n sparkUserAgent += ` ${appName}/${appVersion ?? '0.0'}`;\n }\n\n if (appPlatform) {\n sparkUserAgent += ` ${appPlatform}`;\n }\n\n return sparkUserAgent;\n}\n\nconst Metrics = WebexPlugin.extend({\n children: {\n batcher: Batcher,\n clientMetricsBatcher: ClientMetricsBatcher,\n callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher,\n },\n\n namespace: 'Metrics',\n\n submit(key, value) {\n return this.batcher.request({key, ...value});\n },\n\n /**\n * This corresponds to #sendSemiStructured() in the deprecated metrics handler\n * @param {string} eventName\n * @param {Object} props\n * @param {string} preLoginId\n * @returns {Object} HttpResponse object\n */\n submitClientMetrics(eventName, props = {}, preLoginId) {\n if (!eventName) {\n throw Error('Missing behavioral metric name. Please provide one');\n }\n const payload = {metricName: eventName};\n\n payload.tags = {\n ...props.tags,\n browser: getBrowserName(),\n os: getOSNameInternal(),\n\n // Node does not like this so we need to check if it exists or not\n // eslint-disable-next-line no-undef\n domain:\n typeof window !== 'undefined' ? window.location.hostname || 'non-browser' : 'non-browser', // Check what else we could measure\n client_id: this.webex.credentials.config.client_id,\n user_id: this.webex.internal.device.userId,\n };\n\n try {\n payload.tags.org_id = this.webex.credentials.getOrgId();\n } catch {\n this.logger.info('metrics: unable to get orgId');\n }\n\n payload.fields = {\n ...props.fields,\n browser_version: getBrowserVersion(),\n os_version: getOSVersion(),\n sdk_version: this.webex.version,\n platform: 'Web',\n spark_user_agent: getSparkUserAgent(this.webex),\n };\n\n payload.type = props.type || this.webex.config.metrics.type;\n\n payload.context = {\n ...props.context,\n app: {\n version: this.webex.version,\n },\n locale: 'en-US',\n os: {\n name: getOSNameInternal(),\n version: getOSVersion(),\n },\n };\n\n if (props.eventPayload) {\n payload.eventPayload = props.eventPayload;\n }\n\n // Mocking the time in tests when running in node\n // is impossible so unable to use Date.now()\n payload.timestamp = new Date().valueOf();\n\n if (preLoginId) {\n const _payload = {\n metrics: [payload],\n };\n\n // Do not batch these because pre-login events occur during onboarding, so we will be partially blind\n // to users' progress through the reg flow if we wait to persist pre-login metrics for people who drop off because\n // their metrics will not post from a queue flush in time\n return this.postPreLoginMetric(_payload, preLoginId);\n }\n\n return this.clientMetricsBatcher.request(payload);\n },\n\n /**\n * Issue request to alias a user's pre-login ID with their CI UUID\n * @param {string} preLoginId\n * @returns {Object} HttpResponse object\n */\n aliasUser(preLoginId) {\n return this.request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics',\n headers: {\n 'x-prelogin-userid': preLoginId,\n },\n body: {},\n qs: {\n alias: true,\n },\n });\n },\n\n postPreLoginMetric(payload, preLoginId) {\n return this.webex.credentials.getClientToken().then((token) =>\n this.request({\n method: 'POST',\n api: 'metrics',\n resource: 'clientmetrics-prelogin',\n headers: {\n authorization: token.toString(),\n 'x-prelogin-userid': preLoginId,\n },\n body: payload,\n })\n );\n },\n\n submitCallDiagnosticEvents(payload) {\n const event = {\n type: 'diagnostic-event',\n eventPayload: payload,\n };\n\n return this.callDiagnosticEventsBatcher.request(event);\n },\n});\n\nexport default Metrics;\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webex/internal-plugin-metrics",
|
|
3
|
-
"version": "3.0.0-beta.
|
|
3
|
+
"version": "3.0.0-beta.41",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,12 +24,12 @@
|
|
|
24
24
|
"sinon": "^9.2.4"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@webex/common": "3.0.0-beta.
|
|
28
|
-
"@webex/common-timers": "3.0.0-beta.
|
|
29
|
-
"@webex/internal-plugin-device": "3.0.0-beta.
|
|
30
|
-
"@webex/internal-plugin-metrics": "3.0.0-beta.
|
|
31
|
-
"@webex/test-helper-chai": "3.0.0-beta.
|
|
32
|
-
"@webex/test-helper-mock-webex": "3.0.0-beta.
|
|
33
|
-
"@webex/webex-core": "3.0.0-beta.
|
|
27
|
+
"@webex/common": "3.0.0-beta.41",
|
|
28
|
+
"@webex/common-timers": "3.0.0-beta.41",
|
|
29
|
+
"@webex/internal-plugin-device": "3.0.0-beta.41",
|
|
30
|
+
"@webex/internal-plugin-metrics": "3.0.0-beta.41",
|
|
31
|
+
"@webex/test-helper-chai": "3.0.0-beta.41",
|
|
32
|
+
"@webex/test-helper-mock-webex": "3.0.0-beta.41",
|
|
33
|
+
"@webex/webex-core": "3.0.0-beta.41"
|
|
34
34
|
}
|
|
35
35
|
}
|
package/src/batcher.js
CHANGED
|
@@ -23,11 +23,13 @@ const MetricsBatcher = Batcher.extend({
|
|
|
23
23
|
},
|
|
24
24
|
|
|
25
25
|
prepareRequest(queue) {
|
|
26
|
-
return Promise.resolve(
|
|
27
|
-
|
|
26
|
+
return Promise.resolve(
|
|
27
|
+
queue.map((item) => {
|
|
28
|
+
item.postTime = item.postTime || Date.now();
|
|
28
29
|
|
|
29
|
-
|
|
30
|
-
|
|
30
|
+
return item;
|
|
31
|
+
})
|
|
32
|
+
);
|
|
31
33
|
},
|
|
32
34
|
|
|
33
35
|
submitHttpRequest(payload) {
|
|
@@ -36,8 +38,8 @@ const MetricsBatcher = Batcher.extend({
|
|
|
36
38
|
service: 'metrics',
|
|
37
39
|
resource: 'metrics',
|
|
38
40
|
body: {
|
|
39
|
-
metrics: payload
|
|
40
|
-
}
|
|
41
|
+
metrics: payload,
|
|
42
|
+
},
|
|
41
43
|
});
|
|
42
44
|
},
|
|
43
45
|
|
|
@@ -47,38 +49,43 @@ const MetricsBatcher = Batcher.extend({
|
|
|
47
49
|
|
|
48
50
|
handleHttpError(reason) {
|
|
49
51
|
if (reason instanceof WebexHttpError.NetworkOrCORSError) {
|
|
50
|
-
this.logger.warn(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
item
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
52
|
+
this.logger.warn(
|
|
53
|
+
'metrics-batcher: received network error submitting metrics, reenqueuing payload'
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
return Promise.all(
|
|
57
|
+
reason.options.body.metrics.map(
|
|
58
|
+
(item) =>
|
|
59
|
+
new Promise((resolve) => {
|
|
60
|
+
const delay = item[sym].nextDelay;
|
|
61
|
+
|
|
62
|
+
if (delay < this.config.batcherRetryPlateau) {
|
|
63
|
+
item[sym].nextDelay *= 2;
|
|
64
|
+
}
|
|
65
|
+
safeSetTimeout(() => {
|
|
66
|
+
resolve(this.rerequest(item));
|
|
67
|
+
}, delay);
|
|
68
|
+
})
|
|
69
|
+
)
|
|
70
|
+
);
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
return Reflect.apply(Batcher.prototype.handleHttpError, this, [reason]);
|
|
65
74
|
},
|
|
66
75
|
|
|
67
76
|
rerequest(item) {
|
|
68
|
-
return Promise.all([
|
|
69
|
-
|
|
70
|
-
this.prepareItem(item)
|
|
71
|
-
])
|
|
72
|
-
.then(([defer, req]) => {
|
|
77
|
+
return Promise.all([this.getDeferredForRequest(item), this.prepareItem(item)]).then(
|
|
78
|
+
([defer, req]) => {
|
|
73
79
|
this.enqueue(req)
|
|
74
80
|
.then(() => this.bounce())
|
|
75
81
|
.catch((reason) => defer.reject(reason));
|
|
76
|
-
}
|
|
82
|
+
}
|
|
83
|
+
);
|
|
77
84
|
},
|
|
78
85
|
|
|
79
86
|
fingerprintRequest(item) {
|
|
80
87
|
item[sym] = item[sym] || {
|
|
81
|
-
nextDelay: 1000
|
|
88
|
+
nextDelay: 1000,
|
|
82
89
|
};
|
|
83
90
|
|
|
84
91
|
return Promise.resolve(item[sym]);
|
|
@@ -86,7 +93,7 @@ const MetricsBatcher = Batcher.extend({
|
|
|
86
93
|
|
|
87
94
|
fingerprintResponse(item) {
|
|
88
95
|
return Promise.resolve(item[sym]);
|
|
89
|
-
}
|
|
96
|
+
},
|
|
90
97
|
});
|
|
91
98
|
|
|
92
99
|
export default MetricsBatcher;
|
|
@@ -10,7 +10,7 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
|
|
|
10
10
|
/**
|
|
11
11
|
* @param {string} webClientDomain
|
|
12
12
|
* @returns {string}
|
|
13
|
-
|
|
13
|
+
*/
|
|
14
14
|
getBuildType(webClientDomain) {
|
|
15
15
|
if (
|
|
16
16
|
webClientDomain?.includes('teams.webex.com') ||
|
|
@@ -29,7 +29,7 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
|
|
|
29
29
|
// Browsers cannot provide such information right now. However, it is a required field.
|
|
30
30
|
const origin = {
|
|
31
31
|
buildType: this.getBuildType(item.event?.eventData?.webClientDomain),
|
|
32
|
-
networkType: 'unknown'
|
|
32
|
+
networkType: 'unknown',
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
item.eventPayload.origin = Object.assign(origin, item.eventPayload.origin);
|
|
@@ -53,10 +53,10 @@ const CallDiagnosticEventsBatcher = Batcher.extend({
|
|
|
53
53
|
service: 'metrics',
|
|
54
54
|
resource: 'clientmetrics',
|
|
55
55
|
body: {
|
|
56
|
-
metrics: payload
|
|
57
|
-
}
|
|
56
|
+
metrics: payload,
|
|
57
|
+
},
|
|
58
58
|
});
|
|
59
|
-
}
|
|
59
|
+
},
|
|
60
60
|
});
|
|
61
61
|
|
|
62
62
|
export default CallDiagnosticEventsBatcher;
|
package/src/config.js
CHANGED
|
@@ -8,15 +8,35 @@ export const CLIENT_NAME = 'webex-js-sdk';
|
|
|
8
8
|
export default {
|
|
9
9
|
device: {
|
|
10
10
|
preDiscoveryServices: {
|
|
11
|
-
metricsServiceUrl:
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
metricsServiceUrl:
|
|
12
|
+
process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',
|
|
13
|
+
metrics: process.env.METRICS_SERVICE_URL || 'https://metrics-a.wbx2.com/metrics/api/v1',
|
|
14
|
+
},
|
|
14
15
|
},
|
|
15
16
|
metrics: {
|
|
16
17
|
appType: inBrowser ? 'browser' : 'nodejs',
|
|
17
18
|
batcherWait: 500,
|
|
18
19
|
batcherMaxCalls: 50,
|
|
19
20
|
batcherMaxWait: 1500,
|
|
20
|
-
batcherRetryPlateau: 32000
|
|
21
|
-
}
|
|
21
|
+
batcherRetryPlateau: 32000,
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const OS_NAME = {
|
|
26
|
+
WINDOWS: 'windows',
|
|
27
|
+
MAC: 'mac',
|
|
28
|
+
IOS: 'ios',
|
|
29
|
+
ANDROID: 'android',
|
|
30
|
+
CHROME: 'chrome',
|
|
31
|
+
LINUX: 'linux',
|
|
32
|
+
OTHERS: 'other',
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const OSMap = {
|
|
36
|
+
'Chrome OS': OS_NAME.CHROME,
|
|
37
|
+
macOS: OS_NAME.MAC,
|
|
38
|
+
Windows: OS_NAME.WINDOWS,
|
|
39
|
+
iOS: OS_NAME.IOS,
|
|
40
|
+
Android: OS_NAME.ANDROID,
|
|
41
|
+
Linux: OS_NAME.LINUX,
|
|
22
42
|
};
|
package/src/index.js
CHANGED
|
@@ -10,8 +10,8 @@ import Metrics from './metrics';
|
|
|
10
10
|
import config from './config';
|
|
11
11
|
|
|
12
12
|
registerInternalPlugin('metrics', Metrics, {
|
|
13
|
-
config
|
|
13
|
+
config,
|
|
14
14
|
});
|
|
15
15
|
|
|
16
|
-
export {default} from './metrics';
|
|
16
|
+
export {default, getOSNameInternal} from './metrics';
|
|
17
17
|
export {config};
|
package/src/metrics.js
CHANGED
|
@@ -1,28 +1,25 @@
|
|
|
1
|
+
/* eslint-disable default-param-last */
|
|
2
|
+
|
|
1
3
|
/*!
|
|
2
4
|
* Copyright (c) 2015-2020 Cisco Systems, Inc. See LICENSE file.
|
|
3
5
|
*/
|
|
4
6
|
|
|
5
7
|
import {WebexPlugin} from '@webex/webex-core';
|
|
6
8
|
import {BrowserDetection} from '@webex/common';
|
|
9
|
+
import {OS_NAME, OSMap, CLIENT_NAME} from './config';
|
|
7
10
|
|
|
8
|
-
import {CLIENT_NAME} from './config';
|
|
9
11
|
import Batcher from './batcher';
|
|
10
12
|
import ClientMetricsBatcher from './client-metrics-batcher';
|
|
11
13
|
import CallDiagnosticEventsBatcher from './call-diagnostic-events-batcher';
|
|
12
14
|
|
|
13
|
-
const {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} = BrowserDetection();
|
|
15
|
+
const {getOSName, getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
|
|
16
|
+
|
|
17
|
+
export function getOSNameInternal() {
|
|
18
|
+
return OSMap[getOSName()] ?? OS_NAME.OTHERS;
|
|
19
|
+
}
|
|
19
20
|
|
|
20
21
|
function getSparkUserAgent(webex) {
|
|
21
|
-
const {
|
|
22
|
-
appName,
|
|
23
|
-
appVersion,
|
|
24
|
-
appPlatform
|
|
25
|
-
} = webex?.config ?? {};
|
|
22
|
+
const {appName, appVersion, appPlatform} = webex?.config ?? {};
|
|
26
23
|
|
|
27
24
|
let sparkUserAgent = CLIENT_NAME;
|
|
28
25
|
|
|
@@ -37,21 +34,19 @@ function getSparkUserAgent(webex) {
|
|
|
37
34
|
return sparkUserAgent;
|
|
38
35
|
}
|
|
39
36
|
|
|
40
|
-
|
|
41
37
|
const Metrics = WebexPlugin.extend({
|
|
42
38
|
children: {
|
|
43
39
|
batcher: Batcher,
|
|
44
40
|
clientMetricsBatcher: ClientMetricsBatcher,
|
|
45
|
-
callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher
|
|
41
|
+
callDiagnosticEventsBatcher: CallDiagnosticEventsBatcher,
|
|
46
42
|
},
|
|
47
43
|
|
|
48
44
|
namespace: 'Metrics',
|
|
49
45
|
|
|
50
46
|
submit(key, value) {
|
|
51
|
-
return this.batcher.request(
|
|
47
|
+
return this.batcher.request({key, ...value});
|
|
52
48
|
},
|
|
53
49
|
|
|
54
|
-
|
|
55
50
|
/**
|
|
56
51
|
* This corresponds to #sendSemiStructured() in the deprecated metrics handler
|
|
57
52
|
* @param {string} eventName
|
|
@@ -68,49 +63,45 @@ const Metrics = WebexPlugin.extend({
|
|
|
68
63
|
payload.tags = {
|
|
69
64
|
...props.tags,
|
|
70
65
|
browser: getBrowserName(),
|
|
71
|
-
os:
|
|
66
|
+
os: getOSNameInternal(),
|
|
72
67
|
|
|
73
68
|
// Node does not like this so we need to check if it exists or not
|
|
74
69
|
// eslint-disable-next-line no-undef
|
|
75
|
-
domain:
|
|
70
|
+
domain:
|
|
71
|
+
typeof window !== 'undefined' ? window.location.hostname || 'non-browser' : 'non-browser', // Check what else we could measure
|
|
76
72
|
client_id: this.webex.credentials.config.client_id,
|
|
77
|
-
user_id: this.webex.internal.device.userId
|
|
73
|
+
user_id: this.webex.internal.device.userId,
|
|
78
74
|
};
|
|
79
75
|
|
|
80
76
|
try {
|
|
81
77
|
payload.tags.org_id = this.webex.credentials.getOrgId();
|
|
82
|
-
}
|
|
83
|
-
catch {
|
|
78
|
+
} catch {
|
|
84
79
|
this.logger.info('metrics: unable to get orgId');
|
|
85
80
|
}
|
|
86
81
|
|
|
87
|
-
|
|
88
82
|
payload.fields = {
|
|
89
83
|
...props.fields,
|
|
90
84
|
browser_version: getBrowserVersion(),
|
|
91
85
|
os_version: getOSVersion(),
|
|
92
86
|
sdk_version: this.webex.version,
|
|
93
87
|
platform: 'Web',
|
|
94
|
-
spark_user_agent: getSparkUserAgent(this.webex)
|
|
88
|
+
spark_user_agent: getSparkUserAgent(this.webex),
|
|
95
89
|
};
|
|
96
90
|
|
|
97
|
-
|
|
98
91
|
payload.type = props.type || this.webex.config.metrics.type;
|
|
99
92
|
|
|
100
|
-
|
|
101
93
|
payload.context = {
|
|
102
94
|
...props.context,
|
|
103
95
|
app: {
|
|
104
|
-
version: this.webex.version
|
|
96
|
+
version: this.webex.version,
|
|
105
97
|
},
|
|
106
98
|
locale: 'en-US',
|
|
107
99
|
os: {
|
|
108
|
-
name:
|
|
109
|
-
version: getOSVersion()
|
|
110
|
-
}
|
|
100
|
+
name: getOSNameInternal(),
|
|
101
|
+
version: getOSVersion(),
|
|
102
|
+
},
|
|
111
103
|
};
|
|
112
104
|
|
|
113
|
-
|
|
114
105
|
if (props.eventPayload) {
|
|
115
106
|
payload.eventPayload = props.eventPayload;
|
|
116
107
|
}
|
|
@@ -121,7 +112,7 @@ const Metrics = WebexPlugin.extend({
|
|
|
121
112
|
|
|
122
113
|
if (preLoginId) {
|
|
123
114
|
const _payload = {
|
|
124
|
-
metrics: [payload]
|
|
115
|
+
metrics: [payload],
|
|
125
116
|
};
|
|
126
117
|
|
|
127
118
|
// Do not batch these because pre-login events occur during onboarding, so we will be partially blind
|
|
@@ -144,12 +135,12 @@ const Metrics = WebexPlugin.extend({
|
|
|
144
135
|
api: 'metrics',
|
|
145
136
|
resource: 'clientmetrics',
|
|
146
137
|
headers: {
|
|
147
|
-
'x-prelogin-userid': preLoginId
|
|
138
|
+
'x-prelogin-userid': preLoginId,
|
|
148
139
|
},
|
|
149
140
|
body: {},
|
|
150
141
|
qs: {
|
|
151
|
-
alias: true
|
|
152
|
-
}
|
|
142
|
+
alias: true,
|
|
143
|
+
},
|
|
153
144
|
});
|
|
154
145
|
},
|
|
155
146
|
|
|
@@ -161,20 +152,21 @@ const Metrics = WebexPlugin.extend({
|
|
|
161
152
|
resource: 'clientmetrics-prelogin',
|
|
162
153
|
headers: {
|
|
163
154
|
authorization: token.toString(),
|
|
164
|
-
'x-prelogin-userid': preLoginId
|
|
155
|
+
'x-prelogin-userid': preLoginId,
|
|
165
156
|
},
|
|
166
|
-
body: payload
|
|
167
|
-
})
|
|
157
|
+
body: payload,
|
|
158
|
+
})
|
|
159
|
+
);
|
|
168
160
|
},
|
|
169
161
|
|
|
170
162
|
submitCallDiagnosticEvents(payload) {
|
|
171
163
|
const event = {
|
|
172
164
|
type: 'diagnostic-event',
|
|
173
|
-
eventPayload: payload
|
|
165
|
+
eventPayload: payload,
|
|
174
166
|
};
|
|
175
167
|
|
|
176
168
|
return this.callDiagnosticEventsBatcher.request(event);
|
|
177
|
-
}
|
|
169
|
+
},
|
|
178
170
|
});
|
|
179
171
|
|
|
180
172
|
export default Metrics;
|
|
@@ -27,8 +27,8 @@ describe('plugin-metrics', () => {
|
|
|
27
27
|
beforeEach(() => {
|
|
28
28
|
webex = new MockWebex({
|
|
29
29
|
children: {
|
|
30
|
-
metrics: Metrics
|
|
31
|
-
}
|
|
30
|
+
metrics: Metrics,
|
|
31
|
+
},
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
webex.config.metrics = config.metrics;
|
|
@@ -37,7 +37,7 @@ describe('plugin-metrics', () => {
|
|
|
37
37
|
return Promise.resolve({
|
|
38
38
|
statusCode: 204,
|
|
39
39
|
body: undefined,
|
|
40
|
-
options
|
|
40
|
+
options,
|
|
41
41
|
});
|
|
42
42
|
};
|
|
43
43
|
sinon.spy(webex, 'request');
|
|
@@ -58,9 +58,10 @@ describe('plugin-metrics', () => {
|
|
|
58
58
|
it('clears the queue', () => {
|
|
59
59
|
clock.uninstall();
|
|
60
60
|
|
|
61
|
-
return webex.internal.metrics.batcher
|
|
62
|
-
|
|
63
|
-
|
|
61
|
+
return webex.internal.metrics.batcher
|
|
62
|
+
.request({
|
|
63
|
+
key: 'testMetric',
|
|
64
|
+
})
|
|
64
65
|
.then(() => {
|
|
65
66
|
assert.calledOnce(webex.request);
|
|
66
67
|
assert.lengthOf(webex.internal.metrics.batcher.queue, 0);
|
|
@@ -80,26 +81,28 @@ describe('plugin-metrics', () => {
|
|
|
80
81
|
|
|
81
82
|
sinon.stub(webex, 'request').callsFake((options) => {
|
|
82
83
|
options.headers = {
|
|
83
|
-
trackingid: count
|
|
84
|
+
trackingid: count,
|
|
84
85
|
};
|
|
85
86
|
|
|
86
87
|
count += 1;
|
|
87
88
|
if (count < 9) {
|
|
88
|
-
return Promise.reject(
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
return Promise.reject(
|
|
90
|
+
new WebexHttpError.NetworkOrCORSError({
|
|
91
|
+
statusCode: 0,
|
|
92
|
+
options,
|
|
93
|
+
})
|
|
94
|
+
);
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
return Promise.resolve({
|
|
95
98
|
statusCode: 204,
|
|
96
99
|
body: undefined,
|
|
97
|
-
options
|
|
100
|
+
options,
|
|
98
101
|
});
|
|
99
102
|
});
|
|
100
103
|
|
|
101
104
|
const promise = webex.internal.metrics.batcher.request({
|
|
102
|
-
key: 'testMetric'
|
|
105
|
+
key: 'testMetric',
|
|
103
106
|
});
|
|
104
107
|
|
|
105
108
|
return promiseTick(50)
|
|
@@ -159,8 +162,16 @@ describe('plugin-metrics', () => {
|
|
|
159
162
|
.then(() => assert.lengthOf(webex.internal.metrics.batcher.queue, 0))
|
|
160
163
|
.then(() => promise)
|
|
161
164
|
.then(() => {
|
|
162
|
-
assert.lengthOf(
|
|
163
|
-
|
|
165
|
+
assert.lengthOf(
|
|
166
|
+
webex.request.args[1][0].body.metrics,
|
|
167
|
+
1,
|
|
168
|
+
'Reenqueuing the metric once did not increase the number of metrics to be submitted'
|
|
169
|
+
);
|
|
170
|
+
assert.lengthOf(
|
|
171
|
+
webex.request.args[2][0].body.metrics,
|
|
172
|
+
1,
|
|
173
|
+
'Reenqueuing the metric twice did not increase the number of metrics to be submitted'
|
|
174
|
+
);
|
|
164
175
|
assert.lengthOf(webex.internal.metrics.batcher.queue, 0);
|
|
165
176
|
});
|
|
166
177
|
});
|