@elastic/synthetics 1.0.0-beta.2 → 1.0.0-beta.20
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/CHANGELOG.md +228 -0
- package/NOTICE.txt +250 -0
- package/README.md +2 -1
- package/dist/cli.js +80 -49
- package/dist/cli.js.map +1 -1
- package/dist/common_types.d.ts +77 -10
- package/dist/common_types.d.ts.map +1 -1
- package/dist/config.d.ts +2 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/core/expect.d.ts +177 -0
- package/dist/core/expect.d.ts.map +1 -0
- package/dist/core/expect.js +33 -0
- package/dist/core/expect.js.map +1 -0
- package/dist/core/gatherer.d.ts +4 -7
- package/dist/core/gatherer.d.ts.map +1 -1
- package/dist/core/gatherer.js +33 -9
- package/dist/core/gatherer.js.map +1 -1
- package/dist/core/index.d.ts +5 -5
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/logger.d.ts +0 -1
- package/dist/core/logger.d.ts.map +1 -1
- package/dist/core/logger.js +2 -15
- package/dist/core/logger.js.map +1 -1
- package/dist/core/runner.d.ts +54 -45
- package/dist/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +173 -63
- package/dist/core/runner.js.map +1 -1
- package/dist/dsl/journey.d.ts +13 -4
- package/dist/dsl/journey.d.ts.map +1 -1
- package/dist/dsl/journey.js +40 -1
- package/dist/dsl/journey.js.map +1 -1
- package/dist/formatter/javascript.d.ts +73 -0
- package/dist/formatter/javascript.d.ts.map +1 -0
- package/dist/formatter/javascript.js +274 -0
- package/dist/formatter/javascript.js.map +1 -0
- package/dist/helpers.d.ts +33 -12
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +100 -46
- package/dist/helpers.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/parse_args.d.ts +5 -2
- package/dist/parse_args.d.ts.map +1 -1
- package/dist/parse_args.js +59 -16
- package/dist/parse_args.js.map +1 -1
- package/dist/plugins/browser-console.d.ts +5 -8
- package/dist/plugins/browser-console.d.ts.map +1 -1
- package/dist/plugins/browser-console.js +26 -7
- package/dist/plugins/browser-console.js.map +1 -1
- package/dist/plugins/network.d.ts +20 -20
- package/dist/plugins/network.d.ts.map +1 -1
- package/dist/plugins/network.js +110 -108
- package/dist/plugins/network.js.map +1 -1
- package/dist/plugins/performance.d.ts +5 -5
- package/dist/plugins/performance.d.ts.map +1 -1
- package/dist/plugins/performance.js +5 -5
- package/dist/plugins/performance.js.map +1 -1
- package/dist/plugins/plugin-manager.d.ts +11 -11
- package/dist/plugins/plugin-manager.d.ts.map +1 -1
- package/dist/plugins/plugin-manager.js +40 -24
- package/dist/plugins/plugin-manager.js.map +1 -1
- package/dist/plugins/tracing.d.ts +10 -25
- package/dist/plugins/tracing.d.ts.map +1 -1
- package/dist/plugins/tracing.js +40 -26
- package/dist/plugins/tracing.js.map +1 -1
- package/dist/reporters/base.d.ts +0 -1
- package/dist/reporters/base.d.ts.map +1 -1
- package/dist/reporters/base.js +22 -23
- package/dist/reporters/base.js.map +1 -1
- package/dist/reporters/json.d.ts +43 -7
- package/dist/reporters/json.d.ts.map +1 -1
- package/dist/reporters/json.js +181 -35
- package/dist/reporters/json.js.map +1 -1
- package/dist/sdk/lh-trace-processor.d.ts +304 -0
- package/dist/sdk/lh-trace-processor.d.ts.map +1 -0
- package/dist/sdk/lh-trace-processor.js +832 -0
- package/dist/sdk/lh-trace-processor.js.map +1 -0
- package/dist/sdk/trace-metrics.d.ts +61 -0
- package/dist/sdk/trace-metrics.d.ts.map +1 -0
- package/dist/sdk/trace-metrics.js +252 -0
- package/dist/sdk/trace-metrics.js.map +1 -0
- package/dist/sdk/trace-processor.d.ts +106 -0
- package/dist/sdk/trace-processor.d.ts.map +1 -0
- package/dist/sdk/trace-processor.js +74 -0
- package/dist/sdk/trace-processor.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1575
- package/package.json +24 -13
- package/src/cli.ts +68 -45
- package/src/common_types.ts +92 -10
- package/src/config.ts +2 -5
- package/src/core/expect.ts +187 -0
- package/src/core/gatherer.ts +44 -23
- package/src/core/index.ts +6 -6
- package/src/core/logger.ts +1 -12
- package/src/core/runner.ts +259 -112
- package/src/dsl/journey.ts +28 -6
- package/src/formatter/javascript.ts +330 -0
- package/src/helpers.ts +114 -24
- package/src/index.ts +7 -6
- package/src/parse_args.ts +97 -22
- package/src/plugins/browser-console.ts +30 -13
- package/src/plugins/network.ts +137 -144
- package/src/plugins/performance.ts +7 -7
- package/src/plugins/plugin-manager.ts +47 -36
- package/src/plugins/tracing.ts +43 -54
- package/src/reporters/base.ts +24 -23
- package/src/reporters/json.ts +251 -41
- package/src/sdk/lh-trace-processor.ts +1033 -0
- package/src/sdk/trace-metrics.ts +287 -0
- package/src/sdk/trace-processor.ts +147 -0
package/src/reporters/json.ts
CHANGED
|
@@ -23,13 +23,32 @@
|
|
|
23
23
|
*
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
|
+
import { readFileSync } from 'fs';
|
|
27
|
+
import { join } from 'path';
|
|
28
|
+
import sharp from 'sharp';
|
|
29
|
+
import { createHash } from 'crypto';
|
|
26
30
|
import BaseReporter from './base';
|
|
27
|
-
import {
|
|
31
|
+
import {
|
|
32
|
+
formatError,
|
|
33
|
+
getTimestamp,
|
|
34
|
+
CACHE_PATH,
|
|
35
|
+
totalist,
|
|
36
|
+
isDirectory,
|
|
37
|
+
getDurationInUs,
|
|
38
|
+
} from '../helpers';
|
|
28
39
|
import { Journey, Step } from '../dsl';
|
|
29
40
|
import snakeCaseKeys from 'snakecase-keys';
|
|
30
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
NetworkInfo,
|
|
43
|
+
NetworkConditions,
|
|
44
|
+
TraceOutput,
|
|
45
|
+
StatusValue,
|
|
46
|
+
PerfMetrics,
|
|
47
|
+
Params,
|
|
48
|
+
Screenshot,
|
|
49
|
+
} from '../common_types';
|
|
31
50
|
import { Protocol } from 'playwright-chromium/types/protocol';
|
|
32
|
-
import {
|
|
51
|
+
import { PageMetrics } from '../plugins';
|
|
33
52
|
|
|
34
53
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
35
54
|
const { version, name } = require('../../package.json');
|
|
@@ -38,10 +57,13 @@ type OutputType =
|
|
|
38
57
|
| 'synthetics/metadata'
|
|
39
58
|
| 'journey/register'
|
|
40
59
|
| 'journey/start'
|
|
60
|
+
| 'screenshot/block'
|
|
61
|
+
| 'step/screenshot_ref'
|
|
41
62
|
| 'step/screenshot'
|
|
63
|
+
| 'step/metrics'
|
|
64
|
+
| 'step/filmstrips'
|
|
42
65
|
| 'step/end'
|
|
43
66
|
| 'journey/network_info'
|
|
44
|
-
| 'journey/filmstrips'
|
|
45
67
|
| 'journey/browserconsole'
|
|
46
68
|
| 'journey/end';
|
|
47
69
|
|
|
@@ -51,19 +73,25 @@ type Payload = {
|
|
|
51
73
|
end?: number;
|
|
52
74
|
url?: string;
|
|
53
75
|
status?: StatusValue | number;
|
|
54
|
-
|
|
55
|
-
params?:
|
|
76
|
+
pagemetrics?: PageMetrics;
|
|
77
|
+
params?: Params;
|
|
56
78
|
type?: OutputType;
|
|
57
79
|
text?: string;
|
|
58
80
|
index?: number;
|
|
81
|
+
network_conditions?: NetworkConditions;
|
|
59
82
|
};
|
|
60
83
|
|
|
61
84
|
type OutputFields = {
|
|
62
85
|
type: OutputType;
|
|
86
|
+
_id?: string;
|
|
63
87
|
journey?: Journey;
|
|
64
88
|
timestamp?: number;
|
|
65
89
|
url?: string;
|
|
66
|
-
step?: Partial<Step
|
|
90
|
+
step?: Partial<Step> & {
|
|
91
|
+
duration?: {
|
|
92
|
+
us: number;
|
|
93
|
+
};
|
|
94
|
+
};
|
|
67
95
|
error?: Error;
|
|
68
96
|
root_fields?: Record<string, unknown>;
|
|
69
97
|
payload?: Payload | NetworkInfo;
|
|
@@ -71,6 +99,23 @@ type OutputFields = {
|
|
|
71
99
|
blob_mime?: string;
|
|
72
100
|
};
|
|
73
101
|
|
|
102
|
+
type ScreenshotBlob = {
|
|
103
|
+
blob: string;
|
|
104
|
+
id: string;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
type ScreenshotReference = {
|
|
108
|
+
width: number;
|
|
109
|
+
height: number;
|
|
110
|
+
blocks: Array<{
|
|
111
|
+
hash: string;
|
|
112
|
+
top: number;
|
|
113
|
+
left: number;
|
|
114
|
+
width: number;
|
|
115
|
+
height: number;
|
|
116
|
+
}>;
|
|
117
|
+
};
|
|
118
|
+
|
|
74
119
|
function getMetadata() {
|
|
75
120
|
return {
|
|
76
121
|
os: {
|
|
@@ -200,6 +245,7 @@ function journeyInfo(
|
|
|
200
245
|
return {
|
|
201
246
|
name: journey.name,
|
|
202
247
|
id: journey.id,
|
|
248
|
+
tags: journey.tags,
|
|
203
249
|
status: type === 'journey/end' ? status : undefined,
|
|
204
250
|
};
|
|
205
251
|
}
|
|
@@ -216,21 +262,103 @@ function stepInfo(
|
|
|
216
262
|
name: step.name,
|
|
217
263
|
index: step.index,
|
|
218
264
|
status: type === 'step/end' ? status : undefined,
|
|
265
|
+
duration: step.duration,
|
|
219
266
|
};
|
|
220
267
|
}
|
|
221
268
|
|
|
269
|
+
export async function getScreenshotBlocks(screenshot: Buffer) {
|
|
270
|
+
const img = sharp(screenshot, { sequentialRead: true });
|
|
271
|
+
const { width, height } = await img.metadata();
|
|
272
|
+
/**
|
|
273
|
+
* Chop the screenshot image (1280*720) which is the default
|
|
274
|
+
* viewport size in to 64 equal blocks for a given image
|
|
275
|
+
* which can be acheived by keeping the division to 8
|
|
276
|
+
*
|
|
277
|
+
* Changing division to 16 would yield us 256 smaller blocks, but it is not
|
|
278
|
+
* optimal for caching in the ES and proved out to be bad, so we stick to 8
|
|
279
|
+
*/
|
|
280
|
+
const divisions = 8;
|
|
281
|
+
const blockWidth = Math.floor(width / divisions);
|
|
282
|
+
const blockHeight = Math.floor(height / divisions);
|
|
283
|
+
const reference: ScreenshotReference = {
|
|
284
|
+
width,
|
|
285
|
+
height,
|
|
286
|
+
blocks: [],
|
|
287
|
+
};
|
|
288
|
+
const blocks: Array<ScreenshotBlob> = [];
|
|
289
|
+
|
|
290
|
+
for (let row = 0; row < divisions; row++) {
|
|
291
|
+
const top = row * blockHeight;
|
|
292
|
+
for (let col = 0; col < divisions; col++) {
|
|
293
|
+
const left = col * blockWidth;
|
|
294
|
+
const buf = await img
|
|
295
|
+
.extract({ top, left, width: blockWidth, height: blockHeight })
|
|
296
|
+
.jpeg()
|
|
297
|
+
.toBuffer();
|
|
298
|
+
|
|
299
|
+
const hash = createHash('sha1').update(buf).digest('hex');
|
|
300
|
+
blocks.push({
|
|
301
|
+
blob: buf.toString('base64'),
|
|
302
|
+
id: hash,
|
|
303
|
+
});
|
|
304
|
+
/**
|
|
305
|
+
* We dont write the width, height of individual blocks on the
|
|
306
|
+
* reference as we use similar sized blocks for each extraction,
|
|
307
|
+
* we would need to send the width and height here if we decide to
|
|
308
|
+
* go with dynamic block extraction.
|
|
309
|
+
*/
|
|
310
|
+
reference.blocks.push({
|
|
311
|
+
hash,
|
|
312
|
+
top,
|
|
313
|
+
left,
|
|
314
|
+
width: blockWidth,
|
|
315
|
+
height: blockHeight,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
return { blocks, reference, blob_mime: 'image/jpeg' };
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Get all the screenshots from the cached screenshot location
|
|
325
|
+
* at the end of each journey and construct equally sized blocks out
|
|
326
|
+
* of the individual screenshot image.
|
|
327
|
+
*/
|
|
328
|
+
export async function gatherScreenshots(
|
|
329
|
+
screenshotsPath: string,
|
|
330
|
+
callback: (data: Screenshot) => Promise<void>
|
|
331
|
+
) {
|
|
332
|
+
if (isDirectory(screenshotsPath)) {
|
|
333
|
+
await totalist(screenshotsPath, async (_, absPath) => {
|
|
334
|
+
try {
|
|
335
|
+
const content = readFileSync(absPath, 'utf8');
|
|
336
|
+
const screenshot: Screenshot = JSON.parse(content);
|
|
337
|
+
await callback(screenshot);
|
|
338
|
+
} catch (_) {
|
|
339
|
+
// TODO: capture progarammatic synthetic errors under different type
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
222
345
|
export default class JSONReporter extends BaseReporter {
|
|
223
346
|
_registerListeners() {
|
|
224
347
|
/**
|
|
225
348
|
* report the number of journeys that exists on a suite which
|
|
226
349
|
* could be used for better sharding
|
|
227
350
|
*/
|
|
228
|
-
this.runner.on('start', ({ numJourneys }) => {
|
|
351
|
+
this.runner.on('start', ({ numJourneys, networkConditions }) => {
|
|
229
352
|
this.writeJSON({
|
|
230
353
|
type: 'synthetics/metadata',
|
|
231
354
|
root_fields: {
|
|
232
355
|
num_journeys: numJourneys,
|
|
233
356
|
},
|
|
357
|
+
payload: networkConditions
|
|
358
|
+
? {
|
|
359
|
+
network_conditions: networkConditions,
|
|
360
|
+
}
|
|
361
|
+
: undefined,
|
|
234
362
|
});
|
|
235
363
|
});
|
|
236
364
|
|
|
@@ -258,33 +386,47 @@ export default class JSONReporter extends BaseReporter {
|
|
|
258
386
|
start,
|
|
259
387
|
end,
|
|
260
388
|
error,
|
|
261
|
-
screenshot,
|
|
262
389
|
url,
|
|
263
390
|
status,
|
|
391
|
+
pagemetrics,
|
|
392
|
+
traces,
|
|
264
393
|
metrics,
|
|
394
|
+
filmstrips,
|
|
265
395
|
}) => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
396
|
+
this.writeMetrics(journey, step, 'relative_trace', traces);
|
|
397
|
+
this.writeMetrics(journey, step, 'experience', metrics);
|
|
398
|
+
if (filmstrips) {
|
|
399
|
+
// Write each filmstrip separately so that we don't get documents that are too large
|
|
400
|
+
filmstrips.forEach((strip, index) => {
|
|
401
|
+
this.writeJSON({
|
|
402
|
+
type: 'step/filmstrips',
|
|
403
|
+
journey,
|
|
404
|
+
step,
|
|
405
|
+
payload: { index },
|
|
406
|
+
root_fields: {
|
|
407
|
+
browser: { relative_trace: { start: strip.start } },
|
|
408
|
+
},
|
|
409
|
+
blob: strip.blob,
|
|
410
|
+
blob_mime: strip.mime,
|
|
411
|
+
});
|
|
273
412
|
});
|
|
274
413
|
}
|
|
275
414
|
this.writeJSON({
|
|
276
415
|
type: 'step/end',
|
|
277
416
|
journey,
|
|
278
|
-
step
|
|
417
|
+
step: {
|
|
418
|
+
...step,
|
|
419
|
+
duration: {
|
|
420
|
+
us: getDurationInUs(end - start),
|
|
421
|
+
},
|
|
422
|
+
},
|
|
279
423
|
url,
|
|
280
424
|
error,
|
|
281
425
|
payload: {
|
|
282
426
|
source: step.callback.toString(),
|
|
283
|
-
start,
|
|
284
|
-
end,
|
|
285
427
|
url,
|
|
286
428
|
status,
|
|
287
|
-
|
|
429
|
+
pagemetrics,
|
|
288
430
|
},
|
|
289
431
|
});
|
|
290
432
|
}
|
|
@@ -292,16 +434,45 @@ export default class JSONReporter extends BaseReporter {
|
|
|
292
434
|
|
|
293
435
|
this.runner.on(
|
|
294
436
|
'journey:end',
|
|
295
|
-
({
|
|
437
|
+
async ({
|
|
296
438
|
journey,
|
|
439
|
+
timestamp,
|
|
297
440
|
start,
|
|
298
441
|
end,
|
|
299
|
-
filmstrips,
|
|
300
442
|
networkinfo,
|
|
301
443
|
browserconsole,
|
|
302
444
|
status,
|
|
303
445
|
error,
|
|
446
|
+
options,
|
|
304
447
|
}) => {
|
|
448
|
+
const { ssblocks, screenshots } = options;
|
|
449
|
+
const writeScreenshots =
|
|
450
|
+
screenshots === 'on' ||
|
|
451
|
+
(screenshots === 'only-on-failure' && status === 'failed');
|
|
452
|
+
if (writeScreenshots) {
|
|
453
|
+
await gatherScreenshots(
|
|
454
|
+
join(CACHE_PATH, 'screenshots'),
|
|
455
|
+
async screenshot => {
|
|
456
|
+
const { data, timestamp, step } = screenshot;
|
|
457
|
+
if (!data) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
if (ssblocks) {
|
|
461
|
+
await this.writeScreenshotBlocks(journey, screenshot);
|
|
462
|
+
} else {
|
|
463
|
+
this.writeJSON({
|
|
464
|
+
type: 'step/screenshot',
|
|
465
|
+
timestamp,
|
|
466
|
+
journey,
|
|
467
|
+
step,
|
|
468
|
+
blob: data,
|
|
469
|
+
blob_mime: 'image/jpeg',
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
|
|
305
476
|
if (networkinfo) {
|
|
306
477
|
networkinfo.forEach(ni => {
|
|
307
478
|
const { ecs, payload } = formatNetworkFields(ni);
|
|
@@ -315,37 +486,26 @@ export default class JSONReporter extends BaseReporter {
|
|
|
315
486
|
});
|
|
316
487
|
});
|
|
317
488
|
}
|
|
318
|
-
if (filmstrips) {
|
|
319
|
-
// Write each filmstrip separately so that we don't get documents that are too large
|
|
320
|
-
filmstrips.forEach((strip, index) => {
|
|
321
|
-
this.writeJSON({
|
|
322
|
-
type: 'journey/filmstrips',
|
|
323
|
-
journey,
|
|
324
|
-
payload: {
|
|
325
|
-
index,
|
|
326
|
-
...{
|
|
327
|
-
startTime: strip.startTime,
|
|
328
|
-
ts: strip.ts,
|
|
329
|
-
},
|
|
330
|
-
},
|
|
331
|
-
blob: strip.snapshot,
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
489
|
if (browserconsole) {
|
|
336
|
-
browserconsole.forEach(({ timestamp, text, type, step }) => {
|
|
490
|
+
browserconsole.forEach(({ timestamp, text, type, step, error }) => {
|
|
337
491
|
this.writeJSON({
|
|
338
492
|
type: 'journey/browserconsole',
|
|
339
493
|
journey,
|
|
340
494
|
timestamp,
|
|
341
495
|
step,
|
|
342
|
-
|
|
496
|
+
error,
|
|
497
|
+
payload: {
|
|
498
|
+
text,
|
|
499
|
+
type,
|
|
500
|
+
} as Payload,
|
|
343
501
|
});
|
|
344
502
|
});
|
|
345
503
|
}
|
|
504
|
+
|
|
346
505
|
this.writeJSON({
|
|
347
506
|
type: 'journey/end',
|
|
348
507
|
journey,
|
|
508
|
+
timestamp,
|
|
349
509
|
error,
|
|
350
510
|
payload: {
|
|
351
511
|
start,
|
|
@@ -353,16 +513,65 @@ export default class JSONReporter extends BaseReporter {
|
|
|
353
513
|
status,
|
|
354
514
|
},
|
|
355
515
|
});
|
|
516
|
+
process.nextTick(() => this.runner.emit('journey:end:reported', {}));
|
|
356
517
|
}
|
|
357
518
|
);
|
|
358
519
|
}
|
|
359
520
|
|
|
521
|
+
async writeScreenshotBlocks(journey: Journey, screenshot: Screenshot) {
|
|
522
|
+
const { blob_mime, blocks, reference } = await getScreenshotBlocks(
|
|
523
|
+
Buffer.from(screenshot.data, 'base64')
|
|
524
|
+
);
|
|
525
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
526
|
+
const block = blocks[i];
|
|
527
|
+
this.writeJSON({
|
|
528
|
+
type: 'screenshot/block',
|
|
529
|
+
timestamp: screenshot.timestamp,
|
|
530
|
+
_id: block.id,
|
|
531
|
+
blob: block.blob,
|
|
532
|
+
blob_mime,
|
|
533
|
+
});
|
|
534
|
+
}
|
|
535
|
+
this.writeJSON({
|
|
536
|
+
type: 'step/screenshot_ref',
|
|
537
|
+
timestamp: screenshot.timestamp,
|
|
538
|
+
journey,
|
|
539
|
+
step: screenshot.step,
|
|
540
|
+
root_fields: {
|
|
541
|
+
screenshot_ref: reference,
|
|
542
|
+
},
|
|
543
|
+
});
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
writeMetrics(
|
|
547
|
+
journey: Journey,
|
|
548
|
+
step: Step,
|
|
549
|
+
type: string,
|
|
550
|
+
events: Array<TraceOutput> | PerfMetrics
|
|
551
|
+
) {
|
|
552
|
+
const metrics = Array.isArray(events) ? events : [events];
|
|
553
|
+
metrics.forEach(event => {
|
|
554
|
+
event &&
|
|
555
|
+
this.writeJSON({
|
|
556
|
+
type: 'step/metrics',
|
|
557
|
+
journey,
|
|
558
|
+
step,
|
|
559
|
+
root_fields: {
|
|
560
|
+
browser: {
|
|
561
|
+
[type]: event,
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
});
|
|
565
|
+
});
|
|
566
|
+
}
|
|
567
|
+
|
|
360
568
|
// Writes a structured synthetics event
|
|
361
569
|
// Note that blob is ultimately stored in ES as a base64 encoded string. You must base 64 encode
|
|
362
570
|
// it before passing it into this function!
|
|
363
571
|
// The payload field is an un-indexed field with no ES mapping, so users can put arbitary structured
|
|
364
572
|
// stuff in there
|
|
365
573
|
writeJSON({
|
|
574
|
+
_id,
|
|
366
575
|
journey,
|
|
367
576
|
type,
|
|
368
577
|
timestamp,
|
|
@@ -376,6 +585,7 @@ export default class JSONReporter extends BaseReporter {
|
|
|
376
585
|
}: OutputFields) {
|
|
377
586
|
this.write({
|
|
378
587
|
type,
|
|
588
|
+
_id,
|
|
379
589
|
'@timestamp': timestamp || getTimestamp(),
|
|
380
590
|
journey: journeyInfo(journey, type, payload?.status),
|
|
381
591
|
step: stepInfo(step, type, payload?.status),
|