Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
MiriamAparicio committed Sep 20, 2024
1 parent bb18996 commit 50db60a
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 1 deletion.
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 @@ -37,3 +37,4 @@ export type { ESDocumentWithOperation, SynthtraceESAction, SynthtraceGenerator }
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';
export { alert, type AlertEntityDocument } from './src/lib/alerts';
145 changes: 145 additions & 0 deletions packages/kbn-apm-synthtrace-client/src/lib/alerts/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/*
* 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".
*/

/* eslint-disable max-classes-per-file */
import { Entity, Fields } from '../entity';
import { Serializable } from '../serializable';

interface AlertDocument extends Fields {
'kibana.alert.reason'?: string;
'kibana.alert.evaluation.threshold'?: number[];
'kibana.alert.rule.category'?: string;
'kibana.alert.rule.consumer'?: string;
'kibana.alert.rule.execution.uuid'?: string;
'kibana.alert.rule.name'?: string;
'kibana.alert.rule.producer'?: string;
'kibana.alert.rule.revision'?: number;
'kibana.alert.rule.uuid'?: string;
'kibana.space_ids'?: string[];
'event.action'?: string;
'event.kind'?: string;
'kibana.alert.rule.execution.timestamp'?: number;
'kibana.alert.action_group'?: string;
'kibana.alert.flapping'?: boolean;
'kibana.alert.flapping_history'?: string;
'kibana.alert.instance.id'?: string;
'kibana.alert.maintenance_window_ids'?: string;
'kibana.alert.status'?: string;
'kibana.alert.uuid'?: string;
'kibana.alert.workflow_status'?: string;
'kibana.alert.duration.us'?: number;
tags?: string[];
}

export interface AlertInfraDocument extends AlertDocument {
'kibana.alert.evaluation.values'?: number[];
'cloud.availability_zone'?: string;
'cloud.instance.id'?: string;
'cloud.instance.name'?: string;
'cloud.provider'?: string;
'cloud.machine.type'?: string;
'cloud.project.id'?: string;
'cloud.region'?: string;
'host.hostname'?: string;
'host.os.platform'?: string;
'host.ip'?: string;
'host.name'?: string;
'host.architecture'?: string;
'kibana.alert.start'?: number | string;
'kibana.alert.time_range': {
gte: number | string;
lte?: number | string;
};
}

export interface AlertApmDocument extends AlertDocument {
'processor.event'?: string;
'kibana.alert.evaluation.value'?: number;
'agent.name'?: string;
labels?: { custom_labels?: string[] };
'service.environment'?: string;
'service.name'?: string;
'transaction.type'?: string;
}

export type AlertEntityDocument = AlertInfraDocument | AlertApmDocument;

class AlertInfra extends Serializable<AlertInfraDocument> {}
class AlertApm extends Serializable<AlertApmDocument> {}

class Alert extends Entity<AlertDocument> {
host({ hostName, from, to }: { hostName: string; from: string; to: string }) {
return new AlertInfra({
...this.fields,
// 'kibana.alert.evaluation.values': [0.92],
// 'cloud.availability_zone': 'us-west-1',
// 'cloud.instance.id': 'instance-id',
// 'cloud.instance.name': 'instance-name',
// 'cloud.provider': 'aws',
// 'cloud.machine.type': 't2.micro',
// 'cloud.project.id': 'project-id',
// 'cloud.region': 'us-west-1',
// 'host.hostname': hostName,
// 'host.os.platform': 'linux',
// 'host.ip': 'sjsjsjj',
'host.name': hostName,
'kibana.alert.start': from,
'kibana.alert.time_range': {
gte: from,
lte: to,
},
// 'host.architecture': 'x86_64',
});
}

apm(serviceName: string) {
return new AlertApm({
...this.fields,
'processor.event': 'transaction',
'kibana.alert.evaluation.value': 0.5,
'agent.name': 'nodejs',
labels: { custom_labels: ['label1', 'label2'] },
'service.environment': 'production',
'service.name': serviceName,
'transaction.type': 'type',
});
}
}

