[kbn-performance-testing-dataset-extractor] filter out transactions with static resources (#135222)

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Dzmitry Lemechko 2022-07-11 15:26:15 +02:00 committed by GitHub
parent e3ea3fd02b
commit b0c0c1ba6d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 33 deletions

View file

@ -98,8 +98,10 @@ export async function runExtractor() {
throw createFlagError('--buildId must be defined'); throw createFlagError('--buildId must be defined');
} }
const withoutStaticResources = !!flags['without-static-resources'] || false;
return extractor({ return extractor({
param: { journeyName, scalabilitySetup, buildId }, param: { journeyName, scalabilitySetup, buildId, withoutStaticResources },
client: { baseURL, username, password }, client: { baseURL, username, password },
log, log,
}); });
@ -108,12 +110,14 @@ export async function runExtractor() {
description: `CLI to fetch and normalize APM traces for journey scalability testing`, description: `CLI to fetch and normalize APM traces for journey scalability testing`,
flags: { flags: {
string: ['config', 'buildId', 'es-url', 'es-username', 'es-password'], string: ['config', 'buildId', 'es-url', 'es-username', 'es-password'],
boolean: ['without-static-resources'],
help: ` help: `
--config path to an FTR config file that sets scalabilitySetup and journeyName (stored as 'labels.journeyName' in APM-based document) --config <config_path> path to an FTR config file that sets scalabilitySetup and journeyName (stored as 'labels.journeyName' in APM-based document)
--buildId BUILDKITE_JOB_ID or uuid generated locally, stored in APM-based document as label: 'labels.testBuildId' --buildId <buildId> BUILDKITE_JOB_ID or uuid generated locally, stored in APM-based document as label: 'labels.testBuildId'
--es-url url for Elasticsearch (APM cluster) --es-url <url> url for Elasticsearch (APM cluster)
--es-username username for Elasticsearch (APM cluster) --es-username <username> username for Elasticsearch (APM cluster)
--es-password password for Elasticsearch (APM cluster) --es-password <password> password for Elasticsearch (APM cluster)
--without-static-resources filters out traces with url path matching static resources pattern
`, `,
}, },
} }

View file

@ -15,12 +15,14 @@ import { SearchHit } from '@elastic/elasticsearch/lib/api/types';
import { initClient, Document } from './es_client'; import { initClient, Document } from './es_client';
const DATE_FORMAT = `YYYY-MM-DD'T'HH:mm:ss.SSS'Z'`; 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)$/;
interface CLIParams { interface CLIParams {
param: { param: {
journeyName: string; journeyName: string;
scalabilitySetup: ScalabilitySetup; scalabilitySetup: ScalabilitySetup;
buildId: string; buildId: string;
withoutStaticResources: boolean;
}; };
client: { client: {
baseURL: string; baseURL: string;
@ -61,13 +63,47 @@ const calculateTransactionTimeRage = (hit: SearchHit<Document>) => {
return { startTime, endTime }; return { startTime, endTime };
}; };
const getTraceItems = (
hits: Array<SearchHit<Document>>,
withoutStaticResources: boolean,
log: ToolingLog
) => {
const data = hits
.map((hit) => hit!._source as Document)
.map((hit) => {
const payload = hit.http.request?.body?.original;
return {
processor: hit.processor,
traceId: hit.trace.id,
timestamp: hit['@timestamp'],
environment: hit.environment,
request: {
url: { path: hit.url.path },
headers: hit.http.request.headers,
method: hit.http.request.method,
body: payload ? parsePayload(payload, hit.trace.id, log) : undefined,
},
response: { statusCode: hit.http.response.status_code },
transaction: {
id: hit.transaction.id,
name: hit.transaction.name,
type: hit.transaction.type,
},
};
});
return withoutStaticResources
? data.filter((item) => !STATIC_RESOURCES_PATTERN.test(item.request.url.path))
: data;
};
export const extractor = async ({ param, client, log }: CLIParams) => { export const extractor = async ({ param, client, log }: CLIParams) => {
const authOptions = { const authOptions = {
node: client.baseURL, node: client.baseURL,
username: client.username, username: client.username,
password: client.password, password: client.password,
}; };
const { journeyName, scalabilitySetup, buildId } = param; const { journeyName, scalabilitySetup, buildId, withoutStaticResources } = param;
log.info( log.info(
`Searching transactions with 'labels.testBuildId=${buildId}' and 'labels.journeyName=${journeyName}'` `Searching transactions with 'labels.testBuildId=${buildId}' and 'labels.journeyName=${journeyName}'`
); );
@ -97,42 +133,18 @@ export const extractor = async ({ param, client, log }: CLIParams) => {
const source = hits[0]!._source as Document; const source = hits[0]!._source as Document;
const kibanaVersion = source.service.version; const kibanaVersion = source.service.version;
const data = hits
.map((hit) => hit!._source as Document)
.map((hit) => {
const payload = hit.http.request?.body?.original;
return {
processor: hit.processor,
traceId: hit.trace.id,
timestamp: hit['@timestamp'],
environment: hit.environment,
request: {
url: { path: hit.url.path },
headers: hit.http.request.headers,
method: hit.http.request.method,
body: payload ? parsePayload(payload, hit.trace.id, log) : undefined,
},
response: { statusCode: hit.http.response.status_code },
transaction: {
id: hit.transaction.id,
name: hit.transaction.name,
type: hit.transaction.type,
},
};
});
const output = { const output = {
journeyName, journeyName,
kibanaVersion, kibanaVersion,
scalabilitySetup, scalabilitySetup,
traceItems: data, traceItems: getTraceItems(hits, withoutStaticResources, log),
}; };
const outputDir = path.resolve('target/scalability_traces'); const outputDir = path.resolve('target/scalability_traces');
const fileName = `${output.journeyName.replace(/ /g, '')}-${buildId}.json`; const fileName = `${output.journeyName.replace(/ /g, '')}-${buildId}.json`;
const filePath = path.resolve(outputDir, fileName); const filePath = path.resolve(outputDir, fileName);
log.info(`Found ${hits.length} transactions, output file: ${filePath}`); log.info(`Found ${output.traceItems.length} transactions, output file: ${filePath}`);
if (!existsSync(outputDir)) { if (!existsSync(outputDir)) {
await fs.mkdir(outputDir, { recursive: true }); await fs.mkdir(outputDir, { recursive: true });
} }