Skip to content

Commit 7437aa1

Browse files
authored
TNT-41222, TNT-41675 - collect response parsing time metric and artifact request metrics (#65)
1 parent 01e46f1 commit 7437aa1

21 files changed

+635
-325
lines changed

packages/target-decisioning-engine/src/artifactProvider.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,13 @@ import {
4040
const LOG_TAG = `${LOG_PREFIX}.ArtifactProvider`;
4141
const NOT_MODIFIED = 304;
4242
const OK = 200;
43+
const ARTIFACT_DOWNLOAD = "ArtifactDownload";
4344

4445
/**
4546
* The ArtifactProvider initialize method
4647
* @param {import("../types/DecisioningConfig").DecisioningConfig} config Options map, required
4748
*/
48-
function ArtifactProvider(config) {
49+
function ArtifactProvider(config, telemetryProvider) {
4950
const logger = getLogger(config.logger);
5051
const { eventEmitter = noop } = config;
5152
const obfuscationProvider = ObfuscationProvider(config);
@@ -147,9 +148,24 @@ function ArtifactProvider(config) {
147148
cache: "default"
148149
})
149150
.then(res => {
150-
perfTool.timeEnd(TIMING_ARTIFACT_DOWNLOADED_FETCH);
151+
const executionTime = perfTool.timeEnd(
152+
TIMING_ARTIFACT_DOWNLOADED_FETCH
153+
);
154+
perfTool.clearTiming(TIMING_ARTIFACT_DOWNLOADED_FETCH);
151155
logger.debug(`${LOG_TAG} artifact received - status=${res.status}`);
152156

157+
const entry = {
158+
execution: executionTime
159+
};
160+
161+
if (res.timings) {
162+
entry.parsing = res.timings.parsingTime;
163+
delete res.timings.parsingTime;
164+
entry.request = res.timings;
165+
}
166+
167+
telemetryProvider.addArtifactRequestEntry(ARTIFACT_DOWNLOAD, entry);
168+
153169
if (res.status === NOT_MODIFIED && lastResponseData) {
154170
return lastResponseData;
155171
}

packages/target-decisioning-engine/src/artifactProvider.spec.js

Lines changed: 107 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import * as HttpStatus from "http-status-codes";
33
import {
44
ENVIRONMENT_PROD,
55
ENVIRONMENT_STAGE,
6-
isDefined
6+
isDefined,
7+
TelemetryProvider
78
} from "@adobe/target-tools";
89
import ArtifactProvider from "./artifactProvider";
910
import * as constants from "./constants";
@@ -24,10 +25,14 @@ import {
2425

2526
const ARTIFACT_BLANK = require("../test/schema/artifacts/TEST_ARTIFACT_BLANK.json");
2627

28+
const ARTIFACT_DOWNLOAD = "ArtifactDownload";
29+
2730
require("jest-fetch-mock").enableMocks();
2831

2932
describe("artifactProvider", () => {
3033
let provider;
34+
const telemetryProvider = TelemetryProvider();
35+
telemetryProvider.addArtifactRequestEntry = jest.fn();
3136

3237
const TEST_CONF = {
3338
client: "clientId",
@@ -51,22 +56,28 @@ describe("artifactProvider", () => {
5156
it("initializes", async () => {
5257
fetch.mockResponse(JSON.stringify(ARTIFACT_BLANK));
5358

54-
provider = await ArtifactProvider({
55-
...TEST_CONF,
56-
artifactPayload: ARTIFACT_BLANK,
57-
maximumWaitReady: 500
58-
});
59+
provider = await ArtifactProvider(
60+
{
61+
...TEST_CONF,
62+
artifactPayload: ARTIFACT_BLANK,
63+
maximumWaitReady: 500
64+
},
65+
telemetryProvider
66+
);
5967
expect(provider).not.toBeUndefined();
6068
expect(provider.getArtifact()).toEqual(ARTIFACT_BLANK);
6169
});
6270

6371
it("subscribes", async done => {
6472
fetch.mockResponse(JSON.stringify(ARTIFACT_BLANK));
6573

66-
provider = await ArtifactProvider({
67-
...TEST_CONF,
68-
pollingInterval: 10
69-
});
74+
provider = await ArtifactProvider(
75+
{
76+
...TEST_CONF,
77+
pollingInterval: 10
78+
},
79+
telemetryProvider
80+
);
7081

7182
const subscriptionId = provider.subscribe(data => {
7283
expect(data).toEqual(ARTIFACT_BLANK);
@@ -81,37 +92,55 @@ describe("artifactProvider", () => {
8192
it("polls", async done => {
8293
fetch.mockResponse(JSON.stringify(ARTIFACT_BLANK));
8394

84-
provider = await ArtifactProvider({
85-
...TEST_CONF,
86-
pollingInterval: 10
87-
});
95+
provider = await ArtifactProvider(
96+
{
97+
...TEST_CONF,
98+
pollingInterval: 10
99+
},
100+
telemetryProvider
101+
);
88102

89103
const mockListener = jest.fn();
90104

91105
provider.subscribe(mockListener);
92106

93107
setTimeout(() => {
94108
expect(mockListener.mock.calls.length).toBeGreaterThanOrEqual(4);
109+
expect(telemetryProvider.addArtifactRequestEntry).toHaveBeenCalledWith(
110+
ARTIFACT_DOWNLOAD,
111+
expect.objectContaining({
112+
execution: expect.any(Number)
113+
})
114+
);
95115
done();
96116
}, 100);
97117
});
98118

99119
it("polls even if artifactPayload is provided", async done => {
100120
fetch.mockResponse(JSON.stringify(ARTIFACT_BLANK));
101-
expect.assertions(1);
121+
expect.assertions(2);
102122

103-
provider = await ArtifactProvider({
104-
...TEST_CONF,
105-
artifactPayload: ARTIFACT_BLANK,
106-
pollingInterval: 10
107-
});
123+
provider = await ArtifactProvider(
124+
{
125+
...TEST_CONF,
126+
artifactPayload: ARTIFACT_BLANK,
127+
pollingInterval: 10
128+
},
129+
telemetryProvider
130+
);
108131

109132
const mockListener = jest.fn();
110133

111134
provider.subscribe(mockListener);
112135

113136
setTimeout(() => {
114137
expect(mockListener.mock.calls.length).toBeGreaterThanOrEqual(8);
138+
expect(telemetryProvider.addArtifactRequestEntry).toHaveBeenCalledWith(
139+
ARTIFACT_DOWNLOAD,
140+
expect.objectContaining({
141+
execution: expect.any(Number)
142+
})
143+
);
115144
done();
116145
}, 100);
117146
});
@@ -131,10 +160,13 @@ describe("artifactProvider", () => {
131160
[JSON.stringify(ARTIFACT_BLANK), { status: HttpStatus.OK }]
132161
);
133162

134-
provider = await ArtifactProvider({
135-
...TEST_CONF,
136-
pollingInterval: 0
137-
});
163+
provider = await ArtifactProvider(
164+
{
165+
...TEST_CONF,
166+
pollingInterval: 0
167+
},
168+
telemetryProvider
169+
);
138170

139171
expect(provider.getArtifact()).toEqual(ARTIFACT_BLANK);
140172
expect(fetch.mock.calls.length).toEqual(11);
@@ -168,11 +200,14 @@ describe("artifactProvider", () => {
168200
}
169201
};
170202

171-
provider = await ArtifactProvider({
172-
...TEST_CONF,
173-
pollingInterval: 0,
174-
logger
175-
});
203+
provider = await ArtifactProvider(
204+
{
205+
...TEST_CONF,
206+
pollingInterval: 0,
207+
logger
208+
},
209+
telemetryProvider
210+
);
176211

177212
expect(provider.getArtifact()).toBeUndefined();
178213
expect(fetch.mock.calls.length).toEqual(11);
@@ -183,18 +218,21 @@ describe("artifactProvider", () => {
183218

184219
fetch.mockResponse(JSON.stringify(ARTIFACT_BLANK)).doMockIf(artifactURL);
185220

186-
provider = await ArtifactProvider({
187-
...TEST_CONF,
188-
pollingInterval: 0,
189-
artifactLocation: artifactURL
190-
});
221+
provider = await ArtifactProvider(
222+
{
223+
...TEST_CONF,
224+
pollingInterval: 0,
225+
artifactLocation: artifactURL
226+
},
227+
telemetryProvider
228+
);
191229

192230
expect(provider.getArtifact()).toEqual(ARTIFACT_BLANK);
193231
expect(fetch.mock.calls[0][0]).toEqual(artifactURL);
194232
});
195233

196234
it("gets a cached version based on ETag", async done => {
197-
expect.assertions(6);
235+
expect.assertions(7);
198236

199237
const eTagIdentifier = "the_original_eTag";
200238
const eTagIdentifierNew = "the_new_eTag";
@@ -270,12 +308,15 @@ describe("artifactProvider", () => {
270308

271309
const artifactUpdated = jest.fn();
272310

273-
provider = await ArtifactProvider({
274-
client: "clientId",
275-
organizationId: "orgId",
276-
pollingInterval: 100,
277-
artifactFormat: ARTIFACT_FORMAT_JSON
278-
});
311+
provider = await ArtifactProvider(
312+
{
313+
client: "clientId",
314+
organizationId: "orgId",
315+
pollingInterval: 100,
316+
artifactFormat: ARTIFACT_FORMAT_JSON
317+
},
318+
telemetryProvider
319+
);
279320

280321
provider.subscribe(artifactUpdated);
281322

@@ -284,6 +325,12 @@ describe("artifactProvider", () => {
284325
setTimeout(() => {
285326
expect(artifactUpdated).toHaveBeenCalledTimes(1); // only one update to the artifact after the initial
286327
expect(artifactUpdated.mock.calls[0][0]).toEqual(NEW_VERSION_PAYLOAD);
328+
expect(telemetryProvider.addArtifactRequestEntry).toHaveBeenCalledWith(
329+
ARTIFACT_DOWNLOAD,
330+
expect.objectContaining({
331+
execution: expect.any(Number)
332+
})
333+
);
287334
done();
288335
}, 350);
289336
});
@@ -302,14 +349,17 @@ describe("artifactProvider", () => {
302349
done();
303350
}
304351

305-
provider = await ArtifactProvider({
306-
...TEST_CONF,
307-
pollingInterval: 0,
308-
eventEmitter: (eventName, payload) =>
309-
eventName === ARTIFACT_DOWNLOAD_SUCCEEDED
310-
? eventEmitter(eventName, payload)
311-
: undefined
312-
});
352+
provider = await ArtifactProvider(
353+
{
354+
...TEST_CONF,
355+
pollingInterval: 0,
356+
eventEmitter: (eventName, payload) =>
357+
eventName === ARTIFACT_DOWNLOAD_SUCCEEDED
358+
? eventEmitter(eventName, payload)
359+
: undefined
360+
},
361+
telemetryProvider
362+
);
313363
});
314364

315365
it("emits artifactDownloadFailed event", async done => {
@@ -332,11 +382,14 @@ describe("artifactProvider", () => {
332382
setTimeout(() => done(), 100);
333383
}
334384

335-
provider = await ArtifactProvider({
336-
...TEST_CONF,
337-
pollingInterval: 0,
338-
eventEmitter
339-
});
385+
provider = await ArtifactProvider(
386+
{
387+
...TEST_CONF,
388+
pollingInterval: 0,
389+
eventEmitter
390+
},
391+
telemetryProvider
392+
);
340393
});
341394
});
342395

packages/target-decisioning-engine/src/index.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@ import { GeoProvider } from "./geoProvider";
1212
/**
1313
* The TargetDecisioningEngine initialize method
1414
* @param {import("../types/DecisioningConfig").DecisioningConfig} config Options map, required
15+
* @param {import("@adobe/target-tools/src/telemetryProvider")} telemetryProvider TelemetryProvider function, required
1516
*/
16-
export default function TargetDecisioningEngine(config) {
17+
export default function TargetDecisioningEngine(config, telemetryProvider) {
1718
const logger = getLogger(config.logger);
1819
let artifactProvider;
1920
let artifact;
@@ -75,10 +76,13 @@ export default function TargetDecisioningEngine(config) {
7576
return isDefined(artifact);
7677
}
7778

78-
return ArtifactProvider({
79-
...config,
80-
logger
81-
}).then(providerInstance => {
79+
return ArtifactProvider(
80+
{
81+
...config,
82+
logger
83+
},
84+
telemetryProvider
85+
).then(providerInstance => {
8286
artifactProvider = providerInstance;
8387
artifact = artifactProvider.getArtifact();
8488

0 commit comments

Comments
 (0)