mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[APM] Implementing Journey for APM (#162721)
## Summary Closes - https://github.com/elastic/kibana/issues/153844 As part of this PR, as its just the stepping stone, we will only cover a basic navigation flow and analyze the result obtained from Steps Dashboard and data collected by the APM Agents for this journey ## Scope - Generating a data set using Synthtrace instead of Archives - Capturing the flow from Service Inventory to Trace Waterfall loading on Transaction page - Capturing Event loop utilisation metrics enabled for APM Journey ## How to run it ``` node scripts/run_performance.js --journey-path x-pack/performance/journeys/apm_service_inventory.ts --skip-warmup ``` --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
d5761dc0ea
commit
6b44fff5ac
6 changed files with 237 additions and 0 deletions
|
@ -413,5 +413,6 @@ enabled:
|
|||
- x-pack/performance/journeys/ecommerce_dashboard_tsvb_gauge_only.ts
|
||||
- x-pack/performance/journeys/dashboard_listing_page.ts
|
||||
- x-pack/performance/journeys/cloud_security_dashboard.ts
|
||||
- x-pack/performance/journeys/apm_service_inventory.ts
|
||||
- x-pack/test/custom_branding/config.ts
|
||||
- x-pack/test/profiling_api_integration/cloud/config.ts
|
||||
|
|
37
x-pack/performance/configs/apm_config.ts
Normal file
37
x-pack/performance/configs/apm_config.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { FtrConfigProviderContext } from '@kbn/test';
|
||||
import { CA_CERT_PATH } from '@kbn/dev-utils';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const xpackFunctionalConfig = await readConfigFile(
|
||||
// eslint-disable-next-line @kbn/imports/no_boundary_crossing
|
||||
require.resolve('../../test/functional/config.base.js')
|
||||
);
|
||||
|
||||
return {
|
||||
...xpackFunctionalConfig.getAll(),
|
||||
|
||||
kbnTestServer: {
|
||||
...xpackFunctionalConfig.get('kbnTestServer'),
|
||||
serverArgs: [
|
||||
...xpackFunctionalConfig.get('kbnTestServer.serverArgs'),
|
||||
'--home.disableWelcomeScreen=true',
|
||||
'--csp.strict=false',
|
||||
'--csp.warnLegacyBrowsers=false',
|
||||
// define custom kibana server args here
|
||||
`--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`,
|
||||
'--server.eluMonitor.enabled=true',
|
||||
'--server.eluMonitor.logging.enabled=true',
|
||||
'--server.eluMonitor.logging.threshold.ela=250',
|
||||
'--server.eluMonitor.logging.threshold.elu=0.15',
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
53
x-pack/performance/journeys/apm_service_inventory.ts
Normal file
53
x-pack/performance/journeys/apm_service_inventory.ts
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { Journey } from '@kbn/journeys';
|
||||
import { SynthtraceClient } from '../services/synthtrace';
|
||||
import { generateData } from '../synthtrace_data/apm_data';
|
||||
|
||||
export const journey = new Journey({
|
||||
beforeSteps: async ({ kbnUrl, log, auth, es }) => {
|
||||
// Install APM Package
|
||||
const synthClient = new SynthtraceClient({
|
||||
kbnBaseUrl: kbnUrl.get(),
|
||||
logger: log,
|
||||
username: auth.getUsername(),
|
||||
password: auth.getPassword(),
|
||||
esClient: es,
|
||||
});
|
||||
|
||||
await synthClient.installApmPackage();
|
||||
// Setup Synthtrace Client
|
||||
await synthClient.initialiseEsClient();
|
||||
// Generate data using Synthtrace
|
||||
const start = Date.now() - 1000;
|
||||
const end = Date.now();
|
||||
await synthClient.index(
|
||||
generateData({
|
||||
from: new Date(start).getTime(),
|
||||
to: new Date(end).getTime(),
|
||||
})
|
||||
);
|
||||
},
|
||||
ftrConfigPath: 'x-pack/performance/configs/apm_config.ts',
|
||||
})
|
||||
.step('Navigate to Service Inventory Page', async ({ page, kbnUrl }) => {
|
||||
await page.goto(kbnUrl.get(`app/apm/services`));
|
||||
await page.waitForSelector(`[data-test-subj="serviceLink_nodejs"]`);
|
||||
})
|
||||
.step('Navigate to Service Overview Page', async ({ page, kbnUrl }) => {
|
||||
await page.click(`[data-test-subj="serviceLink_nodejs"]`);
|
||||
await page.waitForSelector(`[data-test-subj="apmMainTemplateHeaderServiceName"]`);
|
||||
})
|
||||
.step('Navigate to Transactions tabs', async ({ page, kbnUrl }) => {
|
||||
await page.click(`[data-test-subj="transactionsTab"]`);
|
||||
await page.waitForSelector(`[data-test-subj="apmTransactionDetailLinkLink"]`);
|
||||
})
|
||||
.step('Wait for Trace Waterfall on the page to load', async ({ page, kbnUrl }) => {
|
||||
await page.click(`[data-test-subj="apmTransactionDetailLinkLink"]`);
|
||||
await page.waitForSelector(`[data-test-subj="apmWaterfallButton"]`);
|
||||
});
|
66
x-pack/performance/services/synthtrace/index.ts
Normal file
66
x-pack/performance/services/synthtrace/index.ts
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ApmSynthtraceEsClient, ApmSynthtraceKibanaClient } from '@kbn/apm-synthtrace';
|
||||
import Url from 'url';
|
||||
import { Readable } from 'stream';
|
||||
import { ApmFields, SynthtraceGenerator } from '@kbn/apm-synthtrace-client';
|
||||
|
||||
export interface SynthtraceClientParams {
|
||||
kbnBaseUrl: string;
|
||||
logger: any;
|
||||
username: string;
|
||||
password: string;
|
||||
esClient: any;
|
||||
}
|
||||
|
||||
export class SynthtraceClient {
|
||||
private synthtraceEsClient: ApmSynthtraceEsClient | undefined;
|
||||
private packageVersion: string = '';
|
||||
private readonly kibanaUrlWithAuth: string;
|
||||
|
||||
constructor(private readonly baseParams: SynthtraceClientParams) {
|
||||
const kibanaUrl = new URL(this.baseParams.kbnBaseUrl);
|
||||
this.kibanaUrlWithAuth = Url.format({
|
||||
protocol: kibanaUrl.protocol,
|
||||
hostname: kibanaUrl.hostname,
|
||||
port: kibanaUrl.port,
|
||||
auth: `${this.baseParams.username}:${this.baseParams.password}`,
|
||||
});
|
||||
}
|
||||
|
||||
async installApmPackage() {
|
||||
const kibanaClient = new ApmSynthtraceKibanaClient({
|
||||
logger: this.baseParams.logger,
|
||||
target: this.kibanaUrlWithAuth,
|
||||
});
|
||||
this.packageVersion = await kibanaClient.fetchLatestApmPackageVersion();
|
||||
|
||||
await kibanaClient.installApmPackage(this.packageVersion);
|
||||
}
|
||||
|
||||
async initialiseEsClient() {
|
||||
this.synthtraceEsClient = new ApmSynthtraceEsClient({
|
||||
client: this.baseParams.esClient,
|
||||
logger: this.baseParams.logger,
|
||||
refreshAfterIndex: true,
|
||||
version: this.packageVersion,
|
||||
});
|
||||
|
||||
this.synthtraceEsClient.pipeline(this.synthtraceEsClient.getDefaultPipeline(false));
|
||||
}
|
||||
|
||||
async index(events: SynthtraceGenerator<ApmFields>) {
|
||||
if (this.synthtraceEsClient) {
|
||||
await this.synthtraceEsClient.index(
|
||||
Readable.from(Array.from(events).flatMap((event) => event.serialize()))
|
||||
);
|
||||
} else {
|
||||
throw new Error('ES Client not initialised');
|
||||
}
|
||||
}
|
||||
}
|
77
x-pack/performance/synthtrace_data/apm_data.ts
Normal file
77
x-pack/performance/synthtrace_data/apm_data.ts
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
import { apm, httpExitSpan, timerange } from '@kbn/apm-synthtrace-client';
|
||||
|
||||
export function generateData({ from, to }: { from: number; to: number }) {
|
||||
const range = timerange(from, to);
|
||||
const transactionName = '240rpm/75% 1000ms';
|
||||
|
||||
const synthRum = apm
|
||||
.service({ name: 'synth-rum', environment: 'production', agentName: 'rum-js' })
|
||||
.instance('my-instance');
|
||||
const synthNode = apm
|
||||
.service({ name: 'synth-node', environment: 'production', agentName: 'nodejs' })
|
||||
.instance('my-instance');
|
||||
const synthGo = apm
|
||||
.service({ name: 'synth-go', environment: 'production', agentName: 'go' })
|
||||
.instance('my-instance');
|
||||
|
||||
return range.interval('1m').generator((timestamp) => {
|
||||
return synthRum
|
||||
.transaction({ transactionName })
|
||||
.duration(400)
|
||||
.timestamp(timestamp)
|
||||
.children(
|
||||
// synth-rum -> synth-node
|
||||
synthRum
|
||||
.span(
|
||||
httpExitSpan({
|
||||
spanName: 'GET /api/products/top',
|
||||
destinationUrl: 'http://synth-node:3000',
|
||||
})
|
||||
)
|
||||
.duration(300)
|
||||
.timestamp(timestamp)
|
||||
|
||||
.children(
|
||||
// synth-node
|
||||
synthNode
|
||||
.transaction({ transactionName: 'Initial transaction in synth-node' })
|
||||
.duration(300)
|
||||
.timestamp(timestamp)
|
||||
.children(
|
||||
synthNode
|
||||
// synth-node -> synth-go
|
||||
.span(
|
||||
httpExitSpan({
|
||||
spanName: 'GET synth-go:3000',
|
||||
destinationUrl: 'http://synth-go:3000',
|
||||
})
|
||||
)
|
||||
.timestamp(timestamp)
|
||||
.duration(400)
|
||||
|
||||
.children(
|
||||
// synth-go
|
||||
synthGo
|
||||
|
||||
.transaction({ transactionName: 'Initial transaction in synth-go' })
|
||||
.timestamp(timestamp)
|
||||
.duration(200)
|
||||
.children(
|
||||
synthGo
|
||||
.span({ spanName: 'custom_operation', spanType: 'custom' })
|
||||
.timestamp(timestamp)
|
||||
.duration(100)
|
||||
.success()
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
|
@ -14,5 +14,8 @@
|
|||
"@kbn/tooling-log",
|
||||
"@kbn/test",
|
||||
"@kbn/expect",
|
||||
"@kbn/dev-utils",
|
||||
"@kbn/apm-synthtrace",
|
||||
"@kbn/apm-synthtrace-client",
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue