@webex/internal-plugin-metrics 3.4.0-next.1 → 3.4.0-next.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.
- package/dist/behavioral-metrics.js +63 -0
- package/dist/behavioral-metrics.js.map +1 -0
- package/dist/business-metrics.js +62 -0
- package/dist/business-metrics.js.map +1 -0
- package/dist/{behavioral/behavioral-metrics.js → generic-metrics.js} +77 -92
- package/dist/generic-metrics.js.map +1 -0
- package/dist/index.js +15 -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 +92 -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/types/behavioral-metrics.d.ts +25 -0
- package/dist/types/business-metrics.d.ts +19 -0
- package/dist/types/call-diagnostic/call-diagnostic-metrics.d.ts +2 -2
- package/dist/types/generic-metrics.d.ts +63 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/metrics.types.d.ts +25 -14
- package/dist/types/new-metrics.d.ts +29 -9
- package/dist/types/operational-metrics.d.ts +19 -0
- package/package.json +11 -11
- package/src/behavioral-metrics.ts +40 -0
- package/src/business-metrics.ts +30 -0
- package/src/generic-metrics.ts +146 -0
- package/src/index.ts +5 -1
- package/src/metrics.types.ts +29 -16
- package/src/new-metrics.ts +68 -17
- package/src/operational-metrics.ts +24 -0
- package/test/unit/spec/behavioral/behavioral-metrics.ts +51 -10
- package/test/unit/spec/business/business-metrics.ts +120 -0
- package/test/unit/spec/operational/operational-metrics.ts +115 -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
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import GenericMetrics from './generic-metrics';
|
|
2
|
+
import { EventPayload } from './metrics.types';
|
|
3
|
+
/**
|
|
4
|
+
* @description Util class to handle Operational Metrics
|
|
5
|
+
* @export
|
|
6
|
+
* @class OperationalMetrics
|
|
7
|
+
*/
|
|
8
|
+
export default class OperationalMetrics extends GenericMetrics {
|
|
9
|
+
/**
|
|
10
|
+
* Submit an operational metric to our metrics endpoint.
|
|
11
|
+
* @param {string} name of the metric
|
|
12
|
+
* @param {EventPayload} user payload of the metric
|
|
13
|
+
* @returns {Promise<any>}
|
|
14
|
+
*/
|
|
15
|
+
submitOperationalEvent({ name, payload }: {
|
|
16
|
+
name: string;
|
|
17
|
+
payload: EventPayload;
|
|
18
|
+
}): void;
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -26,22 +26,22 @@
|
|
|
26
26
|
"@webex/eslint-config-legacy": "0.0.0",
|
|
27
27
|
"@webex/jest-config-legacy": "0.0.0",
|
|
28
28
|
"@webex/legacy-tools": "0.0.0",
|
|
29
|
-
"@webex/test-helper-chai": "3.4.0-next.
|
|
30
|
-
"@webex/test-helper-mocha": "3.4.0-next.
|
|
31
|
-
"@webex/test-helper-mock-webex": "3.4.0-next.
|
|
32
|
-
"@webex/test-helper-test-users": "3.4.0-next.
|
|
29
|
+
"@webex/test-helper-chai": "3.4.0-next.2",
|
|
30
|
+
"@webex/test-helper-mocha": "3.4.0-next.2",
|
|
31
|
+
"@webex/test-helper-mock-webex": "3.4.0-next.2",
|
|
32
|
+
"@webex/test-helper-test-users": "3.4.0-next.2",
|
|
33
33
|
"eslint": "^8.24.0",
|
|
34
34
|
"prettier": "^2.7.1",
|
|
35
35
|
"sinon": "^9.2.4"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@webex/common": "3.4.0-next.
|
|
39
|
-
"@webex/common-timers": "3.4.0-next.
|
|
38
|
+
"@webex/common": "3.4.0-next.2",
|
|
39
|
+
"@webex/common-timers": "3.4.0-next.2",
|
|
40
40
|
"@webex/event-dictionary-ts": "^1.0.1406",
|
|
41
|
-
"@webex/internal-plugin-metrics": "3.4.0-next.
|
|
42
|
-
"@webex/test-helper-chai": "3.4.0-next.
|
|
43
|
-
"@webex/test-helper-mock-webex": "3.4.0-next.
|
|
44
|
-
"@webex/webex-core": "3.4.0-next.
|
|
41
|
+
"@webex/internal-plugin-metrics": "3.4.0-next.2",
|
|
42
|
+
"@webex/test-helper-chai": "3.4.0-next.2",
|
|
43
|
+
"@webex/test-helper-mock-webex": "3.4.0-next.2",
|
|
44
|
+
"@webex/webex-core": "3.4.0-next.2",
|
|
45
45
|
"ip-anonymize": "^0.1.0",
|
|
46
46
|
"lodash": "^4.17.21",
|
|
47
47
|
"uuid": "^3.3.2"
|
|
@@ -54,5 +54,5 @@
|
|
|
54
54
|
"test:style": "eslint ./src/**/*.*",
|
|
55
55
|
"test:unit": "webex-legacy-tools test --unit --runner mocha"
|
|
56
56
|
},
|
|
57
|
-
"version": "3.4.0-next.
|
|
57
|
+
"version": "3.4.0-next.2"
|
|
58
58
|
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import {MetricEventProduct, MetricEventAgent, MetricEventVerb, EventPayload} from './metrics.types';
|
|
2
|
+
import GenericMetrics from './generic-metrics';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description Util class to handle Behavioral Metrics
|
|
6
|
+
* @export
|
|
7
|
+
* @class BehavioralMetrics
|
|
8
|
+
*/
|
|
9
|
+
export default class BehavioralMetrics extends GenericMetrics {
|
|
10
|
+
/**
|
|
11
|
+
* Submit a behavioral metric to our metrics endpoint.
|
|
12
|
+
* @param {MetricEventProduct} product the product from which the metric is being submitted, e.g. 'webex' web client, 'wxcc_desktop'
|
|
13
|
+
* @param {MetricEventAgent} agent the source of the action for this metric
|
|
14
|
+
* @param {string} target the 'thing' that this metric includes information about
|
|
15
|
+
* @param {MetricEventVerb} verb the action that this metric includes information about
|
|
16
|
+
* @param {EventPayload} payload information specific to this event. This should be flat, i.e. it should not include nested objects.
|
|
17
|
+
* @returns {Promise<any>}
|
|
18
|
+
*/
|
|
19
|
+
public submitBehavioralEvent({
|
|
20
|
+
product,
|
|
21
|
+
agent,
|
|
22
|
+
target,
|
|
23
|
+
verb,
|
|
24
|
+
payload,
|
|
25
|
+
}: {
|
|
26
|
+
product: MetricEventProduct;
|
|
27
|
+
agent: MetricEventAgent;
|
|
28
|
+
target: string;
|
|
29
|
+
verb: MetricEventVerb;
|
|
30
|
+
payload?: EventPayload;
|
|
31
|
+
}) {
|
|
32
|
+
const name = `${product}.${agent}.${target}.${verb}`;
|
|
33
|
+
const event = this.createTaggedEventObject({
|
|
34
|
+
type: ['behavioral'],
|
|
35
|
+
name,
|
|
36
|
+
payload,
|
|
37
|
+
});
|
|
38
|
+
this.submitEvent({kind: 'behavioral-events -> ', name, event});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import GenericMetrics from './generic-metrics';
|
|
2
|
+
import {EventPayload} from './metrics.types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description Util class to handle Buisness Metrics
|
|
6
|
+
* @export
|
|
7
|
+
* @class BusinessMetrics
|
|
8
|
+
*/
|
|
9
|
+
export default class BusinessMetrics extends GenericMetrics {
|
|
10
|
+
/**
|
|
11
|
+
* Submit a buisness metric to our metrics endpoint.
|
|
12
|
+
* @param {string} name of the metric
|
|
13
|
+
* @param {EventPayload} user payload of the metric
|
|
14
|
+
* @returns {Promise<any>}
|
|
15
|
+
*/
|
|
16
|
+
public submitBusinessEvent({name, payload}: {name: string; payload: EventPayload}) {
|
|
17
|
+
const event = {
|
|
18
|
+
type: ['business'],
|
|
19
|
+
eventPayload: {
|
|
20
|
+
metricName: name,
|
|
21
|
+
timestamp: Date.now(),
|
|
22
|
+
context: this.getContext(),
|
|
23
|
+
browserDetails: this.getBrowserDetails(),
|
|
24
|
+
value: payload,
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
this.submitEvent({kind: 'buisness-events -> ', name, event});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
2
|
+
import {BrowserDetection} from '@webex/common';
|
|
3
|
+
import {merge} from 'lodash';
|
|
4
|
+
import ClientMetricsBatcher from './client-metrics-batcher';
|
|
5
|
+
import {getOSNameInternal} from './metrics';
|
|
6
|
+
import {DeviceContext, TaggedEvent, EventPayload, MetricType} from './metrics.types';
|
|
7
|
+
|
|
8
|
+
const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @description top-level abstract class to handle Metrics and common routines.
|
|
12
|
+
* @export
|
|
13
|
+
* @class GenericMetrics
|
|
14
|
+
*/
|
|
15
|
+
export default abstract class GenericMetrics extends StatelessWebexPlugin {
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
private clientMetricsBatcher: ClientMetricsBatcher;
|
|
18
|
+
private logger: any; // to avoid adding @ts-ignore everywhere
|
|
19
|
+
private device: any;
|
|
20
|
+
private version: string;
|
|
21
|
+
private deviceId = '';
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Constructor
|
|
25
|
+
* @param {any[]} args
|
|
26
|
+
*/
|
|
27
|
+
constructor(...args) {
|
|
28
|
+
super(...args);
|
|
29
|
+
// @ts-ignore
|
|
30
|
+
this.logger = this.webex.logger;
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
this.clientMetricsBatcher = new ClientMetricsBatcher({}, {parent: this.webex});
|
|
33
|
+
// @ts-ignore
|
|
34
|
+
this.device = this.webex.internal.device;
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
this.version = this.webex.version;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Submit a buisness metric to our metrics endpoint.
|
|
41
|
+
* @param {string} kind of metric for logging
|
|
42
|
+
* @param {string} name of the metric
|
|
43
|
+
* @param {object} event
|
|
44
|
+
* @returns {Promise<any>}
|
|
45
|
+
*/
|
|
46
|
+
protected submitEvent({kind, name, event}: {kind: string; name: string; event: object}) {
|
|
47
|
+
this.logger.log(kind, `@submitEvent. Submit event: ${name}`);
|
|
48
|
+
|
|
49
|
+
return this.clientMetricsBatcher.request(event);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns the deviceId from our registration with WDM.
|
|
54
|
+
* @returns {string} deviceId or empty string
|
|
55
|
+
*/
|
|
56
|
+
protected getDeviceId(): string {
|
|
57
|
+
if (this.deviceId === '') {
|
|
58
|
+
const {url} = this.device;
|
|
59
|
+
if (url && url.length !== 0) {
|
|
60
|
+
const n = url.lastIndexOf('/');
|
|
61
|
+
if (n !== -1) {
|
|
62
|
+
this.deviceId = url.substring(n + 1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return this.deviceId;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Returns the context object to be submitted with all metrics.
|
|
72
|
+
* @returns {DeviceContext}
|
|
73
|
+
*/
|
|
74
|
+
protected getContext(): DeviceContext {
|
|
75
|
+
return {
|
|
76
|
+
app: {
|
|
77
|
+
version: this.version,
|
|
78
|
+
},
|
|
79
|
+
device: {
|
|
80
|
+
id: this.getDeviceId(),
|
|
81
|
+
},
|
|
82
|
+
locale: window.navigator.language,
|
|
83
|
+
os: {
|
|
84
|
+
name: getOSNameInternal(),
|
|
85
|
+
version: getOSVersion(),
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Returns the browser details to be included with all metrics.
|
|
92
|
+
* @returns {object}
|
|
93
|
+
*/
|
|
94
|
+
protected getBrowserDetails(): object {
|
|
95
|
+
return {
|
|
96
|
+
browser: getBrowserName(),
|
|
97
|
+
browserHeight: window.innerHeight,
|
|
98
|
+
browserVersion: getBrowserVersion(),
|
|
99
|
+
browserWidth: window.innerWidth,
|
|
100
|
+
domain: window.location.hostname,
|
|
101
|
+
inIframe: window.self !== window.top,
|
|
102
|
+
locale: window.navigator.language,
|
|
103
|
+
os: getOSNameInternal(),
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Returns true once we have the deviceId we need to submit behavioral/operational/buisness events
|
|
109
|
+
* @returns {boolean}
|
|
110
|
+
*/
|
|
111
|
+
public isReadyToSubmitEvents(): boolean {
|
|
112
|
+
const deviceId = this.getDeviceId();
|
|
113
|
+
|
|
114
|
+
return deviceId && deviceId.length !== 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Creates the object to send to our metrics endpoint for a tagged event (i.e. behavoral or operational)
|
|
119
|
+
* @param {[MetricType]} list of event type (i.e. ['behavioral'], ['operational', 'behavioral'])
|
|
120
|
+
* @param {string} metric name
|
|
121
|
+
* @param {EventPayload} user payload
|
|
122
|
+
* @returns {EventPayload}
|
|
123
|
+
*/
|
|
124
|
+
protected createTaggedEventObject({
|
|
125
|
+
type,
|
|
126
|
+
name,
|
|
127
|
+
payload,
|
|
128
|
+
}: {
|
|
129
|
+
type: [MetricType];
|
|
130
|
+
name: string;
|
|
131
|
+
payload: EventPayload;
|
|
132
|
+
}): TaggedEvent {
|
|
133
|
+
let allTags: EventPayload = payload;
|
|
134
|
+
allTags = merge(allTags, this.getBrowserDetails());
|
|
135
|
+
|
|
136
|
+
const event = {
|
|
137
|
+
context: this.getContext(),
|
|
138
|
+
metricName: name,
|
|
139
|
+
tags: allTags,
|
|
140
|
+
timestamp: Date.now(),
|
|
141
|
+
type,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
return event;
|
|
145
|
+
}
|
|
146
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -22,7 +22,9 @@ import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
|
|
|
22
22
|
import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
|
|
23
23
|
import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
24
24
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
25
|
-
import BehavioralMetrics from './behavioral
|
|
25
|
+
import BehavioralMetrics from './behavioral-metrics';
|
|
26
|
+
import OperationalMetrics from './operational-metrics';
|
|
27
|
+
import BusinessMetrics from './business-metrics';
|
|
26
28
|
|
|
27
29
|
registerInternalPlugin('metrics', Metrics, {
|
|
28
30
|
config,
|
|
@@ -43,6 +45,8 @@ export {
|
|
|
43
45
|
CallDiagnosticLatencies,
|
|
44
46
|
CallDiagnosticMetrics,
|
|
45
47
|
BehavioralMetrics,
|
|
48
|
+
OperationalMetrics,
|
|
49
|
+
BusinessMetrics,
|
|
46
50
|
};
|
|
47
51
|
export type {
|
|
48
52
|
ClientEvent,
|
package/src/metrics.types.ts
CHANGED
|
@@ -102,7 +102,7 @@ export interface ClientEvent {
|
|
|
102
102
|
options?: SubmitClientEventOptions;
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
export interface
|
|
105
|
+
export interface DeviceContext {
|
|
106
106
|
app: {version: string};
|
|
107
107
|
device: {id: string};
|
|
108
108
|
locale: string;
|
|
@@ -112,23 +112,36 @@ export interface BehavioralEventContext {
|
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
export
|
|
116
|
-
|
|
115
|
+
export type MetricType = 'behavioral' | 'operational' | 'business';
|
|
116
|
+
|
|
117
|
+
type InternalEventPayload = string | number | boolean;
|
|
118
|
+
export type EventPayload = Record<string, InternalEventPayload>;
|
|
119
|
+
export type BehavioralEventPayload = EventPayload; // for compatibilty, can be remove after wxcc-desktop did change their imports.
|
|
120
|
+
|
|
121
|
+
export interface BusinessEventPayload {
|
|
117
122
|
metricName: string;
|
|
118
|
-
tags: Record<string, string | number | boolean>;
|
|
119
123
|
timestamp: number;
|
|
120
|
-
|
|
124
|
+
context: DeviceContext;
|
|
125
|
+
browserDetails: EventPayload;
|
|
126
|
+
value: EventPayload;
|
|
121
127
|
}
|
|
122
128
|
|
|
123
|
-
export
|
|
129
|
+
export interface BusinessEvent {
|
|
130
|
+
type: string[];
|
|
131
|
+
eventPayload: BusinessEventPayload;
|
|
132
|
+
}
|
|
124
133
|
|
|
125
|
-
export interface
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
export interface TaggedEvent {
|
|
135
|
+
context: DeviceContext;
|
|
136
|
+
metricName: string;
|
|
137
|
+
tags: EventPayload;
|
|
138
|
+
timestamp: number;
|
|
139
|
+
type: [MetricType];
|
|
130
140
|
}
|
|
131
141
|
|
|
142
|
+
export type BehavioralEvent = TaggedEvent;
|
|
143
|
+
export type OperationalEvent = TaggedEvent;
|
|
144
|
+
|
|
132
145
|
export interface FeatureEvent {
|
|
133
146
|
// TODO: not implemented
|
|
134
147
|
name: never;
|
|
@@ -154,7 +167,8 @@ export type MetricEventNames =
|
|
|
154
167
|
| InternalEvent['name']
|
|
155
168
|
| ClientEvent['name']
|
|
156
169
|
| BehavioralEvent['metricName']
|
|
157
|
-
| OperationalEvent['
|
|
170
|
+
| OperationalEvent['metricName']
|
|
171
|
+
| BusinessEvent['eventPayload']['metricName']
|
|
158
172
|
| FeatureEvent['name']
|
|
159
173
|
| MediaQualityEvent['name'];
|
|
160
174
|
|
|
@@ -190,7 +204,7 @@ export type SubmitBehavioralEvent = (args: {
|
|
|
190
204
|
agent: MetricEventAgent;
|
|
191
205
|
target: string;
|
|
192
206
|
verb: MetricEventVerb;
|
|
193
|
-
payload?:
|
|
207
|
+
payload?: EventPayload;
|
|
194
208
|
}) => void;
|
|
195
209
|
|
|
196
210
|
export type SubmitClientEvent = (args: {
|
|
@@ -200,9 +214,8 @@ export type SubmitClientEvent = (args: {
|
|
|
200
214
|
}) => Promise<any>;
|
|
201
215
|
|
|
202
216
|
export type SubmitOperationalEvent = (args: {
|
|
203
|
-
name: OperationalEvent['
|
|
204
|
-
payload
|
|
205
|
-
options?: any;
|
|
217
|
+
name: OperationalEvent['metricName'];
|
|
218
|
+
payload: EventPayload;
|
|
206
219
|
}) => void;
|
|
207
220
|
|
|
208
221
|
export type SubmitMQE = (args: {
|
package/src/new-metrics.ts
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import {WebexPlugin} from '@webex/webex-core';
|
|
7
7
|
|
|
8
8
|
import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
9
|
-
import BehavioralMetrics from './behavioral
|
|
9
|
+
import BehavioralMetrics from './behavioral-metrics';
|
|
10
|
+
import OperationalMetrics from './operational-metrics';
|
|
11
|
+
import BusinessMetrics from './business-metrics';
|
|
10
12
|
import {
|
|
11
13
|
RecursivePartial,
|
|
12
14
|
MetricEventProduct,
|
|
@@ -14,7 +16,7 @@ import {
|
|
|
14
16
|
MetricEventVerb,
|
|
15
17
|
ClientEvent,
|
|
16
18
|
FeatureEvent,
|
|
17
|
-
|
|
19
|
+
EventPayload,
|
|
18
20
|
OperationalEvent,
|
|
19
21
|
MediaQualityEvent,
|
|
20
22
|
InternalEvent,
|
|
@@ -37,6 +39,9 @@ class Metrics extends WebexPlugin {
|
|
|
37
39
|
// Helper classes to handle the different types of metrics
|
|
38
40
|
callDiagnosticMetrics: CallDiagnosticMetrics;
|
|
39
41
|
behavioralMetrics: BehavioralMetrics;
|
|
42
|
+
operationalMetrics: OperationalMetrics;
|
|
43
|
+
businessMetrics: BusinessMetrics;
|
|
44
|
+
isReady = false;
|
|
40
45
|
|
|
41
46
|
/**
|
|
42
47
|
* Constructor
|
|
@@ -61,8 +66,7 @@ class Metrics extends WebexPlugin {
|
|
|
61
66
|
this.webex.once('ready', () => {
|
|
62
67
|
// @ts-ignore
|
|
63
68
|
this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
|
|
64
|
-
|
|
65
|
-
this.behavioralMetrics = new BehavioralMetrics({}, {parent: this.webex});
|
|
69
|
+
this.isReady = true;
|
|
66
70
|
});
|
|
67
71
|
}
|
|
68
72
|
|
|
@@ -90,7 +94,21 @@ class Metrics extends WebexPlugin {
|
|
|
90
94
|
* @returns true once we have the deviceId we need to submit behavioral events to Amplitude
|
|
91
95
|
*/
|
|
92
96
|
isReadyToSubmitBehavioralEvents() {
|
|
93
|
-
return this.behavioralMetrics
|
|
97
|
+
return this.behavioralMetrics?.isReadyToSubmitEvents() ?? false;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @returns true once we have the deviceId we need to submit operational events
|
|
102
|
+
*/
|
|
103
|
+
isReadyToSubmitOperationalEvents() {
|
|
104
|
+
return this.operationalMetrics?.isReadyToSubmitEvents() ?? false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* @returns true once we have the deviceId we need to submit buisness events
|
|
109
|
+
*/
|
|
110
|
+
isReadyToSubmitBusinessEvents() {
|
|
111
|
+
return this.businessMetrics?.isReadyToSubmitEvents() ?? false;
|
|
94
112
|
}
|
|
95
113
|
|
|
96
114
|
/**
|
|
@@ -108,9 +126,9 @@ class Metrics extends WebexPlugin {
|
|
|
108
126
|
agent: MetricEventAgent;
|
|
109
127
|
target: string;
|
|
110
128
|
verb: MetricEventVerb;
|
|
111
|
-
payload?:
|
|
129
|
+
payload?: EventPayload;
|
|
112
130
|
}) {
|
|
113
|
-
if (!this.
|
|
131
|
+
if (!this.isReady) {
|
|
114
132
|
// @ts-ignore
|
|
115
133
|
this.webex.logger.log(
|
|
116
134
|
`NewMetrics: @submitBehavioralEvent. Attempted to submit before webex.ready: ${product}.${agent}.${target}.${verb}`
|
|
@@ -119,6 +137,11 @@ class Metrics extends WebexPlugin {
|
|
|
119
137
|
return Promise.resolve();
|
|
120
138
|
}
|
|
121
139
|
|
|
140
|
+
if (!this.behavioralMetrics) {
|
|
141
|
+
// @ts-ignore
|
|
142
|
+
this.behavioralMetrics = new BehavioralMetrics({}, {parent: this.webex});
|
|
143
|
+
}
|
|
144
|
+
|
|
122
145
|
return this.behavioralMetrics.submitBehavioralEvent({product, agent, target, verb, payload});
|
|
123
146
|
}
|
|
124
147
|
|
|
@@ -126,16 +149,44 @@ class Metrics extends WebexPlugin {
|
|
|
126
149
|
* Operational event
|
|
127
150
|
* @param args
|
|
128
151
|
*/
|
|
129
|
-
submitOperationalEvent({
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
152
|
+
submitOperationalEvent({name, payload}: {name: string; payload?: EventPayload}) {
|
|
153
|
+
if (!this.isReady) {
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
this.webex.logger.log(
|
|
156
|
+
`NewMetrics: @submitOperationalEvent. Attempted to submit before webex.ready: ${name}`
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
return Promise.resolve();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (!this.operationalMetrics) {
|
|
163
|
+
// @ts-ignore
|
|
164
|
+
this.operationalMetrics = new OperationalMetrics({}, {parent: this.webex});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return this.operationalMetrics.submitOperationalEvent({name, payload});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Buisness event
|
|
172
|
+
* @param args
|
|
173
|
+
*/
|
|
174
|
+
submitBusinessEvent({name, payload}: {name: string; payload: EventPayload}) {
|
|
175
|
+
if (!this.isReady) {
|
|
176
|
+
// @ts-ignore
|
|
177
|
+
this.webex.logger.log(
|
|
178
|
+
`NewMetrics: @submitBusinessEvent. Attempted to submit before webex.ready: ${name}`
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
return Promise.resolve();
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (!this.businessMetrics) {
|
|
185
|
+
// @ts-ignore
|
|
186
|
+
this.businessMetrics = new BusinessMetrics({}, {parent: this.webex});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return this.businessMetrics.submitBusinessEvent({name, payload});
|
|
139
190
|
}
|
|
140
191
|
|
|
141
192
|
/**
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import GenericMetrics from './generic-metrics';
|
|
2
|
+
import {EventPayload} from './metrics.types';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @description Util class to handle Operational Metrics
|
|
6
|
+
* @export
|
|
7
|
+
* @class OperationalMetrics
|
|
8
|
+
*/
|
|
9
|
+
export default class OperationalMetrics extends GenericMetrics {
|
|
10
|
+
/**
|
|
11
|
+
* Submit an operational metric to our metrics endpoint.
|
|
12
|
+
* @param {string} name of the metric
|
|
13
|
+
* @param {EventPayload} user payload of the metric
|
|
14
|
+
* @returns {Promise<any>}
|
|
15
|
+
*/
|
|
16
|
+
public submitOperationalEvent({name, payload}: {name: string; payload: EventPayload}) {
|
|
17
|
+
const event = this.createTaggedEventObject({
|
|
18
|
+
type: ['operational'],
|
|
19
|
+
name,
|
|
20
|
+
payload,
|
|
21
|
+
});
|
|
22
|
+
this.submitEvent({kind: 'operational-events -> ', name, event});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -74,6 +74,45 @@ describe('internal-plugin-metrics', () => {
|
|
|
74
74
|
sinon.restore();
|
|
75
75
|
});
|
|
76
76
|
|
|
77
|
+
describe('#sendEvent', () => {
|
|
78
|
+
it('should send correctly shaped behavioral event (check name building and internal tagged event building)', () => {
|
|
79
|
+
// For some reasons `jest` isn't available when testing form build server - so can't use `jest.fn()` here...
|
|
80
|
+
const requestCalls = [];
|
|
81
|
+
const request = function(arg) { requestCalls.push(arg) }
|
|
82
|
+
|
|
83
|
+
behavioralMetrics.clientMetricsBatcher.request = request;
|
|
84
|
+
|
|
85
|
+
assert.equal(requestCalls.length, 0)
|
|
86
|
+
behavioralMetrics.submitBehavioralEvent({ product: "webex", agent: "user", target: "foo", verb: "get", payload: {bar:"gee"} })
|
|
87
|
+
assert.equal(requestCalls.length, 1)
|
|
88
|
+
assert.deepEqual(requestCalls[0], {
|
|
89
|
+
context: {
|
|
90
|
+
app: {version: 'webex-version'},
|
|
91
|
+
device: {id: 'deviceId'},
|
|
92
|
+
locale: 'language',
|
|
93
|
+
os: {
|
|
94
|
+
name: getOSNameInternal(),
|
|
95
|
+
version: getOSVersion(),
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
metricName: 'webex.user.foo.get',
|
|
99
|
+
tags: {
|
|
100
|
+
browser: getBrowserName(),
|
|
101
|
+
browserHeight: window.innerHeight,
|
|
102
|
+
browserVersion: getBrowserVersion(),
|
|
103
|
+
browserWidth: window.innerWidth,
|
|
104
|
+
domain: window.location.hostname,
|
|
105
|
+
inIframe: false,
|
|
106
|
+
locale: window.navigator.language,
|
|
107
|
+
os: getOSNameInternal(),
|
|
108
|
+
bar:"gee"
|
|
109
|
+
},
|
|
110
|
+
timestamp: requestCalls[0].timestamp, // This is to bypass time check, which is correctly tested below.
|
|
111
|
+
type: ['behavioral'],
|
|
112
|
+
});
|
|
113
|
+
})
|
|
114
|
+
})
|
|
115
|
+
|
|
77
116
|
describe('#getContext', () => {
|
|
78
117
|
it('should build context correctly', () => {
|
|
79
118
|
const res = behavioralMetrics.getContext();
|
|
@@ -96,7 +135,7 @@ describe('internal-plugin-metrics', () => {
|
|
|
96
135
|
|
|
97
136
|
describe('#getDefaultTags', () => {
|
|
98
137
|
it('should build tags correctly', () => {
|
|
99
|
-
const res = behavioralMetrics.
|
|
138
|
+
const res = behavioralMetrics.getBrowserDetails();
|
|
100
139
|
|
|
101
140
|
assert.deepEqual(res, {
|
|
102
141
|
browser: getBrowserName(),
|
|
@@ -111,25 +150,27 @@ describe('internal-plugin-metrics', () => {
|
|
|
111
150
|
});
|
|
112
151
|
});
|
|
113
152
|
|
|
114
|
-
describe('#
|
|
153
|
+
describe('#isReadyToSubmitEvents', () => {
|
|
115
154
|
it('should return true when we have a deviceId, false when deviceId is empty or undefined', async () => {
|
|
116
|
-
|
|
155
|
+
let deviceIdUrl = webex.internal.device.url;
|
|
117
156
|
|
|
157
|
+
// testing case w/o device id url first, as the internal deviceId cache would bypass that flow.
|
|
118
158
|
webex.internal.device.url = "";
|
|
119
|
-
assert.equal(false, behavioralMetrics.
|
|
159
|
+
assert.equal(false, behavioralMetrics.isReadyToSubmitEvents());
|
|
120
160
|
|
|
121
161
|
delete webex.internal.device.url;
|
|
122
|
-
assert.equal(false, behavioralMetrics.
|
|
162
|
+
assert.equal(false, behavioralMetrics.isReadyToSubmitEvents());
|
|
163
|
+
|
|
164
|
+
webex.internal.device.url = deviceIdUrl;
|
|
165
|
+
assert.equal(true, behavioralMetrics.isReadyToSubmitEvents());
|
|
123
166
|
});
|
|
124
167
|
});
|
|
125
168
|
|
|
126
169
|
describe('#createEventObject', () => {
|
|
127
170
|
it('should build event object correctly', async () => {
|
|
128
|
-
const res = behavioralMetrics.
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
target: 'target',
|
|
132
|
-
verb: 'create',
|
|
171
|
+
const res = behavioralMetrics.createTaggedEventObject({
|
|
172
|
+
type:['behavioral'],
|
|
173
|
+
name:'webex.user.target.create',
|
|
133
174
|
payload: tags,
|
|
134
175
|
});
|
|
135
176
|
|