Skip to content
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

[RAC] Populate Observability alerts table with data from alerts indices #96692

Merged
merged 29 commits into from
Apr 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2a2e9bc
Set up Observability rule APIs
dgieselaar Apr 8, 2021
4b585f7
Populate alerts table with data from API
dgieselaar Apr 9, 2021
4401d37
Move field map types/utils to common
dgieselaar Apr 11, 2021
383eb78
Format reason/link in alert type
dgieselaar Apr 12, 2021
0a60956
Format reason/link in alert type
dgieselaar Apr 12, 2021
d95d3d8
Merge branch 'master' of github.com:elastic/kibana into observability…
dgieselaar Apr 12, 2021
a30fc84
Fix issues with tsconfigs
dgieselaar Apr 12, 2021
e72e9b4
Storybook cleanup for example alerts
smith Apr 12, 2021
f5bb6f9
Store/display evaluations, add active/recovered badge
dgieselaar Apr 12, 2021
6dcf396
Some more story fixes
smith Apr 12, 2021
54d851a
Merge branch 'master' of github.com:elastic/kibana into observability…
dgieselaar Apr 13, 2021
46cda90
Decode rule data with type from owning registry
dgieselaar Apr 13, 2021
ab29974
Merge branch 'master' of github.com:elastic/kibana into observability…
dgieselaar Apr 13, 2021
f6e7997
Use transaction type/environment in link to app
dgieselaar Apr 13, 2021
c3f63c4
Fix type issues
dgieselaar Apr 13, 2021
075a3c7
Merge branch 'master' of github.com:elastic/kibana into observability…
dgieselaar Apr 13, 2021
2832e18
Merge branch 'observability-rule-apis' of github.com:dgieselaar/kiban…
dgieselaar Apr 13, 2021
b578fa7
Fix API tests
dgieselaar Apr 13, 2021
e72de87
Merge branch 'master' of github.com:elastic/kibana into observability…
dgieselaar Apr 14, 2021
6089beb
Undo changes in task_runner.ts
dgieselaar Apr 14, 2021
728fc3f
Remove Mutable<> wrappers for field map
dgieselaar Apr 14, 2021
5c190a8
Remove logger.debug calls in alerting es client
dgieselaar Apr 14, 2021
d745a25
Add API test for recovery of alerts
dgieselaar Apr 14, 2021
ba9caea
Merge branch 'master' of github.com:elastic/kibana into observability…
dgieselaar Apr 14, 2021
79a98b9
Revert changes to src/core/server/http/router
dgieselaar Apr 14, 2021
4a5d7bb
Use type imports where possible
dgieselaar Apr 14, 2021
1b0c9c1
Update limits
dgieselaar Apr 14, 2021
110a762
Set limit to 100kb
dgieselaar Apr 14, 2021
64b637c
Merge branch 'master' of github.com:elastic/kibana into observability…
dgieselaar Apr 14, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/kbn-io-ts-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
export { jsonRt } from './json_rt';
export { mergeRt } from './merge_rt';
export { strictKeysRt } from './strict_keys_rt';
export { isoToEpochRt } from './iso_to_epoch_rt';
export { toNumberRt } from './to_number_rt';
export { toBooleanRt } from './to_boolean_rt';
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* 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.
* 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 { isoToEpochRt } from './index';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* 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.
* 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 * as t from 'io-ts';
Expand All @@ -17,9 +18,7 @@ export const isoToEpochRt = new t.Type<number, string, unknown>(
(input, context) =>
either.chain(t.string.validate(input, context), (str) => {
const epochDate = new Date(str).getTime();
return isNaN(epochDate)
? t.failure(input, context)
: t.success(epochDate);
return isNaN(epochDate) ? t.failure(input, context) : t.success(epochDate);
}),
(output) => new Date(output).toISOString()
);
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* 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.
* 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 * as t from 'io-ts';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/*
* 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.
* 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 * as t from 'io-ts';
Expand Down
1 change: 1 addition & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ pageLoadAssetSize:
remoteClusters: 51327
reporting: 183418
rollup: 97204
ruleRegistry: 100000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know this is a bit late, but shouldn't this be near 0 since there's no actual UI yet?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There isn't any UI, but there is the rule registry setup/and start methods and the RuleRegistry class is exported. The bundle includes some io/fp-ts utils and the ECS field mapping, which takes up most of the space.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's down to 10kb now.

savedObjects: 108518
savedObjectsManagement: 101836
savedObjectsTagging: 59482
Expand Down
25 changes: 25 additions & 0 deletions x-pack/plugins/apm/common/rules.ts
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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

const plainApmRuleRegistrySettings = {
name: 'apm',
fieldMap: {
'service.environment': {
type: 'keyword',
},
'transaction.type': {
type: 'keyword',
},
'processor.event': {
type: 'keyword',
},
},
} as const;

type APMRuleRegistrySettings = typeof plainApmRuleRegistrySettings;

export const apmRuleRegistrySettings: APMRuleRegistrySettings = plainApmRuleRegistrySettings;
115 changes: 106 additions & 9 deletions x-pack/plugins/apm/public/components/alerting/register_apm_alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,39 @@

import { i18n } from '@kbn/i18n';
import { lazy } from 'react';
import { format } from 'url';
import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values';
import { asDuration, asPercent } from '../../../common/utils/formatters';
import { AlertType } from '../../../common/alert_types';
import { ApmPluginStartDeps } from '../../plugin';
import { ApmRuleRegistry } from '../../plugin';

export function registerApmAlerts(
alertTypeRegistry: ApmPluginStartDeps['triggersActionsUi']['alertTypeRegistry']
) {
alertTypeRegistry.register({
export function registerApmAlerts(apmRuleRegistry: ApmRuleRegistry) {
apmRuleRegistry.registerType({
id: AlertType.ErrorCount,
description: i18n.translate('xpack.apm.alertTypes.errorCount.description', {
defaultMessage:
'Alert when the number of errors in a service exceeds a defined threshold.',
}),
format: ({ alert }) => {
return {
reason: i18n.translate('xpack.apm.alertTypes.errorCount.reason', {
defaultMessage: `Error count is greater than {threshold} (current value is {measured}) for {serviceName}`,
values: {
threshold: alert['kibana.observability.evaluation.threshold'],
measured: alert['kibana.observability.evaluation.value'],
serviceName: alert['service.name']!,
},
}),
link: format({
pathname: `/app/apm/services/${alert['service.name']!}`,
query: {
...(alert['service.environment']
? { environment: alert['service.environment'] }
: { environment: ENVIRONMENT_ALL.value }),
},
}),
};
},
iconClass: 'bell',
documentationUrl(docLinks) {
return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`;
Expand All @@ -41,7 +62,7 @@ export function registerApmAlerts(
),
});

alertTypeRegistry.register({
apmRuleRegistry.registerType({
id: AlertType.TransactionDuration,
description: i18n.translate(
'xpack.apm.alertTypes.transactionDuration.description',
Expand All @@ -50,6 +71,32 @@ export function registerApmAlerts(
'Alert when the latency of a specific transaction type in a service exceeds a defined threshold.',
}
),
format: ({ alert }) => ({
reason: i18n.translate(
'xpack.apm.alertTypes.transactionDuration.reason',
{
defaultMessage: `Latency is above {threshold} (current value is {measured}) for {serviceName}`,
values: {
threshold: asDuration(
alert['kibana.observability.evaluation.threshold']
),
measured: asDuration(
alert['kibana.observability.evaluation.value']
),
serviceName: alert['service.name']!,
},
}
),
link: format({
pathname: `/app/apm/services/${alert['service.name']!}`,
query: {
transactionType: alert['transaction.type']!,
...(alert['service.environment']
? { environment: alert['service.environment'] }
: { environment: ENVIRONMENT_ALL.value }),
},
}),
}),
iconClass: 'bell',
documentationUrl(docLinks) {
return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`;
Expand All @@ -75,7 +122,7 @@ export function registerApmAlerts(
),
});

alertTypeRegistry.register({
apmRuleRegistry.registerType({
id: AlertType.TransactionErrorRate,
description: i18n.translate(
'xpack.apm.alertTypes.transactionErrorRate.description',
Expand All @@ -84,6 +131,34 @@ export function registerApmAlerts(
'Alert when the rate of transaction errors in a service exceeds a defined threshold.',
}
),
format: ({ alert }) => ({
reason: i18n.translate(
'xpack.apm.alertTypes.transactionErrorRate.reason',
{
defaultMessage: `Transaction error rate is greater than {threshold} (current value is {measured}) for {serviceName}`,
values: {
threshold: asPercent(
alert['kibana.observability.evaluation.threshold'],
100
),
measured: asPercent(
alert['kibana.observability.evaluation.value'],
100
),
serviceName: alert['service.name']!,
},
}
),
link: format({
pathname: `/app/apm/services/${alert['service.name']!}`,
query: {
transactionType: alert['transaction.type']!,
...(alert['service.environment']
? { environment: alert['service.environment'] }
: { environment: ENVIRONMENT_ALL.value }),
},
}),
}),
iconClass: 'bell',
documentationUrl(docLinks) {
return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`;
Expand All @@ -109,14 +184,36 @@ export function registerApmAlerts(
),
});

alertTypeRegistry.register({
apmRuleRegistry.registerType({
id: AlertType.TransactionDurationAnomaly,
description: i18n.translate(
'xpack.apm.alertTypes.transactionDurationAnomaly.description',
{
defaultMessage: 'Alert when the latency of a service is abnormal.',
}
),
format: ({ alert }) => ({
reason: i18n.translate(
'xpack.apm.alertTypes.transactionDurationAnomaly.reason',
{
defaultMessage: `{severityLevel} anomaly detected for {serviceName} (score was {measured})`,
values: {
serviceName: alert['service.name'],
severityLevel: alert['kibana.rac.alert.severity.level'],
measured: alert['kibana.observability.evaluation.value'],
},
}
),
link: format({
pathname: `/app/apm/services/${alert['service.name']!}`,
query: {
transactionType: alert['transaction.type']!,
...(alert['service.environment']
? { environment: alert['service.environment'] }
: { environment: ENVIRONMENT_ALL.value }),
},
}),
}),
iconClass: 'bell',
documentationUrl(docLinks) {
return `${docLinks.ELASTIC_WEBSITE_URL}guide/en/kibana/${docLinks.DOC_LINK_VERSION}/apm-alerts.html`;
Expand All @@ -137,7 +234,7 @@ export function registerApmAlerts(
- Type: \\{\\{context.transactionType\\}\\}
- Environment: \\{\\{context.environment\\}\\}
- Severity threshold: \\{\\{context.threshold\\}\\}
- Severity value: \\{\\{context.thresholdValue\\}\\}
- Severity value: \\{\\{context.triggerValue\\}\\}
`,
}
),
Expand Down
20 changes: 17 additions & 3 deletions x-pack/plugins/apm/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { ConfigSchema } from '.';
import {
FetchDataParams,
FormatterRuleRegistry,
HasDataParams,
ObservabilityPublicSetup,
} from '../../observability/public';
Expand Down Expand Up @@ -40,8 +41,11 @@ import { EmbeddableStart } from '../../../../src/plugins/embeddable/public';
import { registerApmAlerts } from './components/alerting/register_apm_alerts';
import { MlPluginSetup, MlPluginStart } from '../../ml/public';
import { MapsStartApi } from '../../maps/public';
import { apmRuleRegistrySettings } from '../common/rules';

export type ApmPluginSetup = ReturnType<ApmPlugin['setup']>;
export type ApmRuleRegistry = ApmPluginSetup['ruleRegistry'];

export type ApmPluginSetup = void;
export type ApmPluginStart = void;

export interface ApmPluginSetupDeps {
Expand All @@ -52,7 +56,7 @@ export interface ApmPluginSetupDeps {
home?: HomePublicPluginSetup;
licensing: LicensingPluginSetup;
triggersActionsUi: TriggersAndActionsUIPublicPluginSetup;
observability?: ObservabilityPublicSetup;
observability: ObservabilityPublicSetup;
}

export interface ApmPluginStartDeps {
Expand Down Expand Up @@ -156,6 +160,13 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
},
});

const apmRuleRegistry = plugins.observability.ruleRegistry.create({
...apmRuleRegistrySettings,
ctor: FormatterRuleRegistry,
});

registerApmAlerts(apmRuleRegistry);

core.application.register({
id: 'ux',
title: 'User Experience',
Expand Down Expand Up @@ -196,9 +207,12 @@ export class ApmPlugin implements Plugin<ApmPluginSetup, ApmPluginStart> {
);
},
});

return {
ruleRegistry: apmRuleRegistry,
};
}
public start(core: CoreStart, plugins: ApmPluginStartDeps) {
toggleAppLinkInNav(core, this.initializerContext.config.get());
registerApmAlerts(plugins.triggersActionsUi.alertTypeRegistry);
}
}
12 changes: 9 additions & 3 deletions x-pack/plugins/apm/scripts/optimize-tsconfig/optimize.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@ async function setIgnoreChanges() {
}
}

async function deleteApmTsConfig() {
await unlink(path.resolve(kibanaRoot, 'x-pack/plugins/apm', 'tsconfig.json'));
async function deleteTsConfigs() {
const toDelete = ['apm', 'observability', 'rule_registry'];

for (const app of toDelete) {
await unlink(
path.resolve(kibanaRoot, 'x-pack/plugins', app, 'tsconfig.json')
);
}
}

async function optimizeTsConfig() {
Expand All @@ -98,7 +104,7 @@ async function optimizeTsConfig() {

await addApmFilesToTestTsConfig();

await deleteApmTsConfig();
await deleteTsConfigs();

await setIgnoreChanges();
// eslint-disable-next-line no-console
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/apm/scripts/optimize-tsconfig/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ const filesToIgnore = [
path.resolve(kibanaRoot, 'tsconfig.json'),
path.resolve(kibanaRoot, 'tsconfig.base.json'),
path.resolve(kibanaRoot, 'x-pack/plugins/apm', 'tsconfig.json'),
path.resolve(kibanaRoot, 'x-pack/plugins/observability', 'tsconfig.json'),
path.resolve(kibanaRoot, 'x-pack/plugins/rule_registry', 'tsconfig.json'),
path.resolve(kibanaRoot, 'x-pack/test', 'tsconfig.json'),
];

Expand Down
11 changes: 7 additions & 4 deletions x-pack/plugins/apm/server/lib/alerts/alerting_es_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,17 @@ import {
} from '../../../../../../typings/elasticsearch';
import { AlertServices } from '../../../../alerting/server';

export async function alertingEsClient<TParams extends ESSearchRequest>(
export async function alertingEsClient<TParams extends ESSearchRequest>({
scopedClusterClient,
params,
}: {
scopedClusterClient: AlertServices<
never,
never,
never
>['scopedClusterClient'],
params: TParams
): Promise<ESSearchResponse<unknown, TParams>> {
>['scopedClusterClient'];
params: TParams;
}): Promise<ESSearchResponse<unknown, TParams>> {
const response = await scopedClusterClient.asCurrentUser.search({
...params,
ignore_unavailable: true,
Expand Down
Loading