-
Notifications
You must be signed in to change notification settings - Fork 8.6k
[kbn-scout] Add Synthtrace as a fixture #210505
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
8cf3b53
feat: add synthtrace to scout
rmyz 240a855
[CI] Auto-commit changed files from 'node scripts/yarn_deduplicate'
kibanamachine 853b80e
fix types
rmyz 6b5c7fd
feat: add infra client
rmyz 84191a7
improve typings
rmyz 307095b
PR comment fixes
rmyz 9ea808d
Merge branch 'main' into 210340-scout-add-synthtrace-fixture
rmyz 88a527a
fix
rmyz b0a2cdb
address PR comments
rmyz 9742d27
feat: add synthtrace ingestion hook
rmyz b69a36d
refactor: use getters to reduce complexity
rmyz ced8cf9
Merge branch 'main' into 210340-scout-add-synthtrace-fixture
rmyz ea99d35
fix debug messages
rmyz 2f448e4
remove duplication
rmyz 8ed9a19
improve code
rmyz 3cd18cd
Merge branch 'main' into 210340-scout-add-synthtrace-fixture
rmyz 8da80e3
solve PR comments
rmyz e15551e
Merge branch 'main' into 210340-scout-add-synthtrace-fixture
rmyz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| import { | ||
| ApmSynthtraceEsClient, | ||
| ApmSynthtraceKibanaClient, | ||
| InfraSynthtraceEsClient, | ||
| InfraSynthtraceKibanaClient, | ||
| LogLevel, | ||
| OtelSynthtraceEsClient, | ||
| createLogger, | ||
| } from '@kbn/apm-synthtrace'; | ||
| import { ScoutLogger } from './logger'; | ||
| import { EsClient } from '../../types'; | ||
|
|
||
| let apmSynthtraceEsClientInstance: ApmSynthtraceEsClient | undefined; | ||
| let infraSynthtraceEsClientInstance: InfraSynthtraceEsClient | undefined; | ||
| let otelSynthtraceEsClientInstance: OtelSynthtraceEsClient | undefined; | ||
| const logger = createLogger(LogLevel.info); | ||
|
|
||
| export async function getApmSynthtraceEsClient( | ||
| esClient: EsClient, | ||
| target: string, | ||
| log: ScoutLogger | ||
| ) { | ||
| if (!apmSynthtraceEsClientInstance) { | ||
| const apmSynthtraceKibanaClient = new ApmSynthtraceKibanaClient({ | ||
| logger, | ||
| target, | ||
| }); | ||
|
|
||
| const version = await apmSynthtraceKibanaClient.fetchLatestApmPackageVersion(); | ||
| await apmSynthtraceKibanaClient.installApmPackage(version); | ||
| apmSynthtraceEsClientInstance = new ApmSynthtraceEsClient({ | ||
| client: esClient, | ||
| logger, | ||
| refreshAfterIndex: true, | ||
| version, | ||
| }); | ||
|
|
||
| apmSynthtraceEsClientInstance.pipeline( | ||
| apmSynthtraceEsClientInstance.getDefaultPipeline({ includeSerialization: false }) | ||
| ); | ||
|
|
||
| log.serviceLoaded('apmSynthtraceClient'); | ||
| } | ||
|
|
||
| return apmSynthtraceEsClientInstance; | ||
| } | ||
|
|
||
| export async function getInfraSynthtraceEsClient( | ||
| esClient: EsClient, | ||
| kbnUrl: string, | ||
| auth: { username: string; password: string }, | ||
| log: ScoutLogger | ||
| ) { | ||
| if (!infraSynthtraceEsClientInstance) { | ||
| const infraSynthtraceKibanaClient = new InfraSynthtraceKibanaClient({ | ||
| logger, | ||
| target: kbnUrl, | ||
| username: auth.username, | ||
| password: auth.password, | ||
| }); | ||
|
|
||
| const version = await infraSynthtraceKibanaClient.fetchLatestSystemPackageVersion(); | ||
| await infraSynthtraceKibanaClient.installSystemPackage(version); | ||
| infraSynthtraceEsClientInstance = new InfraSynthtraceEsClient({ | ||
| client: esClient, | ||
| logger, | ||
| refreshAfterIndex: true, | ||
| }); | ||
|
|
||
| infraSynthtraceEsClientInstance.pipeline( | ||
| infraSynthtraceEsClientInstance.getDefaultPipeline({ includeSerialization: false }) | ||
| ); | ||
|
|
||
| log.serviceLoaded('infraSynthtraceClient'); | ||
| } | ||
|
|
||
| return infraSynthtraceEsClientInstance; | ||
| } | ||
|
|
||
| export function getOtelSynthtraceEsClient(esClient: EsClient, log: ScoutLogger) { | ||
| if (!otelSynthtraceEsClientInstance) { | ||
| otelSynthtraceEsClientInstance = new OtelSynthtraceEsClient({ | ||
| client: esClient, | ||
| logger, | ||
| refreshAfterIndex: true, | ||
| }); | ||
|
|
||
| otelSynthtraceEsClientInstance.pipeline( | ||
| otelSynthtraceEsClientInstance.getDefaultPipeline({ includeSerialization: false }) | ||
| ); | ||
|
|
||
| log.serviceLoaded('otelSynthtraceClient'); | ||
| } | ||
|
|
||
| return otelSynthtraceEsClientInstance; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
packages/kbn-scout/src/playwright/fixtures/worker/synthtrace.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| /* | ||
| * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||
| * Public License v 1"; you may not use this file except in compliance with, at | ||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||
| */ | ||
|
|
||
| import { Readable } from 'stream'; | ||
| import type { ApmFields, Fields, InfraDocument, OtelDocument } from '@kbn/apm-synthtrace-client'; | ||
| import Url from 'url'; | ||
| import type { SynthtraceEsClient } from '@kbn/apm-synthtrace/src/lib/shared/base_client'; | ||
| import { | ||
| getApmSynthtraceEsClient, | ||
| getInfraSynthtraceEsClient, | ||
| getOtelSynthtraceEsClient, | ||
| } from '../../../common/services/synthtrace'; | ||
| import { coreWorkerFixtures } from './core_fixtures'; | ||
| import type { SynthtraceEvents } from '../../global_hooks/synthtrace_ingestion'; | ||
|
|
||
| interface SynthtraceFixtureEsClient<TFields extends Fields> { | ||
| index: (events: SynthtraceEvents<TFields>) => Promise<void>; | ||
| clean: SynthtraceEsClient<TFields>['clean']; | ||
| } | ||
|
|
||
| export interface SynthtraceFixture { | ||
| apmSynthtraceEsClient: SynthtraceFixtureEsClient<ApmFields>; | ||
| infraSynthtraceEsClient: SynthtraceFixtureEsClient<InfraDocument>; | ||
| otelSynthtraceEsClient: SynthtraceFixtureEsClient<OtelDocument>; | ||
| } | ||
|
|
||
| const useSynthtraceClient = async <TFields extends Fields>( | ||
| client: SynthtraceEsClient<TFields>, | ||
| use: (client: SynthtraceFixtureEsClient<TFields>) => Promise<void> | ||
| ) => { | ||
| const index = async (events: SynthtraceEvents<TFields>) => | ||
| await client.index(Readable.from(Array.from(events).flatMap((event) => event.serialize()))); | ||
|
|
||
| const clean = async () => await client.clean(); | ||
|
|
||
| await use({ index, clean }); | ||
|
|
||
| // cleanup function after all tests have ran | ||
| await client.clean(); | ||
| }; | ||
|
|
||
| export const synthtraceFixture = coreWorkerFixtures.extend<{}, SynthtraceFixture>({ | ||
| apmSynthtraceEsClient: [ | ||
| async ({ esClient, config, kbnUrl, log }, use) => { | ||
| const { username, password } = config.auth; | ||
| const kibanaUrl = new URL(kbnUrl.get()); | ||
| const kibanaUrlWithAuth = Url.format({ | ||
| protocol: kibanaUrl.protocol, | ||
| hostname: kibanaUrl.hostname, | ||
| port: kibanaUrl.port, | ||
| auth: `${username}:${password}`, | ||
| }); | ||
|
|
||
| const apmSynthtraceEsClient = await getApmSynthtraceEsClient( | ||
| esClient, | ||
| kibanaUrlWithAuth, | ||
| log | ||
| ); | ||
|
|
||
| await useSynthtraceClient<ApmFields>(apmSynthtraceEsClient, use); | ||
| }, | ||
| { scope: 'worker' }, | ||
| ], | ||
| infraSynthtraceEsClient: [ | ||
| async ({ esClient, config, kbnUrl, log }, use) => { | ||
| const infraSynthtraceEsClient = await getInfraSynthtraceEsClient( | ||
| esClient, | ||
| kbnUrl.get(), | ||
| config.auth, | ||
| log | ||
| ); | ||
|
|
||
| await useSynthtraceClient<InfraDocument>(infraSynthtraceEsClient, use); | ||
| }, | ||
| { scope: 'worker' }, | ||
| ], | ||
| otelSynthtraceEsClient: [ | ||
| async ({ esClient, log }, use) => { | ||
| const otelSynthtraceEsClient = await getOtelSynthtraceEsClient(esClient, log); | ||
|
|
||
| await useSynthtraceClient<OtelDocument>(otelSynthtraceEsClient, use); | ||
| }, | ||
| { scope: 'worker' }, | ||
| ], | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
115 changes: 115 additions & 0 deletions
115
packages/kbn-scout/src/playwright/global_hooks/synthtrace_ingestion.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,115 @@ | ||||||
| /* | ||||||
| * 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", the "GNU Affero General Public License v3.0 only", and the "Server Side | ||||||
| * Public License v 1"; you may not use this file except in compliance with, at | ||||||
| * your election, the "Elastic License 2.0", the "GNU Affero General Public | ||||||
| * License v3.0 only", or the "Server Side Public License, v 1". | ||||||
| */ | ||||||
|
|
||||||
| import { FullConfig } from 'playwright/test'; | ||||||
| import Url from 'url'; | ||||||
| import { Readable } from 'node:stream'; | ||||||
| import type { | ||||||
| ApmFields, | ||||||
| Fields, | ||||||
| InfraDocument, | ||||||
| OtelDocument, | ||||||
| Serializable, | ||||||
| SynthtraceGenerator, | ||||||
| } from '@kbn/apm-synthtrace-client'; | ||||||
| import { | ||||||
| getLogger, | ||||||
| createScoutConfig, | ||||||
| measurePerformanceAsync, | ||||||
| getEsClient, | ||||||
| ScoutLogger, | ||||||
| EsClient, | ||||||
| } from '../../common'; | ||||||
| import { ScoutTestOptions } from '../types'; | ||||||
| import { | ||||||
| getApmSynthtraceEsClient, | ||||||
| getInfraSynthtraceEsClient, | ||||||
| getOtelSynthtraceEsClient, | ||||||
| } from '../../common/services/synthtrace'; | ||||||
|
|
||||||
| export type SynthtraceEvents<T extends Fields> = SynthtraceGenerator<T> | Array<Serializable<T>>; | ||||||
|
|
||||||
| interface SynthtraceIngestionData { | ||||||
| apm: Array<SynthtraceEvents<ApmFields>>; | ||||||
| infra: Array<SynthtraceEvents<InfraDocument>>; | ||||||
| otel: Array<SynthtraceEvents<OtelDocument>>; | ||||||
| } | ||||||
|
|
||||||
| const getSynthtraceClient = ( | ||||||
| key: keyof SynthtraceIngestionData, | ||||||
| esClient: EsClient, | ||||||
| kbnUrl: string, | ||||||
| auth: { username: string; password: string }, | ||||||
| log: ScoutLogger | ||||||
| ) => { | ||||||
| switch (key) { | ||||||
| case 'apm': | ||||||
| const kibanaUrl = new URL(kbnUrl); | ||||||
| const kibanaUrlWithAuth = Url.format({ | ||||||
| protocol: kibanaUrl.protocol, | ||||||
| hostname: kibanaUrl.hostname, | ||||||
| port: kibanaUrl.port, | ||||||
| auth: `${auth.username}:${auth.password}`, | ||||||
| }); | ||||||
| return getApmSynthtraceEsClient(esClient, kibanaUrlWithAuth, log); | ||||||
| case 'infra': | ||||||
| return getInfraSynthtraceEsClient(esClient, kbnUrl, auth, log); | ||||||
| case 'otel': | ||||||
| return getOtelSynthtraceEsClient(esClient, log); | ||||||
| } | ||||||
| }; | ||||||
|
|
||||||
| export async function ingestSynthtraceDataHook(config: FullConfig, data: SynthtraceIngestionData) { | ||||||
| const log = getLogger(); | ||||||
|
|
||||||
| const { apm, infra, otel } = data; | ||||||
| const hasApmData = apm.length > 0; | ||||||
| const hasInfraData = infra.length > 0; | ||||||
| const hasOtelData = otel.length > 0; | ||||||
| const hasAnyData = hasApmData || hasInfraData || hasOtelData; | ||||||
|
|
||||||
| if (!hasAnyData) { | ||||||
| log.debug('[setup] no synthtrace data to ingest'); | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| return measurePerformanceAsync(log, '[setup]: ingestSynthtraceDataHook', async () => { | ||||||
| // TODO: This should be configurable local vs cloud | ||||||
|
|
||||||
| const configName = 'local'; | ||||||
| const projectUse = config.projects[0].use as ScoutTestOptions; | ||||||
| const serversConfigDir = projectUse.serversConfigDir; | ||||||
| const scoutConfig = createScoutConfig(serversConfigDir, configName, log); | ||||||
| const esClient = getEsClient(scoutConfig, log); | ||||||
| const kbnUrl = scoutConfig.hosts.kibana; | ||||||
|
|
||||||
| for (const key of Object.keys(data)) { | ||||||
| const typedKey = key as keyof SynthtraceIngestionData; | ||||||
| if (data[typedKey].length > 0) { | ||||||
| const client = await getSynthtraceClient(typedKey, esClient, kbnUrl, scoutConfig.auth, log); | ||||||
|
|
||||||
| log.debug(`[setup] ingesting ${key} synthtrace data`); | ||||||
|
|
||||||
| try { | ||||||
| await Promise.all( | ||||||
| data[typedKey].map((event) => { | ||||||
| return client.index(Readable.from(Array.from(event).flatMap((e) => e.serialize()))); | ||||||
| }) | ||||||
| ); | ||||||
| } catch (e) { | ||||||
| log.debug(`[setup] error ingesting ${key} synthtrace data`, e); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
nit: it can be logged as error here |
||||||
| } | ||||||
|
|
||||||
| log.debug(`[setup] ${key} synthtrace data ingested successfully`); | ||||||
| } else { | ||||||
| log.debug(`[setup] no synthtrace data to ingest for ${key}`); | ||||||
| } | ||||||
| } | ||||||
| }); | ||||||
| } | ||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.