export function alert({
category,
consumer,
producer,
}: {
category: string;
consumer: string;
producer: string;
}) {
return new Alert({
'kibana.alert.reason': 'CPU usage is 91.5% in the last 1 min for host. Alert when above 50%.',
'kibana.alert.evaluation.threshold': [50],
'kibana.alert.rule.category': category,
'kibana.alert.rule.consumer': consumer,
'kibana.alert.rule.name': 'Inventory threshold',
'kibana.alert.rule.producer': producer,
// 'kibana.alert.rule.revision': 0,
// 'kibana.space_ids': ['default'],
// 'event.action': 'active',
// 'event.kind': 'signal',
// 'kibana.alert.rule.execution.timestamp': timestamp,
// 'kibana.alert.action_group': 'metrics.inventory_threshold.fired',
// 'kibana.alert.instance.id': 'instance',
// 'kibana.alert.maintenance_window_ids': 'window',
'kibana.alert.status': 'active',
'kibana.alert.uuid': 'ef596789-5be3-45ad-91b4-e6b463ae06e2',
// 'kibana.alert.workflow_status': 'workflow',
// 'kibana.alert.duration.us': 1000,
tags: [],
});
}
1 change: 1 addition & 0 deletions packages/kbn-apm-synthtrace/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export { MonitoringSynthtraceEsClient } from './src/lib/monitoring/monitoring_sy
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 { AlertsSynthtraceEsClient } from './src/lib/alerts/alerts_sythtrace_es_client';
export {
addObserverVersionTransform,
deleteSummaryFieldTransform,
Expand Down
2 changes: 2 additions & 0 deletions packages/kbn-apm-synthtrace/src/cli/scenario.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
InfraSynthtraceEsClient,
LogsSynthtraceEsClient,
SyntheticsSynthtraceEsClient,
AlertsSynthtraceEsClient,
} from '../..';
import { AssetsSynthtraceEsClient } from '../lib/assets/assets_synthtrace_es_client';
import { Logger } from '../lib/utils/create_logger';
Expand All @@ -25,6 +26,7 @@ interface EsClients {
infraEsClient: InfraSynthtraceEsClient;
assetsEsClient: AssetsSynthtraceEsClient;
syntheticsEsClient: SyntheticsSynthtraceEsClient;
alertsEsClient: AlertsSynthtraceEsClient;
}

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 @@ -16,6 +16,7 @@ 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';
import { getAlertsEsClient } from './get_alerts_es_client';

export async function bootstrap(runOptions: RunOptions) {
const logger = createLogger(runOptions.logLevel);
Expand Down Expand Up @@ -69,12 +70,19 @@ export async function bootstrap(runOptions: RunOptions) {
concurrency: runOptions.concurrency,
});

const alertsEsClient = getAlertsEsClient({
target: esUrl,
logger,
concurrency: runOptions.concurrency,
});

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

return {
Expand All @@ -84,6 +92,7 @@ export async function bootstrap(runOptions: RunOptions) {
infraEsClient,
assetsEsClient,
syntheticsEsClient,
alertsEsClient,
version,
kibanaUrl,
esUrl,
Expand Down
35 changes: 35 additions & 0 deletions packages/kbn-apm-synthtrace/src/cli/utils/get_alerts_es_client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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 { Client } from '@elastic/elasticsearch';
import { AlertsSynthtraceEsClient } from '../../lib/alerts/alerts_sythtrace_es_client';
import { Logger } from '../../lib/utils/create_logger';
import { RunOptions } from './parse_run_cli_flags';
import { getEsClientTlsSettings } from './ssl';

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

return new AlertsSynthtraceEsClient({
client,
logger,
concurrency,
refreshAfterIndex: true,
});
}
17 changes: 16 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 @@ -20,6 +20,7 @@ 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';
import { getAlertsEsClient } from './get_alerts_es_client';

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

const alertsEsClient = getAlertsEsClient({
concurrency: runOptions.concurrency,
target: esUrl,
logger,
});

const file = runOptions.file;

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

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

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* 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 { Client } from '@elastic/elasticsearch';
import { ESDocumentWithOperation, AlertEntityDocument } from '@kbn/apm-synthtrace-client';
import { pipeline, Readable, Transform } from 'stream';
import { SynthtraceEsClient, SynthtraceEsClientOptions } from '../shared/base_client';
import { getDedotTransform } from '../shared/get_dedot_transform';
import { getSerializeTransform } from '../shared/get_serialize_transform';
import { Logger } from '../utils/create_logger';

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

export class AlertsSynthtraceEsClient extends SynthtraceEsClient<AlertEntityDocument> {
constructor(options: { client: Client; logger: Logger } & AlertsSynthtraceEsClientOptions) {
super({
...options,
pipeline: alertsPipeline(),
});
this.dataStreams = ['alerts-observability.apm*', 'alerts-observability.metrics*'];
}
}

function alertsPipeline() {
return (base: Readable) => {
return pipeline(
base,
getSerializeTransform(),
getRoutingTransform(),
getDedotTransform(),
(err: unknown) => {
if (err) {
throw err;
}
}
);
};
}

function getRoutingTransform() {
return new Transform({
objectMode: true,
transform(document: ESDocumentWithOperation<AlertEntityDocument>, encoding, callback) {
const alertProducer = document['kibana.alert.rule.producer'];
if (alertProducer === 'apm') {
document._index = 'alerts-observability.apm.alerts-default';
} else if (alertProducer === 'infrastructure') {
document._index = 'alerts-observability.metrics.alerts-default';
} else {
throw new Error('Cannot determine index for event');
}

callback(null, document);
},
});
}
Loading

0 comments on commit 50db60a

Please sign in to comment.