@webex/internal-plugin-metrics 3.4.0 → 3.5.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/call-diagnostic/call-diagnostic-metrics.js +15 -5
- 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/{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 +122 -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 +21 -5
- package/dist/types/call-diagnostic/call-diagnostic-metrics.util.d.ts +2 -1
- package/dist/types/generic-metrics.d.ts +63 -0
- package/dist/types/index.d.ts +4 -2
- package/dist/types/metrics.types.d.ts +26 -14
- package/dist/types/new-metrics.d.ts +41 -9
- package/dist/types/operational-metrics.d.ts +19 -0
- package/package.json +12 -12
- package/src/behavioral-metrics.ts +40 -0
- package/src/business-metrics.ts +30 -0
- package/src/call-diagnostic/call-diagnostic-metrics.ts +19 -2
- package/src/call-diagnostic/call-diagnostic-metrics.util.ts +17 -4
- package/src/generic-metrics.ts +146 -0
- package/src/index.ts +5 -1
- package/src/metrics.types.ts +30 -16
- package/src/new-metrics.ts +95 -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/call-diagnostic/call-diagnostic-metrics-batcher.ts +2 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.ts +167 -1
- package/test/unit/spec/call-diagnostic/call-diagnostic-metrics.util.ts +22 -8
- package/test/unit/spec/new-metrics.ts +14 -0
- package/test/unit/spec/operational/operational-metrics.ts +115 -0
- package/test/unit/spec/prelogin-metrics-batcher.ts +3 -1
- 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,63 @@
|
|
|
1
|
+
import { StatelessWebexPlugin } from '@webex/webex-core';
|
|
2
|
+
import { DeviceContext, TaggedEvent, EventPayload, MetricType } from './metrics.types';
|
|
3
|
+
/**
|
|
4
|
+
* @description top-level abstract class to handle Metrics and common routines.
|
|
5
|
+
* @export
|
|
6
|
+
* @class GenericMetrics
|
|
7
|
+
*/
|
|
8
|
+
export default abstract class GenericMetrics extends StatelessWebexPlugin {
|
|
9
|
+
private clientMetricsBatcher;
|
|
10
|
+
private logger;
|
|
11
|
+
private device;
|
|
12
|
+
private version;
|
|
13
|
+
private deviceId;
|
|
14
|
+
/**
|
|
15
|
+
* Constructor
|
|
16
|
+
* @param {any[]} args
|
|
17
|
+
*/
|
|
18
|
+
constructor(...args: any[]);
|
|
19
|
+
/**
|
|
20
|
+
* Submit a buisness metric to our metrics endpoint.
|
|
21
|
+
* @param {string} kind of metric for logging
|
|
22
|
+
* @param {string} name of the metric
|
|
23
|
+
* @param {object} event
|
|
24
|
+
* @returns {Promise<any>}
|
|
25
|
+
*/
|
|
26
|
+
protected submitEvent({ kind, name, event }: {
|
|
27
|
+
kind: string;
|
|
28
|
+
name: string;
|
|
29
|
+
event: object;
|
|
30
|
+
}): any;
|
|
31
|
+
/**
|
|
32
|
+
* Returns the deviceId from our registration with WDM.
|
|
33
|
+
* @returns {string} deviceId or empty string
|
|
34
|
+
*/
|
|
35
|
+
protected getDeviceId(): string;
|
|
36
|
+
/**
|
|
37
|
+
* Returns the context object to be submitted with all metrics.
|
|
38
|
+
* @returns {DeviceContext}
|
|
39
|
+
*/
|
|
40
|
+
protected getContext(): DeviceContext;
|
|
41
|
+
/**
|
|
42
|
+
* Returns the browser details to be included with all metrics.
|
|
43
|
+
* @returns {object}
|
|
44
|
+
*/
|
|
45
|
+
protected getBrowserDetails(): object;
|
|
46
|
+
/**
|
|
47
|
+
* Returns true once we have the deviceId we need to submit behavioral/operational/buisness events
|
|
48
|
+
* @returns {boolean}
|
|
49
|
+
*/
|
|
50
|
+
isReadyToSubmitEvents(): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Creates the object to send to our metrics endpoint for a tagged event (i.e. behavoral or operational)
|
|
53
|
+
* @param {[MetricType]} list of event type (i.e. ['behavioral'], ['operational', 'behavioral'])
|
|
54
|
+
* @param {string} metric name
|
|
55
|
+
* @param {EventPayload} user payload
|
|
56
|
+
* @returns {EventPayload}
|
|
57
|
+
*/
|
|
58
|
+
protected createTaggedEventObject({ type, name, payload, }: {
|
|
59
|
+
type: [MetricType];
|
|
60
|
+
name: string;
|
|
61
|
+
payload: EventPayload;
|
|
62
|
+
}): TaggedEvent;
|
|
63
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ import * as CALL_DIAGNOSTIC_CONFIG from './call-diagnostic/config';
|
|
|
9
9
|
import * as CallDiagnosticUtils from './call-diagnostic/call-diagnostic-metrics.util';
|
|
10
10
|
import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
11
11
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
12
|
-
import BehavioralMetrics from './behavioral
|
|
12
|
+
import BehavioralMetrics from './behavioral-metrics';
|
|
13
|
+
import OperationalMetrics from './operational-metrics';
|
|
14
|
+
import BusinessMetrics from './business-metrics';
|
|
13
15
|
export { default, getOSNameInternal } from './metrics';
|
|
14
|
-
export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, BehavioralMetrics, };
|
|
16
|
+
export { config, CALL_DIAGNOSTIC_CONFIG, NewMetrics, Utils, CallDiagnosticUtils, CallDiagnosticLatencies, CallDiagnosticMetrics, BehavioralMetrics, OperationalMetrics, BusinessMetrics, };
|
|
15
17
|
export type { ClientEvent, ClientEventLeaveReason, SubmitBehavioralEvent, SubmitClientEvent, SubmitInternalEvent, SubmitMQE, SubmitOperationalEvent, PreComputedLatencies, };
|
|
@@ -15,6 +15,7 @@ export type SubmitClientEventOptions = {
|
|
|
15
15
|
mediaConnections?: any[];
|
|
16
16
|
rawError?: any;
|
|
17
17
|
correlationId?: string;
|
|
18
|
+
sessionCorrelationId?: string;
|
|
18
19
|
preLoginId?: string;
|
|
19
20
|
environment?: EnvironmentType;
|
|
20
21
|
newEnvironmentType?: NewEnvironmentType;
|
|
@@ -40,7 +41,7 @@ export interface ClientEvent {
|
|
|
40
41
|
payload?: RawClientEvent;
|
|
41
42
|
options?: SubmitClientEventOptions;
|
|
42
43
|
}
|
|
43
|
-
export interface
|
|
44
|
+
export interface DeviceContext {
|
|
44
45
|
app: {
|
|
45
46
|
version: string;
|
|
46
47
|
};
|
|
@@ -53,19 +54,30 @@ export interface BehavioralEventContext {
|
|
|
53
54
|
version: string;
|
|
54
55
|
};
|
|
55
56
|
}
|
|
56
|
-
export
|
|
57
|
-
|
|
57
|
+
export type MetricType = 'behavioral' | 'operational' | 'business';
|
|
58
|
+
type InternalEventPayload = string | number | boolean;
|
|
59
|
+
export type EventPayload = Record<string, InternalEventPayload>;
|
|
60
|
+
export type BehavioralEventPayload = EventPayload;
|
|
61
|
+
export interface BusinessEventPayload {
|
|
58
62
|
metricName: string;
|
|
59
|
-
tags: Record<string, string | number | boolean>;
|
|
60
63
|
timestamp: number;
|
|
64
|
+
context: DeviceContext;
|
|
65
|
+
browserDetails: EventPayload;
|
|
66
|
+
value: EventPayload;
|
|
67
|
+
}
|
|
68
|
+
export interface BusinessEvent {
|
|
61
69
|
type: string[];
|
|
70
|
+
eventPayload: BusinessEventPayload;
|
|
62
71
|
}
|
|
63
|
-
export
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
export interface TaggedEvent {
|
|
73
|
+
context: DeviceContext;
|
|
74
|
+
metricName: string;
|
|
75
|
+
tags: EventPayload;
|
|
76
|
+
timestamp: number;
|
|
77
|
+
type: [MetricType];
|
|
68
78
|
}
|
|
79
|
+
export type BehavioralEvent = TaggedEvent;
|
|
80
|
+
export type OperationalEvent = TaggedEvent;
|
|
69
81
|
export interface FeatureEvent {
|
|
70
82
|
name: never;
|
|
71
83
|
payload?: never;
|
|
@@ -79,7 +91,7 @@ export interface MediaQualityEvent {
|
|
|
79
91
|
export type RecursivePartial<T> = {
|
|
80
92
|
[P in keyof T]?: T[P] extends (infer U)[] ? RecursivePartial<U>[] : T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
|
81
93
|
};
|
|
82
|
-
export type MetricEventNames = InternalEvent['name'] | ClientEvent['name'] | BehavioralEvent['metricName'] | OperationalEvent['
|
|
94
|
+
export type MetricEventNames = InternalEvent['name'] | ClientEvent['name'] | BehavioralEvent['metricName'] | OperationalEvent['metricName'] | BusinessEvent['eventPayload']['metricName'] | FeatureEvent['name'] | MediaQualityEvent['name'];
|
|
83
95
|
export type ClientInfo = NonNullable<RawEvent['origin']['clientInfo']>;
|
|
84
96
|
export type ClientType = NonNullable<RawEvent['origin']['clientInfo']>['clientType'];
|
|
85
97
|
export type SubClientType = NonNullable<RawEvent['origin']['clientInfo']>['subClientType'];
|
|
@@ -103,7 +115,7 @@ export type SubmitBehavioralEvent = (args: {
|
|
|
103
115
|
agent: MetricEventAgent;
|
|
104
116
|
target: string;
|
|
105
117
|
verb: MetricEventVerb;
|
|
106
|
-
payload?:
|
|
118
|
+
payload?: EventPayload;
|
|
107
119
|
}) => void;
|
|
108
120
|
export type SubmitClientEvent = (args: {
|
|
109
121
|
name: ClientEvent['name'];
|
|
@@ -111,9 +123,8 @@ export type SubmitClientEvent = (args: {
|
|
|
111
123
|
options?: SubmitClientEventOptions;
|
|
112
124
|
}) => Promise<any>;
|
|
113
125
|
export type SubmitOperationalEvent = (args: {
|
|
114
|
-
name: OperationalEvent['
|
|
115
|
-
payload
|
|
116
|
-
options?: any;
|
|
126
|
+
name: OperationalEvent['metricName'];
|
|
127
|
+
payload: EventPayload;
|
|
117
128
|
}) => void;
|
|
118
129
|
export type SubmitMQE = (args: {
|
|
119
130
|
name: MediaQualityEvent['name'];
|
|
@@ -126,3 +137,4 @@ export type BuildClientEventFetchRequestOptions = (args: {
|
|
|
126
137
|
options?: SubmitClientEventOptions;
|
|
127
138
|
}) => Promise<any>;
|
|
128
139
|
export type PreComputedLatencies = 'internal.client.pageJMT' | 'internal.download.time' | 'internal.get.cluster.time' | 'internal.click.to.interstitial' | 'internal.refresh.captcha.time' | 'internal.exchange.ci.token.time' | 'internal.get.u2c.time' | 'internal.call.init.join.req' | 'internal.other.app.api.time' | 'internal.api.fetch.intelligence.models';
|
|
140
|
+
export {};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { WebexPlugin } from '@webex/webex-core';
|
|
2
2
|
import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
|
|
3
|
-
import BehavioralMetrics from './behavioral
|
|
4
|
-
import
|
|
3
|
+
import BehavioralMetrics from './behavioral-metrics';
|
|
4
|
+
import OperationalMetrics from './operational-metrics';
|
|
5
|
+
import BusinessMetrics from './business-metrics';
|
|
6
|
+
import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions } from './metrics.types';
|
|
5
7
|
import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
|
|
6
8
|
/**
|
|
7
9
|
* Metrics plugin to centralize all types of metrics.
|
|
@@ -12,6 +14,9 @@ declare class Metrics extends WebexPlugin {
|
|
|
12
14
|
callDiagnosticLatencies: CallDiagnosticLatencies;
|
|
13
15
|
callDiagnosticMetrics: CallDiagnosticMetrics;
|
|
14
16
|
behavioralMetrics: BehavioralMetrics;
|
|
17
|
+
operationalMetrics: OperationalMetrics;
|
|
18
|
+
businessMetrics: BusinessMetrics;
|
|
19
|
+
isReady: boolean;
|
|
15
20
|
/**
|
|
16
21
|
* Constructor
|
|
17
22
|
* @param args
|
|
@@ -33,10 +38,30 @@ declare class Metrics extends WebexPlugin {
|
|
|
33
38
|
payload?: RecursivePartial<InternalEvent['payload']>;
|
|
34
39
|
options?: any;
|
|
35
40
|
}): void;
|
|
41
|
+
/**
|
|
42
|
+
* if webex metrics is ready, build behavioral metric backend if not already done.
|
|
43
|
+
*/
|
|
44
|
+
private lazyBuildBehavioralMetrics;
|
|
45
|
+
/**
|
|
46
|
+
* if webex metrics is ready, build operational metric backend if not already done.
|
|
47
|
+
*/
|
|
48
|
+
private lazyBuildOperationalMetrics;
|
|
49
|
+
/**
|
|
50
|
+
* if webex metrics is ready, build business metric backend if not already done.
|
|
51
|
+
*/
|
|
52
|
+
private lazyBuildBusinessMetrics;
|
|
36
53
|
/**
|
|
37
54
|
* @returns true once we have the deviceId we need to submit behavioral events to Amplitude
|
|
38
55
|
*/
|
|
39
56
|
isReadyToSubmitBehavioralEvents(): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* @returns true once we have the deviceId we need to submit operational events
|
|
59
|
+
*/
|
|
60
|
+
isReadyToSubmitOperationalEvents(): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* @returns true once we have the deviceId we need to submit buisness events
|
|
63
|
+
*/
|
|
64
|
+
isReadyToSubmitBusinessEvents(): boolean;
|
|
40
65
|
/**
|
|
41
66
|
* Behavioral event
|
|
42
67
|
* @param args
|
|
@@ -46,17 +71,24 @@ declare class Metrics extends WebexPlugin {
|
|
|
46
71
|
agent: MetricEventAgent;
|
|
47
72
|
target: string;
|
|
48
73
|
verb: MetricEventVerb;
|
|
49
|
-
payload?:
|
|
50
|
-
}):
|
|
74
|
+
payload?: EventPayload;
|
|
75
|
+
}): void | Promise<void>;
|
|
51
76
|
/**
|
|
52
77
|
* Operational event
|
|
53
78
|
* @param args
|
|
54
79
|
*/
|
|
55
|
-
submitOperationalEvent({ name, payload
|
|
56
|
-
name:
|
|
57
|
-
payload?:
|
|
58
|
-
|
|
59
|
-
|
|
80
|
+
submitOperationalEvent({ name, payload }: {
|
|
81
|
+
name: string;
|
|
82
|
+
payload?: EventPayload;
|
|
83
|
+
}): void | Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Buisness event
|
|
86
|
+
* @param args
|
|
87
|
+
*/
|
|
88
|
+
submitBusinessEvent({ name, payload }: {
|
|
89
|
+
name: string;
|
|
90
|
+
payload: EventPayload;
|
|
91
|
+
}): void | Promise<void>;
|
|
60
92
|
/**
|
|
61
93
|
* Call Analyzer: Media Quality Event
|
|
62
94
|
* @param args
|
|
@@ -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.
|
|
30
|
-
"@webex/test-helper-mocha": "3.
|
|
31
|
-
"@webex/test-helper-mock-webex": "3.
|
|
32
|
-
"@webex/test-helper-test-users": "3.
|
|
29
|
+
"@webex/test-helper-chai": "3.5.0-next.2",
|
|
30
|
+
"@webex/test-helper-mocha": "3.5.0-next.2",
|
|
31
|
+
"@webex/test-helper-mock-webex": "3.5.0-next.2",
|
|
32
|
+
"@webex/test-helper-test-users": "3.5.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.
|
|
39
|
-
"@webex/common-timers": "3.
|
|
40
|
-
"@webex/event-dictionary-ts": "^1.0.
|
|
41
|
-
"@webex/internal-plugin-metrics": "3.
|
|
42
|
-
"@webex/test-helper-chai": "3.
|
|
43
|
-
"@webex/test-helper-mock-webex": "3.
|
|
44
|
-
"@webex/webex-core": "3.
|
|
38
|
+
"@webex/common": "3.5.0-next.2",
|
|
39
|
+
"@webex/common-timers": "3.5.0-next.2",
|
|
40
|
+
"@webex/event-dictionary-ts": "^1.0.1546",
|
|
41
|
+
"@webex/internal-plugin-metrics": "3.5.0-next.2",
|
|
42
|
+
"@webex/test-helper-chai": "3.5.0-next.2",
|
|
43
|
+
"@webex/test-helper-mock-webex": "3.5.0-next.2",
|
|
44
|
+
"@webex/webex-core": "3.5.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.
|
|
57
|
+
"version": "3.5.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
|
+
key: name,
|
|
21
|
+
client_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
|
+
}
|
|
@@ -75,6 +75,7 @@ type GetIdentifiersOptions = {
|
|
|
75
75
|
meeting?: any;
|
|
76
76
|
mediaConnections?: any[];
|
|
77
77
|
correlationId?: string;
|
|
78
|
+
sessionCorrelationId?: string;
|
|
78
79
|
preLoginId?: string;
|
|
79
80
|
globalMeetingId?: string;
|
|
80
81
|
webexConferenceIdStr?: string;
|
|
@@ -285,13 +286,20 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
285
286
|
webexConferenceIdStr,
|
|
286
287
|
globalMeetingId,
|
|
287
288
|
preLoginId,
|
|
289
|
+
sessionCorrelationId,
|
|
288
290
|
} = options;
|
|
289
291
|
const identifiers: Event['event']['identifiers'] = {
|
|
290
292
|
correlationId: 'unknown',
|
|
293
|
+
sessionCorrelationId: 'unknown',
|
|
291
294
|
};
|
|
292
295
|
|
|
293
296
|
if (meeting) {
|
|
294
297
|
identifiers.correlationId = meeting.correlationId;
|
|
298
|
+
identifiers.sessionCorrelationId = meeting.sessionCorrelationId;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (sessionCorrelationId) {
|
|
302
|
+
identifiers.sessionCorrelationId = sessionCorrelationId;
|
|
295
303
|
}
|
|
296
304
|
|
|
297
305
|
if (correlationId) {
|
|
@@ -646,7 +654,13 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
646
654
|
options?: SubmitClientEventOptions;
|
|
647
655
|
errors?: ClientEventPayloadError;
|
|
648
656
|
}) {
|
|
649
|
-
const {
|
|
657
|
+
const {
|
|
658
|
+
meetingId,
|
|
659
|
+
mediaConnections,
|
|
660
|
+
globalMeetingId,
|
|
661
|
+
webexConferenceIdStr,
|
|
662
|
+
sessionCorrelationId,
|
|
663
|
+
} = options;
|
|
650
664
|
|
|
651
665
|
// @ts-ignore
|
|
652
666
|
const meeting = this.webex.meetings.meetingCollection.get(meetingId);
|
|
@@ -673,6 +687,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
673
687
|
mediaConnections: meeting?.mediaConnections || mediaConnections,
|
|
674
688
|
webexConferenceIdStr,
|
|
675
689
|
globalMeetingId,
|
|
690
|
+
sessionCorrelationId,
|
|
676
691
|
});
|
|
677
692
|
|
|
678
693
|
// create client event object
|
|
@@ -714,11 +729,13 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
|
|
|
714
729
|
options?: SubmitClientEventOptions;
|
|
715
730
|
errors?: ClientEventPayloadError;
|
|
716
731
|
}) {
|
|
717
|
-
const {correlationId, globalMeetingId, webexConferenceIdStr, preLoginId} =
|
|
732
|
+
const {correlationId, globalMeetingId, webexConferenceIdStr, preLoginId, sessionCorrelationId} =
|
|
733
|
+
options;
|
|
718
734
|
|
|
719
735
|
// grab identifiers
|
|
720
736
|
const identifiers = this.getIdentifiers({
|
|
721
737
|
correlationId,
|
|
738
|
+
sessionCorrelationId,
|
|
722
739
|
preLoginId,
|
|
723
740
|
globalMeetingId,
|
|
724
741
|
webexConferenceIdStr,
|
|
@@ -195,10 +195,12 @@ export const isBrowserMediaErrorName = (errorName: any) => {
|
|
|
195
195
|
};
|
|
196
196
|
|
|
197
197
|
/**
|
|
198
|
+
* @param {Object} webex sdk instance
|
|
198
199
|
* @param webClientDomain
|
|
199
200
|
* @returns
|
|
200
201
|
*/
|
|
201
202
|
export const getBuildType = (
|
|
203
|
+
webex,
|
|
202
204
|
webClientDomain,
|
|
203
205
|
markAsTestEvent = false
|
|
204
206
|
): Event['origin']['buildType'] => {
|
|
@@ -207,6 +209,10 @@ export const getBuildType = (
|
|
|
207
209
|
return 'test';
|
|
208
210
|
}
|
|
209
211
|
|
|
212
|
+
if (webex.internal.metrics?.config?.caBuildType) {
|
|
213
|
+
return webex.internal.metrics.config.caBuildType;
|
|
214
|
+
}
|
|
215
|
+
|
|
210
216
|
if (
|
|
211
217
|
webClientDomain?.includes('localhost') ||
|
|
212
218
|
webClientDomain?.includes('127.0.0.1') ||
|
|
@@ -225,12 +231,19 @@ export const getBuildType = (
|
|
|
225
231
|
* @returns {Object} prepared item
|
|
226
232
|
*/
|
|
227
233
|
export const prepareDiagnosticMetricItem = (webex: any, item: any) => {
|
|
234
|
+
const buildType = getBuildType(
|
|
235
|
+
webex,
|
|
236
|
+
item.eventPayload?.event?.eventData?.webClientDomain,
|
|
237
|
+
item.eventPayload?.event?.eventData?.markAsTestEvent
|
|
238
|
+
);
|
|
239
|
+
|
|
240
|
+
// Set upgradeChannel to 'gold' if buildType is 'prod', otherwise to the buildType value
|
|
241
|
+
const upgradeChannel = buildType === 'prod' ? 'gold' : buildType;
|
|
242
|
+
|
|
228
243
|
const origin: Partial<Event['origin']> = {
|
|
229
|
-
buildType
|
|
230
|
-
item.eventPayload?.event?.eventData?.webClientDomain,
|
|
231
|
-
item.eventPayload?.event?.eventData?.markAsTestEvent
|
|
232
|
-
),
|
|
244
|
+
buildType,
|
|
233
245
|
networkType: 'unknown',
|
|
246
|
+
upgradeChannel,
|
|
234
247
|
};
|
|
235
248
|
|
|
236
249
|
// check event names and append latencies?
|
|
@@ -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,
|