[kbn-performance-testing-dataset-extractor] update json structure, filter out static resources on ci (#136651)

* [kbn-performance-testing-dataset-extractor] update json structure, filter out static res on ci

* convert body to string

* update schema and ftr configs

* update extractor

* fix headers combining

* update json structure

* re-order fields for easy read
This commit is contained in:
Dzmitry Lemechko 2022-07-21 10:42:36 +02:00 committed by GitHub
parent 184f8070aa
commit 10cd177456
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 100 additions and 98 deletions

View file

@ -24,7 +24,8 @@ for i in "${scalabilityJourneys[@]}"; do
--buildId "${BUILD_ID}" \
--es-url "${ES_SERVER_URL}" \
--es-username "${USER_FROM_VAULT}" \
--es-password "${PASS_FROM_VAULT}"
--es-password "${PASS_FROM_VAULT}" \
--without-static-resources
done
echo "--- Upload Kibana build, plugins and scalability traces to the public bucket"

View file

@ -22,9 +22,13 @@ interface Labels {
maxUsersCount: string;
}
export interface Headers {
readonly [key: string]: string[];
}
interface Request {
method: string;
headers: string;
headers: Headers;
body?: { original: string };
}
@ -44,6 +48,7 @@ export interface Document {
character: string;
quote: string;
service: { version: string };
parent?: { id: string };
processor: string;
trace: { id: string };
'@timestamp': string;

View file

@ -12,7 +12,7 @@ import { existsSync } from 'fs';
import path from 'path';
import { ToolingLog } from '@kbn/tooling-log';
import { SearchHit } from '@elastic/elasticsearch/lib/api/types';
import { initClient, Document } from './es_client';
import { initClient, Document, Headers } from './es_client';
const DATE_FORMAT = `YYYY-MM-DD'T'HH:mm:ss.SSS'Z'`;
const STATIC_RESOURCES_PATTERN = /\.(css|ico|js|json|jpeg|jpg|gif|png|otf|ttf|woff|woff2)$/;
@ -32,7 +32,7 @@ interface CLIParams {
log: ToolingLog;
}
interface Stage {
interface InjectionStep {
action: string;
minUsersCount?: number;
maxUsersCount: number;
@ -40,8 +40,8 @@ interface Stage {
}
export interface ScalabilitySetup {
warmup: { stages: Stage[] };
test: { stages: Stage[] };
warmup: InjectionStep[];
test: InjectionStep[];
maxDuration: string;
}
@ -55,6 +55,13 @@ const parsePayload = (payload: string, traceId: string, log: ToolingLog): string
return body;
};
const combineHeaderFieldValues = (headers: Headers) => {
return Object.assign(
{},
...Object.keys(headers).map((key) => ({ [key]: headers[key].join(', ') }))
);
};
const calculateTransactionTimeRage = (hit: SearchHit<Document>) => {
const trSource = hit._source as Document;
const startTime = trSource['@timestamp'];
@ -73,17 +80,18 @@ const getTraceItems = (
.map((hit) => {
const payload = hit.http.request?.body?.original;
return {
processor: hit.processor,
traceId: hit.trace.id,
timestamp: hit['@timestamp'],
parentId: hit?.parent?.id,
processor: hit.processor,
environment: hit.environment,
request: {
url: { path: hit.url.path },
headers: hit.http.request.headers,
timestamp: hit['@timestamp'],
method: hit.http.request.method,
body: payload ? parsePayload(payload, hit.trace.id, log) : undefined,
path: hit.url.path,
headers: combineHeaderFieldValues(hit.http.request.headers),
body: payload ? JSON.stringify(parsePayload(payload, hit.trace.id, log)) : undefined,
statusCode: hit.http.response.status_code,
},
response: { statusCode: hit.http.response.status_code },
transaction: {
id: hit.transaction.id,
name: hit.transaction.name,
@ -93,7 +101,7 @@ const getTraceItems = (
});
return withoutStaticResources
? data.filter((item) => !STATIC_RESOURCES_PATTERN.test(item.request.url.path))
? data.filter((item) => !STATIC_RESOURCES_PATTERN.test(item.request.path))
: data;
};
@ -137,14 +145,14 @@ export const extractor = async ({ param, client, log }: CLIParams) => {
journeyName,
kibanaVersion,
scalabilitySetup,
traceItems: getTraceItems(hits, withoutStaticResources, log),
requests: getTraceItems(hits, withoutStaticResources, log),
};
const outputDir = path.resolve('target/scalability_traces');
const fileName = `${output.journeyName.replace(/ /g, '')}-${buildId}.json`;
const filePath = path.resolve(outputDir, fileName);
log.info(`Found ${output.traceItems.length} transactions, output file: ${filePath}`);
log.info(`Found ${output.requests.length} transactions, output file: ${filePath}`);
if (!existsSync(outputDir)) {
await fs.mkdir(outputDir, { recursive: true });
}

View file

@ -279,7 +279,7 @@ export const schema = Joi.object()
/**
* Optional settings to enable scalability testing for single user performance journey.
* If defined, 'scalabilitySetup' must include 'warmup' and 'test' stages,
* If defined, 'scalabilitySetup' must include 'warmup' and 'test' stage array,
* 'maxDuration', e.g. '10m' to limit execution time to 10 minutes.
* Each stage must include 'action', 'duration' and 'maxUsersCount'.
* In addition, 'rampConcurrentUsers' requires 'minUsersCount' to ramp users from
@ -287,41 +287,37 @@ export const schema = Joi.object()
*/
scalabilitySetup: Joi.object()
.keys({
warmup: Joi.object()
.keys({
stages: Joi.array().items(
Joi.object().keys({
action: Joi.string()
.valid('constantConcurrentUsers', 'rampConcurrentUsers')
.required(),
duration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(),
minUsersCount: Joi.number().when('action', {
is: 'rampConcurrentUsers',
then: Joi.number().required().less(Joi.ref('maxUsersCount')),
otherwise: Joi.forbidden(),
}),
maxUsersCount: Joi.number().required().greater(0),
})
),
})
warmup: Joi.array()
.items(
Joi.object().keys({
action: Joi.string()
.valid('constantConcurrentUsers', 'rampConcurrentUsers')
.required(),
duration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(),
minUsersCount: Joi.number().when('action', {
is: 'rampConcurrentUsers',
then: Joi.number().required().less(Joi.ref('maxUsersCount')),
otherwise: Joi.forbidden(),
}),
maxUsersCount: Joi.number().required().greater(0),
})
)
.required(),
test: Joi.object()
.keys({
stages: Joi.array().items(
Joi.object().keys({
action: Joi.string()
.valid('constantConcurrentUsers', 'rampConcurrentUsers')
.required(),
duration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(),
minUsersCount: Joi.number().when('action', {
is: 'rampConcurrentUsers',
then: Joi.number().required().less(Joi.ref('maxUsersCount')),
otherwise: Joi.forbidden(),
}),
maxUsersCount: Joi.number().required().greater(0),
})
),
})
test: Joi.array()
.items(
Joi.object().keys({
action: Joi.string()
.valid('constantConcurrentUsers', 'rampConcurrentUsers')
.required(),
duration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(),
minUsersCount: Joi.number().when('action', {
is: 'rampConcurrentUsers',
then: Joi.number().required().less(Joi.ref('maxUsersCount')),
otherwise: Joi.forbidden(),
}),
maxUsersCount: Joi.number().required().greater(0),
})
)
.required(),
maxDuration: Joi.string().pattern(SCALABILITY_DURATION_PATTERN).required(),
})

View file

@ -15,30 +15,26 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const config = {
testFiles,
scalabilitySetup: {
warmup: {
stages: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 10,
duration: '30s',
},
{
action: 'rampConcurrentUsers',
minUsersCount: 10,
maxUsersCount: 50,
duration: '2m',
},
],
},
test: {
stages: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 50,
duration: '5m',
},
],
},
warmup: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 10,
duration: '30s',
},
{
action: 'rampConcurrentUsers',
minUsersCount: 10,
maxUsersCount: 50,
duration: '2m',
},
],
test: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 50,
duration: '5m',
},
],
maxDuration: '10m',
},
...performanceConfig.getAll(),

View file

@ -16,30 +16,26 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
testFiles,
...performanceConfig.getAll(),
scalabilitySetup: {
warmup: {
stages: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 10,
duration: '30s',
},
{
action: 'rampConcurrentUsers',
minUsersCount: 10,
maxUsersCount: 50,
duration: '2m',
},
],
},
test: {
stages: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 50,
duration: '5m',
},
],
},
warmup: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 10,
duration: '30s',
},
{
action: 'rampConcurrentUsers',
minUsersCount: 10,
maxUsersCount: 50,
duration: '2m',
},
],
test: [
{
action: 'constantConcurrentUsers',
maxUsersCount: 50,
duration: '5m',
},
],
maxDuration: '10m',
},
};