@webex/internal-plugin-metrics 3.4.0-next.1 → 3.4.0-next.3
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,120 @@
|
|
|
1
|
+
import sinon from 'sinon';
|
|
2
|
+
import {assert} from '@webex/test-helper-chai';
|
|
3
|
+
import {BrowserDetection} from '@webex/common';
|
|
4
|
+
import {BusinessMetrics, config, getOSNameInternal} from '@webex/internal-plugin-metrics';
|
|
5
|
+
import uuid from 'uuid';
|
|
6
|
+
|
|
7
|
+
//@ts-ignore
|
|
8
|
+
global.window = {location: {hostname: 'whatever'}, navigator: {language: 'language'}};
|
|
9
|
+
process.env.NODE_ENV = 'test';
|
|
10
|
+
|
|
11
|
+
const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
|
|
12
|
+
|
|
13
|
+
describe('internal-plugin-metrics', () => {
|
|
14
|
+
describe('BusinessMetrics', () => {
|
|
15
|
+
let webex;
|
|
16
|
+
let now;
|
|
17
|
+
let businessMetrics: BusinessMetrics;
|
|
18
|
+
|
|
19
|
+
const tags = {key: 'val'};
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
now = new Date();
|
|
23
|
+
|
|
24
|
+
webex = {
|
|
25
|
+
canAuthorize: true,
|
|
26
|
+
version: 'webex-version',
|
|
27
|
+
internal: {
|
|
28
|
+
services: {
|
|
29
|
+
get: () => 'locus-url',
|
|
30
|
+
},
|
|
31
|
+
metrics: {
|
|
32
|
+
submitClientMetrics: sinon.stub(),
|
|
33
|
+
config: {...config.metrics},
|
|
34
|
+
},
|
|
35
|
+
newMetrics: {},
|
|
36
|
+
device: {
|
|
37
|
+
userId: 'userId',
|
|
38
|
+
url: 'https://wdm-intb.ciscospark.com/wdm/api/v1/devices/deviceId',
|
|
39
|
+
orgId: 'orgId',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
meetings: {
|
|
43
|
+
config: {
|
|
44
|
+
metrics: {
|
|
45
|
+
clientType: 'TEAMS_CLIENT',
|
|
46
|
+
subClientType: 'WEB_APP',
|
|
47
|
+
clientName: 'Cantina',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
geoHintInfo: {
|
|
51
|
+
clientAddress: '1.3.4.5',
|
|
52
|
+
countryCode: 'UK',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
credentials: {
|
|
56
|
+
isUnverifiedGuest: false,
|
|
57
|
+
},
|
|
58
|
+
prepareFetchOptions: sinon.stub().callsFake((opts: any) => ({...opts, foo: 'bar'})),
|
|
59
|
+
request: sinon.stub().resolves({body: {}}),
|
|
60
|
+
logger: {
|
|
61
|
+
log: sinon.stub(),
|
|
62
|
+
error: sinon.stub(),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
sinon.createSandbox();
|
|
67
|
+
sinon.useFakeTimers(now.getTime());
|
|
68
|
+
businessMetrics = new BusinessMetrics({}, {parent: webex});
|
|
69
|
+
sinon.stub(uuid, 'v4').returns('my-fake-id');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
sinon.restore();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('#sendEvent', () => {
|
|
77
|
+
it('should send correctly shaped business event (check name building and internal tagged event building)', () => {
|
|
78
|
+
// For some reasons `jest` isn't available when testing form build server - so can't use `jest.fn()` here...
|
|
79
|
+
const requestCalls = [];
|
|
80
|
+
const request = function(arg) { requestCalls.push(arg) }
|
|
81
|
+
|
|
82
|
+
businessMetrics.clientMetricsBatcher.request = request;
|
|
83
|
+
|
|
84
|
+
assert.equal(requestCalls.length, 0)
|
|
85
|
+
businessMetrics.submitBusinessEvent({ name: "foobar", payload: {bar:"gee"} })
|
|
86
|
+
assert.equal(requestCalls.length, 1)
|
|
87
|
+
assert.deepEqual(requestCalls[0], {
|
|
88
|
+
eventPayload: {
|
|
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: 'foobar',
|
|
99
|
+
browserDetails: {
|
|
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
|
+
},
|
|
109
|
+
timestamp: requestCalls[0].eventPayload.timestamp, // This is to bypass time check, which is checked below.
|
|
110
|
+
value: {
|
|
111
|
+
bar: "gee"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
type: ['business'],
|
|
115
|
+
});
|
|
116
|
+
assert.isNumber(requestCalls[0].eventPayload.timestamp)
|
|
117
|
+
})
|
|
118
|
+
})
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import sinon from 'sinon';
|
|
2
|
+
import {assert} from '@webex/test-helper-chai';
|
|
3
|
+
import {BrowserDetection} from '@webex/common';
|
|
4
|
+
import {OperationalMetrics, config, getOSNameInternal} from '@webex/internal-plugin-metrics';
|
|
5
|
+
import uuid from 'uuid';
|
|
6
|
+
|
|
7
|
+
//@ts-ignore
|
|
8
|
+
global.window = {location: {hostname: 'whatever'}, navigator: {language: 'language'}};
|
|
9
|
+
process.env.NODE_ENV = 'test';
|
|
10
|
+
|
|
11
|
+
const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
|
|
12
|
+
|
|
13
|
+
describe('internal-plugin-metrics', () => {
|
|
14
|
+
describe('OperationalMetrics', () => {
|
|
15
|
+
let webex;
|
|
16
|
+
let now;
|
|
17
|
+
let operationalMetrics: OperationalMetrics;
|
|
18
|
+
|
|
19
|
+
const tags = {key: 'val'};
|
|
20
|
+
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
now = new Date();
|
|
23
|
+
|
|
24
|
+
webex = {
|
|
25
|
+
canAuthorize: true,
|
|
26
|
+
version: 'webex-version',
|
|
27
|
+
internal: {
|
|
28
|
+
services: {
|
|
29
|
+
get: () => 'locus-url',
|
|
30
|
+
},
|
|
31
|
+
metrics: {
|
|
32
|
+
submitClientMetrics: sinon.stub(),
|
|
33
|
+
config: {...config.metrics},
|
|
34
|
+
},
|
|
35
|
+
newMetrics: {},
|
|
36
|
+
device: {
|
|
37
|
+
userId: 'userId',
|
|
38
|
+
url: 'https://wdm-intb.ciscospark.com/wdm/api/v1/devices/deviceId',
|
|
39
|
+
orgId: 'orgId',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
meetings: {
|
|
43
|
+
config: {
|
|
44
|
+
metrics: {
|
|
45
|
+
clientType: 'TEAMS_CLIENT',
|
|
46
|
+
subClientType: 'WEB_APP',
|
|
47
|
+
clientName: 'Cantina',
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
geoHintInfo: {
|
|
51
|
+
clientAddress: '1.3.4.5',
|
|
52
|
+
countryCode: 'UK',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
credentials: {
|
|
56
|
+
isUnverifiedGuest: false,
|
|
57
|
+
},
|
|
58
|
+
prepareFetchOptions: sinon.stub().callsFake((opts: any) => ({...opts, foo: 'bar'})),
|
|
59
|
+
request: sinon.stub().resolves({body: {}}),
|
|
60
|
+
logger: {
|
|
61
|
+
log: sinon.stub(),
|
|
62
|
+
error: sinon.stub(),
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
sinon.createSandbox();
|
|
67
|
+
sinon.useFakeTimers(now.getTime());
|
|
68
|
+
operationalMetrics = new OperationalMetrics({}, {parent: webex});
|
|
69
|
+
sinon.stub(uuid, 'v4').returns('my-fake-id');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
afterEach(() => {
|
|
73
|
+
sinon.restore();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('#sendEvent', () => {
|
|
77
|
+
it('should send correctly shaped operational event (check name building and internal tagged event building)', () => {
|
|
78
|
+
// For some reasons `jest` isn't available when testing form build server - so can't use `jest.fn()` here...
|
|
79
|
+
const requestCalls = [];
|
|
80
|
+
const request = function(arg) { requestCalls.push(arg) }
|
|
81
|
+
|
|
82
|
+
operationalMetrics.clientMetricsBatcher.request = request;
|
|
83
|
+
|
|
84
|
+
assert.equal(requestCalls.length, 0)
|
|
85
|
+
operationalMetrics.submitOperationalEvent({ name: "foobar", payload: {bar:"gee"} })
|
|
86
|
+
assert.equal(requestCalls.length, 1)
|
|
87
|
+
assert.deepEqual(requestCalls[0], {
|
|
88
|
+
context: {
|
|
89
|
+
app: {version: 'webex-version'},
|
|
90
|
+
device: {id: 'deviceId'},
|
|
91
|
+
locale: 'language',
|
|
92
|
+
os: {
|
|
93
|
+
name: getOSNameInternal(),
|
|
94
|
+
version: getOSVersion(),
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
metricName: 'foobar',
|
|
98
|
+
tags: {
|
|
99
|
+
browser: getBrowserName(),
|
|
100
|
+
browserHeight: window.innerHeight,
|
|
101
|
+
browserVersion: getBrowserVersion(),
|
|
102
|
+
browserWidth: window.innerWidth,
|
|
103
|
+
domain: window.location.hostname,
|
|
104
|
+
inIframe: false,
|
|
105
|
+
locale: window.navigator.language,
|
|
106
|
+
os: getOSNameInternal(),
|
|
107
|
+
bar: "gee"
|
|
108
|
+
},
|
|
109
|
+
timestamp: requestCalls[0].timestamp, // This is to bypass time check, which is correctly tested in behavioral-metrics tests.
|
|
110
|
+
type: ['operational'],
|
|
111
|
+
});
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
});
|
|
115
|
+
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["_lodash","require","_common","_webexCore","_metrics","_config","_clientMetricsBatcher","_interopRequireDefault","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","default","result","NewTarget","constructor","_Reflect$construct","arguments","apply","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","e","_BrowserDetection","BrowserDetection","getOSVersion","getBrowserName","getBrowserVersion","BehavioralMetrics","exports","_StatelessWebexPlugin","_inherits2","_super","_this","_classCallCheck2","_len","length","args","Array","_key","concat","_defineProperty2","_assertThisInitialized2","logger","webex","device","internal","version","clientMetricsBatcher","ClientMetricsBatcher","parent","_createClass2","key","value","getDeviceId","url","n","lastIndexOf","substring","getContext","context","app","id","locale","window","navigator","language","os","name","getOSNameInternal","getDefaultTags","tags","browser","browserHeight","innerHeight","browserVersion","browserWidth","innerWidth","domain","location","hostname","inIframe","self","top","createEventObject","_ref","product","agent","target","verb","payload","metricName","allTags","merge","event","timestamp","_now","type","isReadyToSubmitBehavioralEvents","deviceId","submitBehavioralEvent","_ref2","log","BEHAVIORAL_LOG_IDENTIFIER","behavioralEvent","request","StatelessWebexPlugin"],"sources":["behavioral-metrics.ts"],"sourcesContent":["import {merge} from 'lodash';\nimport {BrowserDetection} from '@webex/common';\nimport {StatelessWebexPlugin} from '@webex/webex-core';\nimport {getOSNameInternal} from '../metrics';\nimport {BEHAVIORAL_LOG_IDENTIFIER} from './config';\nimport {\n MetricEventProduct,\n MetricEventAgent,\n MetricEventVerb,\n BehavioralEventContext,\n BehavioralEvent,\n BehavioralEventPayload,\n} from '../metrics.types';\nimport ClientMetricsBatcher from '../client-metrics-batcher';\n\nconst {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();\n\n/**\n * @description Util class to handle Behavioral Metrics\n * @export\n * @class BehavioralMetrics\n */\nexport default class BehavioralMetrics extends StatelessWebexPlugin {\n // @ts-ignore\n private clientMetricsBatcher: ClientMetricsBatcher;\n private logger: any; // to avoid adding @ts-ignore everywhere\n private device: any;\n private version: string;\n\n /**\n * Constructor\n * @param {any[]} args\n */\n constructor(...args) {\n super(...args);\n // @ts-ignore\n this.logger = this.webex.logger;\n // @ts-ignore\n this.device = this.webex.internal.device;\n // @ts-ignore\n this.version = this.webex.version;\n // @ts-ignore\n this.clientMetricsBatcher = new ClientMetricsBatcher({}, {parent: this.webex});\n }\n\n /**\n * Returns the deviceId from our registration with WDM.\n * @returns {string} deviceId or empty string\n */\n private getDeviceId(): string {\n const {url} = this.device;\n if (url && url.length !== 0) {\n const n = url.lastIndexOf('/');\n if (n !== -1) {\n return url.substring(n + 1);\n }\n }\n\n return '';\n }\n\n /**\n * Returns the context object to be submitted with all behavioral metrics.\n * @returns {BehavioralEventContext}\n */\n private getContext(): BehavioralEventContext {\n const context: BehavioralEventContext = {\n app: {\n version: this.version,\n },\n device: {\n id: this.getDeviceId(),\n },\n locale: window.navigator.language,\n os: {\n name: getOSNameInternal(),\n version: getOSVersion(),\n },\n };\n\n return context;\n }\n\n /**\n * Returns the default tags to be included with all behavioral metrics.\n * @returns {BehavioralEventPayload}\n */\n private getDefaultTags(): BehavioralEventPayload {\n const tags = {\n browser: getBrowserName(),\n browserHeight: window.innerHeight,\n browserVersion: getBrowserVersion(),\n browserWidth: window.innerWidth,\n domain: window.location.hostname,\n inIframe: window.self !== window.top,\n locale: window.navigator.language,\n os: getOSNameInternal(),\n };\n\n return tags;\n }\n\n /**\n * Creates the object to send to our metrics endpoint for a behavioral event\n * @param {MetricEventProduct} product\n * @param {MetricEventAgent} agent\n * @param {string} target\n * @param {MetricEventVerb} verb\n * @returns {BehavioralEventPayload}\n */\n private createEventObject({\n product,\n agent,\n target,\n verb,\n payload,\n }: {\n product: MetricEventProduct;\n agent: MetricEventAgent;\n target: string;\n verb: MetricEventVerb;\n payload?: BehavioralEventPayload;\n }): BehavioralEvent {\n const metricName = `${product}.${agent}.${target}.${verb}`;\n let allTags: BehavioralEventPayload = payload;\n allTags = merge(allTags, this.getDefaultTags());\n\n const event: BehavioralEvent = {\n context: this.getContext(),\n metricName,\n tags: allTags,\n timestamp: Date.now(),\n type: ['behavioral'],\n };\n\n return event;\n }\n\n /**\n * Returns true once we're ready to submit behavioral metrics, after startup.\n * @returns {boolean} true when deviceId is defined and non-empty\n */\n public isReadyToSubmitBehavioralEvents(): boolean {\n const deviceId = this.getDeviceId();\n\n return deviceId && deviceId.length !== 0;\n }\n\n /**\n * Submit a behavioral metric to our metrics endpoint.\n * @param {MetricEventProduct} product the product from which the metric is being submitted, e.g. 'webex' web client, 'wxcc_desktop'\n * @param {MetricEventAgent} agent the source of the action for this metric\n * @param {string} target the 'thing' that this metric includes information about\n * @param {MetricEventVerb} verb the action that this metric includes information about\n * @param {BehavioralEventPayload} payload information specific to this event. This should be flat, i.e. it should not include nested objects.\n * @returns {Promise<any>}\n */\n public submitBehavioralEvent({\n product,\n agent,\n target,\n verb,\n payload,\n }: {\n product: MetricEventProduct;\n agent: MetricEventAgent;\n target: string;\n verb: MetricEventVerb;\n payload?: BehavioralEventPayload;\n }) {\n this.logger.log(\n BEHAVIORAL_LOG_IDENTIFIER,\n `BehavioralMetrics: @submitBehavioralEvent. Submit Behavioral event: ${product}.${agent}.${target}.${verb}`\n );\n const behavioralEvent = this.createEventObject({product, agent, target, verb, payload});\n\n return this.clientMetricsBatcher.request(behavioralEvent);\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
4
|
-
_Object$defineProperty(exports, "__esModule", {
|
|
5
|
-
value: true
|
|
6
|
-
});
|
|
7
|
-
exports.BEHAVIORAL_LOG_IDENTIFIER = void 0;
|
|
8
|
-
/* eslint-disable import/prefer-default-export */
|
|
9
|
-
|
|
10
|
-
var BEHAVIORAL_LOG_IDENTIFIER = exports.BEHAVIORAL_LOG_IDENTIFIER = 'behavioral-events -> ';
|
|
11
|
-
//# sourceMappingURL=config.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"names":["BEHAVIORAL_LOG_IDENTIFIER","exports"],"sources":["config.ts"],"sourcesContent":["/* eslint-disable import/prefer-default-export */\n\nexport const BEHAVIORAL_LOG_IDENTIFIER = 'behavioral-events -> ';\n"],"mappings":";;;;;;;AAAA;;AAEO,IAAMA,yBAAyB,GAAAC,OAAA,CAAAD,yBAAA,GAAG,uBAAuB"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { StatelessWebexPlugin } from '@webex/webex-core';
|
|
2
|
-
import { MetricEventProduct, MetricEventAgent, MetricEventVerb, BehavioralEventPayload } from '../metrics.types';
|
|
3
|
-
/**
|
|
4
|
-
* @description Util class to handle Behavioral Metrics
|
|
5
|
-
* @export
|
|
6
|
-
* @class BehavioralMetrics
|
|
7
|
-
*/
|
|
8
|
-
export default class BehavioralMetrics extends StatelessWebexPlugin {
|
|
9
|
-
private clientMetricsBatcher;
|
|
10
|
-
private logger;
|
|
11
|
-
private device;
|
|
12
|
-
private version;
|
|
13
|
-
/**
|
|
14
|
-
* Constructor
|
|
15
|
-
* @param {any[]} args
|
|
16
|
-
*/
|
|
17
|
-
constructor(...args: any[]);
|
|
18
|
-
/**
|
|
19
|
-
* Returns the deviceId from our registration with WDM.
|
|
20
|
-
* @returns {string} deviceId or empty string
|
|
21
|
-
*/
|
|
22
|
-
private getDeviceId;
|
|
23
|
-
/**
|
|
24
|
-
* Returns the context object to be submitted with all behavioral metrics.
|
|
25
|
-
* @returns {BehavioralEventContext}
|
|
26
|
-
*/
|
|
27
|
-
private getContext;
|
|
28
|
-
/**
|
|
29
|
-
* Returns the default tags to be included with all behavioral metrics.
|
|
30
|
-
* @returns {BehavioralEventPayload}
|
|
31
|
-
*/
|
|
32
|
-
private getDefaultTags;
|
|
33
|
-
/**
|
|
34
|
-
* Creates the object to send to our metrics endpoint for a behavioral event
|
|
35
|
-
* @param {MetricEventProduct} product
|
|
36
|
-
* @param {MetricEventAgent} agent
|
|
37
|
-
* @param {string} target
|
|
38
|
-
* @param {MetricEventVerb} verb
|
|
39
|
-
* @returns {BehavioralEventPayload}
|
|
40
|
-
*/
|
|
41
|
-
private createEventObject;
|
|
42
|
-
/**
|
|
43
|
-
* Returns true once we're ready to submit behavioral metrics, after startup.
|
|
44
|
-
* @returns {boolean} true when deviceId is defined and non-empty
|
|
45
|
-
*/
|
|
46
|
-
isReadyToSubmitBehavioralEvents(): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Submit a behavioral metric to our metrics endpoint.
|
|
49
|
-
* @param {MetricEventProduct} product the product from which the metric is being submitted, e.g. 'webex' web client, 'wxcc_desktop'
|
|
50
|
-
* @param {MetricEventAgent} agent the source of the action for this metric
|
|
51
|
-
* @param {string} target the 'thing' that this metric includes information about
|
|
52
|
-
* @param {MetricEventVerb} verb the action that this metric includes information about
|
|
53
|
-
* @param {BehavioralEventPayload} payload information specific to this event. This should be flat, i.e. it should not include nested objects.
|
|
54
|
-
* @returns {Promise<any>}
|
|
55
|
-
*/
|
|
56
|
-
submitBehavioralEvent({ product, agent, target, verb, payload, }: {
|
|
57
|
-
product: MetricEventProduct;
|
|
58
|
-
agent: MetricEventAgent;
|
|
59
|
-
target: string;
|
|
60
|
-
verb: MetricEventVerb;
|
|
61
|
-
payload?: BehavioralEventPayload;
|
|
62
|
-
}): any;
|
|
63
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const BEHAVIORAL_LOG_IDENTIFIER = "behavioral-events -> ";
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import {merge} from 'lodash';
|
|
2
|
-
import {BrowserDetection} from '@webex/common';
|
|
3
|
-
import {StatelessWebexPlugin} from '@webex/webex-core';
|
|
4
|
-
import {getOSNameInternal} from '../metrics';
|
|
5
|
-
import {BEHAVIORAL_LOG_IDENTIFIER} from './config';
|
|
6
|
-
import {
|
|
7
|
-
MetricEventProduct,
|
|
8
|
-
MetricEventAgent,
|
|
9
|
-
MetricEventVerb,
|
|
10
|
-
BehavioralEventContext,
|
|
11
|
-
BehavioralEvent,
|
|
12
|
-
BehavioralEventPayload,
|
|
13
|
-
} from '../metrics.types';
|
|
14
|
-
import ClientMetricsBatcher from '../client-metrics-batcher';
|
|
15
|
-
|
|
16
|
-
const {getOSVersion, getBrowserName, getBrowserVersion} = BrowserDetection();
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @description Util class to handle Behavioral Metrics
|
|
20
|
-
* @export
|
|
21
|
-
* @class BehavioralMetrics
|
|
22
|
-
*/
|
|
23
|
-
export default class BehavioralMetrics extends StatelessWebexPlugin {
|
|
24
|
-
// @ts-ignore
|
|
25
|
-
private clientMetricsBatcher: ClientMetricsBatcher;
|
|
26
|
-
private logger: any; // to avoid adding @ts-ignore everywhere
|
|
27
|
-
private device: any;
|
|
28
|
-
private version: string;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Constructor
|
|
32
|
-
* @param {any[]} args
|
|
33
|
-
*/
|
|
34
|
-
constructor(...args) {
|
|
35
|
-
super(...args);
|
|
36
|
-
// @ts-ignore
|
|
37
|
-
this.logger = this.webex.logger;
|
|
38
|
-
// @ts-ignore
|
|
39
|
-
this.device = this.webex.internal.device;
|
|
40
|
-
// @ts-ignore
|
|
41
|
-
this.version = this.webex.version;
|
|
42
|
-
// @ts-ignore
|
|
43
|
-
this.clientMetricsBatcher = new ClientMetricsBatcher({}, {parent: this.webex});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Returns the deviceId from our registration with WDM.
|
|
48
|
-
* @returns {string} deviceId or empty string
|
|
49
|
-
*/
|
|
50
|
-
private getDeviceId(): string {
|
|
51
|
-
const {url} = this.device;
|
|
52
|
-
if (url && url.length !== 0) {
|
|
53
|
-
const n = url.lastIndexOf('/');
|
|
54
|
-
if (n !== -1) {
|
|
55
|
-
return url.substring(n + 1);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return '';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
* Returns the context object to be submitted with all behavioral metrics.
|
|
64
|
-
* @returns {BehavioralEventContext}
|
|
65
|
-
*/
|
|
66
|
-
private getContext(): BehavioralEventContext {
|
|
67
|
-
const context: BehavioralEventContext = {
|
|
68
|
-
app: {
|
|
69
|
-
version: this.version,
|
|
70
|
-
},
|
|
71
|
-
device: {
|
|
72
|
-
id: this.getDeviceId(),
|
|
73
|
-
},
|
|
74
|
-
locale: window.navigator.language,
|
|
75
|
-
os: {
|
|
76
|
-
name: getOSNameInternal(),
|
|
77
|
-
version: getOSVersion(),
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
return context;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Returns the default tags to be included with all behavioral metrics.
|
|
86
|
-
* @returns {BehavioralEventPayload}
|
|
87
|
-
*/
|
|
88
|
-
private getDefaultTags(): BehavioralEventPayload {
|
|
89
|
-
const tags = {
|
|
90
|
-
browser: getBrowserName(),
|
|
91
|
-
browserHeight: window.innerHeight,
|
|
92
|
-
browserVersion: getBrowserVersion(),
|
|
93
|
-
browserWidth: window.innerWidth,
|
|
94
|
-
domain: window.location.hostname,
|
|
95
|
-
inIframe: window.self !== window.top,
|
|
96
|
-
locale: window.navigator.language,
|
|
97
|
-
os: getOSNameInternal(),
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
return tags;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Creates the object to send to our metrics endpoint for a behavioral event
|
|
105
|
-
* @param {MetricEventProduct} product
|
|
106
|
-
* @param {MetricEventAgent} agent
|
|
107
|
-
* @param {string} target
|
|
108
|
-
* @param {MetricEventVerb} verb
|
|
109
|
-
* @returns {BehavioralEventPayload}
|
|
110
|
-
*/
|
|
111
|
-
private createEventObject({
|
|
112
|
-
product,
|
|
113
|
-
agent,
|
|
114
|
-
target,
|
|
115
|
-
verb,
|
|
116
|
-
payload,
|
|
117
|
-
}: {
|
|
118
|
-
product: MetricEventProduct;
|
|
119
|
-
agent: MetricEventAgent;
|
|
120
|
-
target: string;
|
|
121
|
-
verb: MetricEventVerb;
|
|
122
|
-
payload?: BehavioralEventPayload;
|
|
123
|
-
}): BehavioralEvent {
|
|
124
|
-
const metricName = `${product}.${agent}.${target}.${verb}`;
|
|
125
|
-
let allTags: BehavioralEventPayload = payload;
|
|
126
|
-
allTags = merge(allTags, this.getDefaultTags());
|
|
127
|
-
|
|
128
|
-
const event: BehavioralEvent = {
|
|
129
|
-
context: this.getContext(),
|
|
130
|
-
metricName,
|
|
131
|
-
tags: allTags,
|
|
132
|
-
timestamp: Date.now(),
|
|
133
|
-
type: ['behavioral'],
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
return event;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Returns true once we're ready to submit behavioral metrics, after startup.
|
|
141
|
-
* @returns {boolean} true when deviceId is defined and non-empty
|
|
142
|
-
*/
|
|
143
|
-
public isReadyToSubmitBehavioralEvents(): boolean {
|
|
144
|
-
const deviceId = this.getDeviceId();
|
|
145
|
-
|
|
146
|
-
return deviceId && deviceId.length !== 0;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Submit a behavioral metric to our metrics endpoint.
|
|
151
|
-
* @param {MetricEventProduct} product the product from which the metric is being submitted, e.g. 'webex' web client, 'wxcc_desktop'
|
|
152
|
-
* @param {MetricEventAgent} agent the source of the action for this metric
|
|
153
|
-
* @param {string} target the 'thing' that this metric includes information about
|
|
154
|
-
* @param {MetricEventVerb} verb the action that this metric includes information about
|
|
155
|
-
* @param {BehavioralEventPayload} payload information specific to this event. This should be flat, i.e. it should not include nested objects.
|
|
156
|
-
* @returns {Promise<any>}
|
|
157
|
-
*/
|
|
158
|
-
public submitBehavioralEvent({
|
|
159
|
-
product,
|
|
160
|
-
agent,
|
|
161
|
-
target,
|
|
162
|
-
verb,
|
|
163
|
-
payload,
|
|
164
|
-
}: {
|
|
165
|
-
product: MetricEventProduct;
|
|
166
|
-
agent: MetricEventAgent;
|
|
167
|
-
target: string;
|
|
168
|
-
verb: MetricEventVerb;
|
|
169
|
-
payload?: BehavioralEventPayload;
|
|
170
|
-
}) {
|
|
171
|
-
this.logger.log(
|
|
172
|
-
BEHAVIORAL_LOG_IDENTIFIER,
|
|
173
|
-
`BehavioralMetrics: @submitBehavioralEvent. Submit Behavioral event: ${product}.${agent}.${target}.${verb}`
|
|
174
|
-
);
|
|
175
|
-
const behavioralEvent = this.createEventObject({product, agent, target, verb, payload});
|
|
176
|
-
|
|
177
|
-
return this.clientMetricsBatcher.request(behavioralEvent);
|
|
178
|
-
}
|
|
179
|
-
}
|
package/src/behavioral/config.ts
DELETED