Skip to content

Commit

Permalink
[RAM] Add example log system action type (#175057)
Browse files Browse the repository at this point in the history
## Summary

<img width="449" alt="Screenshot 2024-01-17 at 11 29 36 AM"
src="https://github.com/elastic/kibana/assets/1445834/f95aa7f0-54fa-4681-a1f7-1a9af19c884c">
<img width="493" alt="Screenshot 2024-01-17 at 11 29 32 AM"
src="https://github.com/elastic/kibana/assets/1445834/44c7be21-b23b-4d7a-b9ea-66394a767abe">

This adds an example action type called System Log, which is enabled
when running Kibana with the `--run-examples` flag.

This action will log out to Kibana at the same rate as summarized
alerts.

**Please only refer to
[29fa70d](29fa70d)
when reviewing. Other code changes were cherry-picked from `main`**

---------

Co-authored-by: Ying Mao <ying.mao@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
3 people authored Jan 30, 2024
1 parent 21f0a78 commit 299142c
Show file tree
Hide file tree
Showing 62 changed files with 1,271 additions and 188 deletions.
2 changes: 1 addition & 1 deletion NOTICE.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Kibana source code with Kibana X-Pack source code
Copyright 2012-2023 Elasticsearch B.V.
Copyright 2012-2024 Elasticsearch B.V.

---
Pretty handling of logarithmic axes.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ export const schemaGeoPoint = rt.union([
export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const %%schemaPrefix%%Required = %%REQUIRED_FIELDS%%;
// prettier-ignore
const %%schemaPrefix%%Optional = %%OPTIONAL_FIELDS%%;
// prettier-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const AlertRequired = rt.type({
'kibana.alert.uuid': schemaString,
'kibana.space_ids': schemaStringArray,
});
// prettier-ignore
const AlertOptional = rt.partial({
'event.action': schemaString,
'event.kind': schemaString,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* 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.
*/
// ---------------------------------- WARNING ----------------------------------
// this file was generated, and should not be edited by hand
// ---------------------------------- WARNING ----------------------------------
import * as rt from 'io-ts';
import { Either } from 'fp-ts/lib/Either';
import { AlertSchema } from './alert_schema';
const ISO_DATE_PATTERN = /^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$/;
export const IsoDateString = new rt.Type<string, string, unknown>(
'IsoDateString',
rt.string.is,
(input, context): Either<rt.Errors, string> => {
if (typeof input === 'string' && ISO_DATE_PATTERN.test(input)) {
return rt.success(input);
} else {
return rt.failure(input, context);
}
},
rt.identity
);
export type IsoDateStringC = typeof IsoDateString;
export const schemaUnknown = rt.unknown;
export const schemaUnknownArray = rt.array(rt.unknown);
export const schemaString = rt.string;
export const schemaStringArray = rt.array(schemaString);
export const schemaNumber = rt.number;
export const schemaNumberArray = rt.array(schemaNumber);
export const schemaDate = rt.union([IsoDateString, schemaNumber]);
export const schemaDateArray = rt.array(schemaDate);
export const schemaDateRange = rt.partial({
gte: schemaDate,
lte: schemaDate,
});
export const schemaDateRangeArray = rt.array(schemaDateRange);
export const schemaStringOrNumber = rt.union([schemaString, schemaNumber]);
export const schemaStringOrNumberArray = rt.array(schemaStringOrNumber);
export const schemaBoolean = rt.boolean;
export const schemaBooleanArray = rt.array(schemaBoolean);
const schemaGeoPointCoords = rt.type({
type: schemaString,
coordinates: schemaNumberArray,
});
const schemaGeoPointString = schemaString;
const schemaGeoPointLatLon = rt.type({
lat: schemaNumber,
lon: schemaNumber,
});
const schemaGeoPointLocation = rt.type({
location: schemaNumberArray,
});
const schemaGeoPointLocationString = rt.type({
location: schemaString,
});
export const schemaGeoPoint = rt.union([
schemaGeoPointCoords,
schemaGeoPointString,
schemaGeoPointLatLon,
schemaGeoPointLocation,
schemaGeoPointLocationString,
]);
export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const DefaultAlertRequired = rt.type({
});
// prettier-ignore
const DefaultAlertOptional = rt.partial({
});

// prettier-ignore
export const DefaultAlertSchema = rt.intersection([DefaultAlertRequired, DefaultAlertOptional, AlertSchema]);
// prettier-ignore
export type DefaultAlert = rt.TypeOf<typeof DefaultAlertSchema>;
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const EcsRequired = rt.type({
'@timestamp': schemaDate,
'ecs.version': schemaString,
});
// prettier-ignore
const EcsOptional = rt.partial({
'agent.build.original': schemaString,
'agent.ephemeral_id': schemaString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const LegacyAlertRequired = rt.type({
});
// prettier-ignore
const LegacyAlertOptional = rt.partial({
'ecs.version': schemaString,
'kibana.alert.risk_score': schemaNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
const MlAnomalyDetectionAlertRequired = rt.type({
'kibana.alert.job_id': schemaString,
});
// prettier-ignore
const MlAnomalyDetectionAlertOptional = rt.partial({
'kibana.alert.anomaly_score': schemaNumber,
'kibana.alert.anomaly_timestamp': schemaDate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const ObservabilityApmAlertRequired = rt.type({
});
// prettier-ignore
const ObservabilityApmAlertOptional = rt.partial({
'agent.name': schemaString,
'error.grouping_key': schemaString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const ObservabilityLogsAlertRequired = rt.type({
});
// prettier-ignore
const ObservabilityLogsAlertOptional = rt.partial({
'kibana.alert.context': schemaUnknown,
'kibana.alert.evaluation.threshold': schemaStringOrNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const ObservabilityMetricsAlertRequired = rt.type({
});
// prettier-ignore
const ObservabilityMetricsAlertOptional = rt.partial({
'kibana.alert.context': schemaUnknown,
'kibana.alert.evaluation.threshold': schemaStringOrNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const ObservabilitySloAlertRequired = rt.type({
});
// prettier-ignore
const ObservabilitySloAlertOptional = rt.partial({
'kibana.alert.context': schemaUnknown,
'kibana.alert.evaluation.threshold': schemaStringOrNumber,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const ObservabilityUptimeAlertRequired = rt.type({
});
// prettier-ignore
const ObservabilityUptimeAlertOptional = rt.partial({
'agent.name': schemaString,
'anomaly.bucket_span.minutes': schemaString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ const SecurityAlertRequired = rt.type({
'kibana.alert.uuid': schemaString,
'kibana.space_ids': schemaStringArray,
});
// prettier-ignore
const SecurityAlertOptional = rt.partial({
'ecs.version': schemaString,
'event.action': schemaString,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export const schemaGeoPointArray = rt.array(schemaGeoPoint);
// prettier-ignore
const StackAlertRequired = rt.type({
});
// prettier-ignore
const StackAlertOptional = rt.partial({
'kibana.alert.evaluation.conditions': schemaString,
'kibana.alert.evaluation.threshold': schemaStringOrNumber,
Expand Down
5 changes: 4 additions & 1 deletion packages/kbn-alerts-as-data-utils/src/schemas/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { ObservabilitySloAlert } from './generated/observability_slo_schema
import type { ObservabilityUptimeAlert } from './generated/observability_uptime_schema';
import type { SecurityAlert } from './generated/security_schema';
import type { MlAnomalyDetectionAlert } from './generated/ml_anomaly_detection_schema';
import type { DefaultAlert } from './generated/default_schema';

export * from './create_schema_from_field_map';

Expand All @@ -26,6 +27,7 @@ export type { ObservabilityUptimeAlert } from './generated/observability_uptime_
export type { SecurityAlert } from './generated/security_schema';
export type { StackAlert } from './generated/stack_schema';
export type { MlAnomalyDetectionAlert } from './generated/ml_anomaly_detection_schema';
export type { DefaultAlert } from './generated/default_schema';

export type AADAlert =
| Alert
Expand All @@ -35,4 +37,5 @@ export type AADAlert =
| ObservabilitySloAlert
| ObservabilityUptimeAlert
| SecurityAlert
| MlAnomalyDetectionAlert;
| MlAnomalyDetectionAlert
| DefaultAlert;
2 changes: 2 additions & 0 deletions packages/kbn-rule-data-utils/src/alerts_as_data_rbac.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ export const AlertConsumers = {
SIEM: 'siem',
UPTIME: 'uptime',
ML: 'ml',
STACK_ALERTS: 'stackAlerts',
EXAMPLE: 'AlertingExample',
} as const;
export type AlertConsumers = typeof AlertConsumers[keyof typeof AlertConsumers];
export type STATUS_VALUES = 'open' | 'acknowledged' | 'closed' | 'in-progress'; // TODO: remove 'in-progress' after migration to 'acknowledged'
Expand Down
22 changes: 11 additions & 11 deletions x-pack/examples/alerting_example/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common';
import { PluginSetupContract as AlertingSetup } from '@kbn/alerting-plugin/server';
import { PluginSetupContract as FeaturesPluginSetup } from '@kbn/features-plugin/server';

import { alertType as alwaysFiringAlert } from './alert_types/always_firing';
import { alertType as peopleInSpaceAlert } from './alert_types/astros';
import { alertType as patternAlert } from './alert_types/pattern';
import { ruleType as alwaysFiringRule } from './rule_types/always_firing';
import { ruleType as peopleInSpaceRule } from './rule_types/astros';
import { ruleType as patternRule } from './rule_types/pattern';
// can't import static code from another plugin to support examples functional test
const INDEX_THRESHOLD_ID = '.index-threshold';
import { ALERTING_EXAMPLE_APP_ID } from '../common/constants';
Expand All @@ -27,9 +27,9 @@ export interface AlertingExampleDeps {

export class AlertingExamplePlugin implements Plugin<void, void, AlertingExampleDeps> {
public setup(core: CoreSetup, { alerting, features }: AlertingExampleDeps) {
alerting.registerType(alwaysFiringAlert);
alerting.registerType(peopleInSpaceAlert);
alerting.registerType(patternAlert);
alerting.registerType(alwaysFiringRule);
alerting.registerType(peopleInSpaceRule);
alerting.registerType(patternRule);

features.registerKibanaFeature({
id: ALERTING_EXAMPLE_APP_ID,
Expand All @@ -41,15 +41,15 @@ export class AlertingExamplePlugin implements Plugin<void, void, AlertingExample
insightsAndAlerting: ['triggersActions'],
},
category: DEFAULT_APP_CATEGORIES.management,
alerting: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID],
alerting: [alwaysFiringRule.id, peopleInSpaceRule.id, INDEX_THRESHOLD_ID],
privileges: {
all: {
alerting: {
rule: {
all: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID],
all: [alwaysFiringRule.id, peopleInSpaceRule.id, INDEX_THRESHOLD_ID],
},
alert: {
all: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID],
all: [alwaysFiringRule.id, peopleInSpaceRule.id, INDEX_THRESHOLD_ID],
},
},
savedObject: {
Expand All @@ -64,10 +64,10 @@ export class AlertingExamplePlugin implements Plugin<void, void, AlertingExample
read: {
alerting: {
rule: {
read: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID],
read: [alwaysFiringRule.id, peopleInSpaceRule.id, INDEX_THRESHOLD_ID],
},
alert: {
read: [alwaysFiringAlert.id, peopleInSpaceAlert.id, INDEX_THRESHOLD_ID],
read: [alwaysFiringRule.id, peopleInSpaceRule.id, INDEX_THRESHOLD_ID],
},
},
savedObject: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@

import { v4 as uuidv4 } from 'uuid';
import { range } from 'lodash';
import { RuleType } from '@kbn/alerting-plugin/server';
import {
DEFAULT_AAD_CONFIG,
RuleType,
RuleTypeState,
AlertsClientError,
} from '@kbn/alerting-plugin/server';
import { schema } from '@kbn/config-schema';
import type { DefaultAlert } from '@kbn/alerts-as-data-utils';
import {
DEFAULT_INSTANCES_TO_GENERATE,
ALERTING_EXAMPLE_APP_ID,
Expand All @@ -17,6 +23,12 @@ import {
} from '../../common/constants';

type ActionGroups = 'small' | 'medium' | 'large';
interface State extends RuleTypeState {
count?: number;
}
interface AlertState {
triggerdOnCycle: number;
}
const DEFAULT_ACTION_GROUP: ActionGroups = 'small';

function getTShirtSizeByIdAndThreshold(
Expand All @@ -38,13 +50,15 @@ function getTShirtSizeByIdAndThreshold(
return DEFAULT_ACTION_GROUP;
}

export const alertType: RuleType<
export const ruleType: RuleType<
AlwaysFiringParams,
never,
{ count?: number },
{ triggerdOnCycle: number },
State,
AlertState,
never,
AlwaysFiringActionGroupIds
AlwaysFiringActionGroupIds,
never,
DefaultAlert
> = {
id: 'example.always-firing',
name: 'Always firing',
Expand All @@ -61,15 +75,20 @@ export const alertType: RuleType<
params: { instances = DEFAULT_INSTANCES_TO_GENERATE, thresholds },
state,
}) {
const { alertsClient } = services;
if (!alertsClient) {
throw new AlertsClientError();
}
const count = (state.count ?? 0) + 1;

range(instances)
.map(() => uuidv4())
.forEach((id: string) => {
services.alertFactory
.create(id)
.replaceState({ triggerdOnCycle: count })
.scheduleActions(getTShirtSizeByIdAndThreshold(id, thresholds));
alertsClient.report({
id,
actionGroup: getTShirtSizeByIdAndThreshold(id, thresholds),
state: { triggerdOnCycle: count },
});
});

return {
Expand All @@ -92,4 +111,5 @@ export const alertType: RuleType<
),
}),
},
alerts: DEFAULT_AAD_CONFIG,
};
Loading

0 comments on commit 299142c

Please sign in to comment.