@elastic/synthetics 1.0.0-beta.37 → 1.0.0-beta.39
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/core/runner.d.ts.map +1 -1
- package/dist/core/runner.js +1 -0
- package/dist/core/runner.js.map +1 -1
- package/dist/dsl/monitor.d.ts +3 -1
- package/dist/dsl/monitor.d.ts.map +1 -1
- package/dist/dsl/monitor.js +17 -1
- package/dist/dsl/monitor.js.map +1 -1
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +10 -3
- package/dist/generator/index.js.map +1 -1
- package/dist/generator/utils.d.ts.map +1 -1
- package/dist/generator/utils.js +1 -0
- package/dist/generator/utils.js.map +1 -1
- package/dist/helpers.d.ts +3 -1
- package/dist/helpers.d.ts.map +1 -1
- package/dist/helpers.js +16 -4
- package/dist/helpers.js.map +1 -1
- package/dist/push/index.d.ts.map +1 -1
- package/dist/push/index.js +28 -22
- package/dist/push/index.js.map +1 -1
- package/dist/push/monitor.d.ts +2 -1
- package/dist/push/monitor.d.ts.map +1 -1
- package/dist/push/monitor.js +29 -6
- package/dist/push/monitor.js.map +1 -1
- package/dist/push/plugin.d.ts.map +1 -1
- package/dist/push/plugin.js +20 -3
- package/dist/push/plugin.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +9 -9
- package/src/core/runner.ts +1 -0
- package/src/dsl/monitor.ts +22 -1
- package/src/generator/index.ts +15 -6
- package/src/generator/utils.ts +1 -0
- package/src/helpers.ts +15 -3
- package/src/push/index.ts +32 -24
- package/src/push/monitor.ts +29 -8
- package/src/push/plugin.ts +19 -3
- package/templates/.github/workflows/run-synthetics.yml +9 -8
- package/templates/lightweight/heartbeat.yml +7 -0
package/src/push/index.ts
CHANGED
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
import { readFile, writeFile } from 'fs/promises';
|
|
27
27
|
import { prompt } from 'enquirer';
|
|
28
|
-
import { bold } from 'kleur/colors';
|
|
28
|
+
import { bold, grey } from 'kleur/colors';
|
|
29
29
|
import {
|
|
30
30
|
ok,
|
|
31
31
|
formatAPIError,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
formatStaleMonitors,
|
|
35
35
|
} from './request';
|
|
36
36
|
import { buildMonitorSchema, createMonitors, MonitorSchema } from './monitor';
|
|
37
|
-
import { Monitor } from '../dsl/monitor';
|
|
37
|
+
import { ALLOWED_SCHEDULES, Monitor } from '../dsl/monitor';
|
|
38
38
|
import {
|
|
39
39
|
progress,
|
|
40
40
|
apiProgress,
|
|
@@ -44,6 +44,8 @@ import {
|
|
|
44
44
|
indent,
|
|
45
45
|
safeNDJSONParse,
|
|
46
46
|
done,
|
|
47
|
+
getMonitorManagementURL,
|
|
48
|
+
getArrayChunks,
|
|
47
49
|
} from '../helpers';
|
|
48
50
|
import type { PushOptions, ProjectSettings } from '../common_types';
|
|
49
51
|
import { findSyntheticsConfig, readConfig } from '../config';
|
|
@@ -60,8 +62,9 @@ export async function push(monitors: Monitor[], options: PushOptions) {
|
|
|
60
62
|
schemas = await buildMonitorSchema(monitors);
|
|
61
63
|
|
|
62
64
|
progress(`creating all monitors`);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
+
const chunks = getArrayChunks(schemas, 10);
|
|
66
|
+
for (const chunk of chunks) {
|
|
67
|
+
await pushMonitors({ schemas: chunk, keepStale: true, options });
|
|
65
68
|
}
|
|
66
69
|
} else {
|
|
67
70
|
write('');
|
|
@@ -85,7 +88,7 @@ export async function push(monitors: Monitor[], options: PushOptions) {
|
|
|
85
88
|
progress(`deleting all stale monitors`);
|
|
86
89
|
await pushMonitors({ schemas, keepStale: false, options });
|
|
87
90
|
|
|
88
|
-
done(
|
|
91
|
+
done(`Pushed: ${grey(getMonitorManagementURL(options.url))}`);
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
export async function pushMonitors({
|
|
@@ -109,26 +112,27 @@ export async function pushMonitors({
|
|
|
109
112
|
const { error, message } = await body.json();
|
|
110
113
|
throw formatAPIError(statusCode, error, message);
|
|
111
114
|
}
|
|
112
|
-
|
|
115
|
+
const allchunks = [];
|
|
113
116
|
for await (const data of body) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
117
|
+
allchunks.push(Buffer.from(data));
|
|
118
|
+
}
|
|
119
|
+
const chunks = safeNDJSONParse(Buffer.concat(allchunks).toString('utf-8'));
|
|
120
|
+
// Its kind of hacky for now where Kibana streams the response by
|
|
121
|
+
// writing the data as NDJSON events (data can be interleaved), we
|
|
122
|
+
// distinguish the final data by checking if the event was a progress vs complete event
|
|
123
|
+
for (const chunk of chunks) {
|
|
124
|
+
if (typeof chunk === 'string') {
|
|
125
|
+
// TODO: add progress back for all states once we get the fix
|
|
126
|
+
// on kibana side
|
|
127
|
+
keepStale && apiProgress(chunk);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const { failedMonitors, failedStaleMonitors } = chunk;
|
|
131
|
+
if (failedMonitors && failedMonitors.length > 0) {
|
|
132
|
+
throw formatFailedMonitors(failedMonitors);
|
|
133
|
+
}
|
|
134
|
+
if (failedStaleMonitors.length > 0) {
|
|
135
|
+
throw formatStaleMonitors(failedStaleMonitors);
|
|
132
136
|
}
|
|
133
137
|
}
|
|
134
138
|
}
|
|
@@ -192,6 +196,10 @@ export function validateSettings(opts: PushOptions) {
|
|
|
192
196
|
reason = `Set default schedule in minutes for all monitors via
|
|
193
197
|
- CLI '--schedule <mins>'
|
|
194
198
|
- Config file 'monitors.schedule' field`;
|
|
199
|
+
} else if (opts.schedule && !ALLOWED_SCHEDULES.includes(opts.schedule)) {
|
|
200
|
+
reason = `Set default schedule(${
|
|
201
|
+
opts.schedule
|
|
202
|
+
}) to one of the allowed values - ${ALLOWED_SCHEDULES.join(',')}`;
|
|
195
203
|
}
|
|
196
204
|
|
|
197
205
|
if (!reason) return;
|
package/src/push/monitor.ts
CHANGED
|
@@ -37,7 +37,7 @@ import {
|
|
|
37
37
|
warn,
|
|
38
38
|
} from '../helpers';
|
|
39
39
|
import { LocationsMap } from '../locations/public-locations';
|
|
40
|
-
import { Monitor, MonitorConfig } from '../dsl/monitor';
|
|
40
|
+
import { ALLOWED_SCHEDULES, Monitor, MonitorConfig } from '../dsl/monitor';
|
|
41
41
|
import { PushOptions } from '../common_types';
|
|
42
42
|
|
|
43
43
|
export type MonitorSchema = Omit<MonitorConfig, 'locations'> & {
|
|
@@ -95,13 +95,8 @@ export async function createLightweightMonitors(
|
|
|
95
95
|
lwFiles.add(abs);
|
|
96
96
|
}
|
|
97
97
|
});
|
|
98
|
-
// Warn users about schedule that are less than 60 seconds
|
|
99
|
-
if (lwFiles.size > 0) {
|
|
100
|
-
warn(
|
|
101
|
-
'lightweight monitors schedule < 1 minute resolution are not supported, will get reset to their nearest minute interval.'
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
98
|
|
|
99
|
+
let warnOnce = false;
|
|
105
100
|
const monitors: Monitor[] = [];
|
|
106
101
|
for (const file of lwFiles.values()) {
|
|
107
102
|
const content = await readFile(file, 'utf-8');
|
|
@@ -115,6 +110,13 @@ export async function createLightweightMonitors(
|
|
|
115
110
|
if (!monitorSeq) {
|
|
116
111
|
continue;
|
|
117
112
|
}
|
|
113
|
+
// Warn users about schedule that are less than 60 seconds
|
|
114
|
+
if (!warnOnce) {
|
|
115
|
+
warn(
|
|
116
|
+
'If you are using lightweight monitors with less than 1 minute resolution, these will be saved to the nearest supported frequency'
|
|
117
|
+
);
|
|
118
|
+
warnOnce = true;
|
|
119
|
+
}
|
|
118
120
|
|
|
119
121
|
for (const monNode of monitorSeq.items) {
|
|
120
122
|
// Skip browser monitors and disabled monitors from pushing
|
|
@@ -193,7 +195,26 @@ export function parseSchedule(schedule: string) {
|
|
|
193
195
|
break;
|
|
194
196
|
}
|
|
195
197
|
}
|
|
196
|
-
return minutes;
|
|
198
|
+
return nearestSchedule(minutes);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Find the nearest schedule that is supported by the platform
|
|
202
|
+
// from the parsed schedule value
|
|
203
|
+
export function nearestSchedule(schedule: number) {
|
|
204
|
+
let start = 0;
|
|
205
|
+
let end = ALLOWED_SCHEDULES.length - 1;
|
|
206
|
+
while (start <= end) {
|
|
207
|
+
const mid = Math.floor((start + end) / 2);
|
|
208
|
+
const midValue = ALLOWED_SCHEDULES[mid];
|
|
209
|
+
if (midValue === schedule) {
|
|
210
|
+
return midValue;
|
|
211
|
+
} else if (midValue < schedule) {
|
|
212
|
+
start = mid + 1;
|
|
213
|
+
} else {
|
|
214
|
+
end = mid - 1;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return ALLOWED_SCHEDULES[end];
|
|
197
218
|
}
|
|
198
219
|
|
|
199
220
|
export async function createMonitors(
|
package/src/push/plugin.ts
CHANGED
|
@@ -39,6 +39,11 @@ export function commonOptions(): esbuild.BuildOptions {
|
|
|
39
39
|
bundle: true,
|
|
40
40
|
external: ['@elastic/synthetics'],
|
|
41
41
|
minify: false,
|
|
42
|
+
minifyIdentifiers: false,
|
|
43
|
+
minifySyntax: false,
|
|
44
|
+
minifyWhitespace: false,
|
|
45
|
+
treeShaking: false,
|
|
46
|
+
keepNames: false,
|
|
42
47
|
platform: 'node',
|
|
43
48
|
logLevel: 'silent',
|
|
44
49
|
format: 'esm',
|
|
@@ -108,7 +113,7 @@ export function MultiAssetPlugin(callback: PluginCallback): esbuild.Plugin {
|
|
|
108
113
|
if (args.kind === 'entry-point') {
|
|
109
114
|
return {
|
|
110
115
|
path: args.path,
|
|
111
|
-
namespace: '
|
|
116
|
+
namespace: 'journey',
|
|
112
117
|
};
|
|
113
118
|
}
|
|
114
119
|
|
|
@@ -142,10 +147,21 @@ export function MultiAssetPlugin(callback: PluginCallback): esbuild.Plugin {
|
|
|
142
147
|
};
|
|
143
148
|
});
|
|
144
149
|
|
|
145
|
-
build.onLoad({ filter: /.*?/, namespace: '
|
|
150
|
+
build.onLoad({ filter: /.*?/, namespace: 'journey' }, async args => {
|
|
146
151
|
const contents = await fs.readFile(args.path, 'utf-8');
|
|
147
152
|
callback({ path: args.path, contents });
|
|
148
|
-
|
|
153
|
+
|
|
154
|
+
// Use correct loader for the journey entry path
|
|
155
|
+
let loader: esbuild.Loader = 'default';
|
|
156
|
+
const ext = extname(args.path).slice(1);
|
|
157
|
+
if (ext === 'cjs' || ext === 'mjs') {
|
|
158
|
+
loader = 'js';
|
|
159
|
+
} else if (ext === 'cts' || ext === 'mts') {
|
|
160
|
+
loader = 'ts';
|
|
161
|
+
} else {
|
|
162
|
+
loader = ext as esbuild.Loader;
|
|
163
|
+
}
|
|
164
|
+
return { contents, loader };
|
|
149
165
|
});
|
|
150
166
|
},
|
|
151
167
|
};
|
|
@@ -8,19 +8,20 @@ on:
|
|
|
8
8
|
- cron: '* 0 * * *'
|
|
9
9
|
jobs:
|
|
10
10
|
test:
|
|
11
|
+
defaults:
|
|
12
|
+
run:
|
|
13
|
+
working-directory: ./advanced-examples
|
|
11
14
|
runs-on: ubuntu-latest
|
|
12
15
|
steps:
|
|
13
|
-
- uses: actions/checkout@
|
|
14
|
-
- uses: actions/setup-node@
|
|
16
|
+
- uses: actions/checkout@v3
|
|
17
|
+
- uses: actions/setup-node@v3
|
|
15
18
|
with:
|
|
16
|
-
node-version:
|
|
19
|
+
node-version: 18
|
|
17
20
|
- run: npm install
|
|
18
21
|
- run: "SYNTHETICS_JUNIT_FILE='junit-synthetics.xml' npx @elastic/synthetics . --reporter=junit"
|
|
19
|
-
continue-on-error: true
|
|
20
22
|
- name: Publish Unit Test Results
|
|
21
|
-
uses: EnricoMi/publish-unit-test-result-action@
|
|
23
|
+
uses: EnricoMi/publish-unit-test-result-action@v2
|
|
22
24
|
if: always()
|
|
23
25
|
with:
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
check_name: Elastic Synthetics Tests
|
|
26
|
+
junit_files: '**/junit-*.xml'
|
|
27
|
+
check_name: Elastic Synthetics Tests
|