Skip to content

Commit

Permalink
[Dataset quality] Enable page for synthetics (elastic#191846)
Browse files Browse the repository at this point in the history
Closes elastic/observability-dev#3457.

This PR enables Dataset quality for being used for synthetics datasets.

### Changes
- Added `synthetics` to `KNOWN_TYPES` array.
- Permissions were updated in `Data_quality` plugin.


https://github.com/user-attachments/assets/e9945012-166b-4704-bb73-11e6fe6eed76
  • Loading branch information
yngrdyn authored Sep 4, 2024
1 parent 4ca6f1d commit 1b2cbf1
Show file tree
Hide file tree
Showing 27 changed files with 542 additions and 77 deletions.
1 change: 1 addition & 0 deletions packages/kbn-apm-synthtrace-client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ export { appendHash, hashKeysOf } from './src/lib/utils/hash';
export type { ESDocumentWithOperation, SynthtraceESAction, SynthtraceGenerator } from './src/types';
export { log, type LogDocument, LONG_FIELD_NAME } from './src/lib/logs';
export { type AssetDocument } from './src/lib/assets';
export { syntheticsMonitor, type SyntheticsMonitorDocument } from './src/lib/synthetics';
103 changes: 103 additions & 0 deletions packages/kbn-apm-synthtrace-client/src/lib/synthetics/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
* 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 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 or the Server
* Side Public License, v 1.
*/

import { Fields } from '../entity';
import { Serializable } from '../serializable';

export type SyntheticsMonitorDocument = Fields &
Partial<{
'data_stream.namespace': string;
'data_stream.type': string;
'data_stream.dataset': string;
'monitor.id': string;
'monitor.origin': string;
'monitor.name': string;
'monitor.type': string;
'monitor.check_group': string;
'monitor.timespan.lt': string;
'monitor.timespan.gte': string;
'monitor.duration.us'?: number;
'monitor.ip'?: string;
'monitor.project.name'?: string;
'monitor.project.id'?: string;
'monitor.fleet_managed'?: boolean;
'monitor.status'?: string;
'synthetics.type'?: string;
'synthetics.step.index'?: number;
'observer.os.name'?: string;
'observer.product'?: string;
}>;

type MonitorDataStream =
| 'http'
| 'tcp'
| 'icmp'
| 'browser'
| 'browser.screenshot'
| 'browser.network';

class SyntheticsMonitor extends Serializable<SyntheticsMonitorDocument> {
constructor(fields: SyntheticsMonitorDocument) {
super({
...fields,
});
}

namespace(value: string) {
this.fields['data_stream.namespace'] = value;
return this;
}

dataset(value: MonitorDataStream) {
this.fields['data_stream.dataset'] = value;

if (value === 'browser.screenshot' || value === 'browser.network') {
this.fields['monitor.type'] = 'browser';
return this;
}

this.fields['monitor.type'] = value;
return this;
}

name(value: string) {
this.fields['monitor.name'] = value;
return this;
}

origin(value: string) {
this.fields['monitor.origin'] = value;
return this;
}

ip(value: string) {
this.fields['monitor.ip'] = value;
return this;
}

status(value: string) {
this.fields['monitor.status'] = value;
return this;
}

timestamp(time: number) {
super.timestamp(time);
return this;
}
}

function create(): SyntheticsMonitor {
return new SyntheticsMonitor({
'data_stream.namespace': 'default',
'data_stream.type': 'synthetics',
}).dataset('http');
}

export const syntheticsMonitor = {
create,
};
1 change: 1 addition & 0 deletions packages/kbn-apm-synthtrace/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ This library can currently be used in two ways:
- `Timerange`: an object that will return an array of timestamps based on an interval and a rate. These timestamps can be used to generate events/metricsets.
- `Transaction`, `Span`, `APMError` and `Metricset`: events/metricsets that occur on an instance. For more background, see the [explanation of the APM data model](https://www.elastic.co/guide/en/apm/get-started/7.15/apm-data-model.html)
- `Log`: An instance of Log generating Service which supports additional helpers to customise fields like `messages`, `logLevel`
- `SyntheticsMonitor`: An instance of Synthetic monitor. For more information see [Synthetic monitoring](https://www.elastic.co/guide/en/observability/current/monitor-uptime-synthetics.html).

#### Example

Expand Down
1 change: 1 addition & 0 deletions packages/kbn-apm-synthtrace/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { InfraSynthtraceKibanaClient } from './src/lib/infra/infra_synthtrace_ki
export { MonitoringSynthtraceEsClient } from './src/lib/monitoring/monitoring_synthtrace_es_client';
export { LogsSynthtraceEsClient } from './src/lib/logs/logs_synthtrace_es_client';
export { AssetsSynthtraceEsClient } from './src/lib/assets/assets_synthtrace_es_client';
export { SyntheticsSynthtraceEsClient } from './src/lib/synthetics/synthetics_synthtrace_es_client';
export {
addObserverVersionTransform,
deleteSummaryFieldTransform,
Expand Down
8 changes: 7 additions & 1 deletion packages/kbn-apm-synthtrace/src/cli/scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,12 @@
*/

import { Timerange } from '@kbn/apm-synthtrace-client';
import { ApmSynthtraceEsClient, InfraSynthtraceEsClient, LogsSynthtraceEsClient } from '../..';
import {
ApmSynthtraceEsClient,
InfraSynthtraceEsClient,
LogsSynthtraceEsClient,
SyntheticsSynthtraceEsClient,
} from '../..';
import { AssetsSynthtraceEsClient } from '../lib/assets/assets_synthtrace_es_client';
import { Logger } from '../lib/utils/create_logger';
import { ScenarioReturnType } from '../lib/utils/with_client';
Expand All @@ -18,6 +23,7 @@ interface EsClients {
logsEsClient: LogsSynthtraceEsClient;
infraEsClient: InfraSynthtraceEsClient;
assetsEsClient: AssetsSynthtraceEsClient;
syntheticsEsClient: SyntheticsSynthtraceEsClient;
}

type Generate<TFields> = (options: {
Expand Down
9 changes: 9 additions & 0 deletions packages/kbn-apm-synthtrace/src/cli/utils/bootstrap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { getKibanaClient } from './get_kibana_client';
import { getServiceUrls } from './get_service_urls';
import { RunOptions } from './parse_run_cli_flags';
import { getAssetsEsClient } from './get_assets_es_client';
import { getSyntheticsEsClient } from './get_synthetics_es_client';

export async function bootstrap(runOptions: RunOptions) {
const logger = createLogger(runOptions.logLevel);
Expand Down Expand Up @@ -61,11 +62,18 @@ export async function bootstrap(runOptions: RunOptions) {
concurrency: runOptions.concurrency,
});

const syntheticsEsClient = getSyntheticsEsClient({
target: esUrl,
logger,
concurrency: runOptions.concurrency,
});

if (runOptions.clean) {
await apmEsClient.clean();
await logsEsClient.clean();
await infraEsClient.clean();
await assetsEsClient.clean();
await syntheticsEsClient.clean();
}

return {
Expand All @@ -74,6 +82,7 @@ export async function bootstrap(runOptions: RunOptions) {
logsEsClient,
infraEsClient,
assetsEsClient,
syntheticsEsClient,
version,
kibanaUrl,
esUrl,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 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 or the Server
* Side Public License, v 1.
*/

import { Client } from '@elastic/elasticsearch';
import { Logger } from '../../lib/utils/create_logger';
import { RunOptions } from './parse_run_cli_flags';
import { getEsClientTlsSettings } from './ssl';
import { SyntheticsSynthtraceEsClient } from '../../lib/synthetics/synthetics_synthtrace_es_client';

export function getSyntheticsEsClient({
target,
logger,
concurrency,
}: Pick<RunOptions, 'concurrency'> & {
target: string;
logger: Logger;
}) {
const client = new Client({
node: target,
tls: getEsClientTlsSettings(target),
});

return new SyntheticsSynthtraceEsClient({
client,
logger,
concurrency,
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,8 @@ export async function startLiveDataUpload({
}) {
const file = runOptions.file;

const { logger, apmEsClient, logsEsClient, infraEsClient, assetsEsClient } = await bootstrap(
runOptions
);
const { logger, apmEsClient, logsEsClient, infraEsClient, assetsEsClient, syntheticsEsClient } =
await bootstrap(runOptions);

const scenario = await getScenario({ file, logger });
const { generate } = await scenario({ ...runOptions, logger });
Expand Down Expand Up @@ -65,7 +64,7 @@ export async function startLiveDataUpload({

const generatorsAndClients = generate({
range: timerange(bucketFrom.getTime(), bucketTo.getTime()),
clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient },
clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient, syntheticsEsClient },
});

const generatorsAndClientsArray = castArray(generatorsAndClients);
Expand Down
10 changes: 9 additions & 1 deletion packages/kbn-apm-synthtrace/src/cli/utils/synthtrace_worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { RunOptions } from './parse_run_cli_flags';
import { getLogsEsClient } from './get_logs_es_client';
import { getInfraEsClient } from './get_infra_es_client';
import { getAssetsEsClient } from './get_assets_es_client';
import { getSyntheticsEsClient } from './get_synthetics_es_client';

export interface WorkerData {
bucketFrom: Date;
Expand Down Expand Up @@ -56,6 +57,12 @@ async function start() {
logger,
});

const syntheticsEsClient = getSyntheticsEsClient({
concurrency: runOptions.concurrency,
target: esUrl,
logger,
});

const file = runOptions.file;

const scenario = await logger.perf('get_scenario', () => getScenario({ file, logger }));
Expand All @@ -70,6 +77,7 @@ async function start() {
logsEsClient,
infraEsClient,
assetsEsClient,
syntheticsEsClient,
});
}

Expand All @@ -78,7 +86,7 @@ async function start() {
const generatorsAndClients = logger.perf('generate_scenario', () =>
generate({
range: timerange(bucketFrom, bucketTo),
clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient },
clients: { logsEsClient, apmEsClient, infraEsClient, assetsEsClient, syntheticsEsClient },
})
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
*/

import { Client } from '@elastic/elasticsearch';
import { ESDocumentWithOperation } from '@kbn/apm-synthtrace-client';
import { pipeline, Readable, Transform } from 'stream';
import { pipeline, Readable } from 'stream';
import { LogDocument } from '@kbn/apm-synthtrace-client/src/lib/logs';
import { MappingTypeMapping } from '@elastic/elasticsearch/lib/api/types';
import { SynthtraceEsClient, SynthtraceEsClientOptions } from '../shared/base_client';
import { getSerializeTransform } from '../shared/get_serialize_transform';
import { Logger } from '../utils/create_logger';
import { indexTemplates, IndexTemplateName } from './custom_logsdb_index_templates';
import { getRoutingTransform } from '../shared/data_stream_get_routing_transform';

export type LogsSynthtraceEsClientOptions = Omit<SynthtraceEsClientOptions, 'pipeline'>;

Expand Down Expand Up @@ -66,7 +66,7 @@ function logsPipeline() {
return pipeline(
base,
getSerializeTransform<LogDocument>(),
getRoutingTransform(),
getRoutingTransform('logs'),
(err: unknown) => {
if (err) {
throw err;
Expand All @@ -75,22 +75,3 @@ function logsPipeline() {
);
};
}

function getRoutingTransform() {
return new Transform({
objectMode: true,
transform(document: ESDocumentWithOperation<LogDocument>, encoding, callback) {
if (
'data_stream.type' in document &&
'data_stream.dataset' in document &&
'data_stream.namespace' in document
) {
document._index = `${document['data_stream.type']}-${document['data_stream.dataset']}-${document['data_stream.namespace']}`;
} else {
throw new Error('Cannot determine index for event');
}

callback(null, document);
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* 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 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 or the Server
* Side Public License, v 1.
*/

import { ESDocumentWithOperation, Fields } from '@kbn/apm-synthtrace-client';
import { Transform } from 'stream';

export function getRoutingTransform<T extends Fields>(dataStreamType: string) {
return new Transform({
objectMode: true,
transform(document: ESDocumentWithOperation<T>, encoding, callback) {
if ('data_stream.dataset' in document && 'data_stream.namespace' in document) {
document._index = `${dataStreamType}-${document['data_stream.dataset']}-${document['data_stream.namespace']}`;
} else {
throw new Error('Cannot determine index for event');
}

callback(null, document);
},
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* 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 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 or the Server
* Side Public License, v 1.
*/

import { Client } from '@elastic/elasticsearch';
import { SyntheticsMonitorDocument } from '@kbn/apm-synthtrace-client';
import { pipeline, Readable } from 'stream';
import { SynthtraceEsClient, SynthtraceEsClientOptions } from '../shared/base_client';
import { getSerializeTransform } from '../shared/get_serialize_transform';
import { Logger } from '../utils/create_logger';
import { getRoutingTransform } from '../shared/data_stream_get_routing_transform';

export type SyntheticsSynthtraceEsClientOptions = Omit<SynthtraceEsClientOptions, 'pipeline'>;

export class SyntheticsSynthtraceEsClient extends SynthtraceEsClient<SyntheticsMonitorDocument> {
constructor(options: { client: Client; logger: Logger } & SyntheticsSynthtraceEsClientOptions) {
super({
...options,
pipeline: syntheticsPipeline(),
});
this.dataStreams = ['synthetics-*-*'];
}
}

function syntheticsPipeline() {
return (base: Readable) => {
return pipeline(
base,
getSerializeTransform<SyntheticsMonitorDocument>(),
getRoutingTransform('synthetics'),
(err: unknown) => {
if (err) {
throw err;
}
}
);
};
}
Loading

0 comments on commit 1b2cbf1

Please sign in to comment.