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

[ML] Explain log rate spikes: Plugin setup #131317

Merged
merged 45 commits into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from 43 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
41d413f
[ML] AIOps plugin setup.
walterra Apr 29, 2022
f19c6d4
[ML] Stream demo.
walterra May 2, 2022
54c7784
[ML] Break out card components.
walterra May 2, 2022
e7fb0fd
[ML] Remove console.logs.
walterra May 3, 2022
614d5b4
[ML] Additional plugin boilerplate.
walterra May 3, 2022
daa4734
[ML] Fix cancelling/error handling.
walterra May 3, 2022
73ce845
[ML] Fix linting/types.
walterra May 3, 2022
da38fe3
[ML] Fix tsconfig.json.
walterra May 3, 2022
64dcba9
[ML] Fix docs.
walterra May 3, 2022
4618dfb
[ML] Fix tsconfig.json.
walterra May 3, 2022
6d64d5b
[ML] Fix optimizer limits.
walterra May 3, 2022
1e1a431
[ML] Fix application usage schema.
walterra May 3, 2022
3ed87af
[ML] Telemetry fix.
walterra May 3, 2022
8188782
[ML] Move spike analysis from top level page to a page within the ML …
walterra May 3, 2022
955093b
[ML] Fix breadcrumb.
walterra May 3, 2022
750590c
[ML] Fix translations setup.
walterra May 4, 2022
b3d2de3
[ML] Fix public APIs missing comments.
walterra May 4, 2022
3d4a608
[ML] Remove app level schema.
walterra May 4, 2022
3c1407c
[ML] Fix telemetry check.
walterra May 4, 2022
c34ff6c
[ML] Fix missing export.
walterra May 4, 2022
21b2727
[ML] Migrate GIF battle to bar chart race without 3rd party references.
walterra May 4, 2022
c9e8a21
[ML] Add hard coded feature flag.
walterra May 5, 2022
61081f6
[ML] Make AIOps menu entry a non-clickable section header.
walterra May 5, 2022
36d4671
[ML] API integration test.
walterra May 5, 2022
cbc8b54
[ML] API integration test to read stream.
walterra May 5, 2022
d97a646
[ML] Fix stream decoding in Firefox.
walterra May 6, 2022
91e3dce
Merge branch 'main' into ml-aiops-plugin
walterra May 6, 2022
9fd3eaf
[ML] Improved types, error handling.
walterra May 9, 2022
1fbab8d
Merge branch 'main' into ml-aiops-plugin
walterra May 9, 2022
9fffb56
[ML] Tweak checkbox label.
walterra May 9, 2022
584bee8
[ML] Tweak button text.
walterra May 10, 2022
3ee63c6
Merge branch 'main' into ml-aiops-plugin
walterra May 10, 2022
b018e6f
[ML] Fix to apply basepath.
walterra May 11, 2022
63fe364
[ML] Add comment to explain buffer clearing.
walterra May 11, 2022
6825ea7
[ML] Fix typos.
walterra May 11, 2022
bbe2c5e
[ML] Fix unintentional double check.
walterra May 11, 2022
6ac022a
[ML] Fix typo.
walterra May 11, 2022
e523670
[ML] Update README.md intro text.
walterra May 11, 2022
b393103
[ML] Remove unnecessary i18n file.
walterra May 11, 2022
1c63220
[ML] Fix typo.
walterra May 11, 2022
f5b98ee
[ML] Fix integration test tags.
walterra May 11, 2022
0ce498b
Merge branch 'main' into ml-aiops-plugin
walterra May 11, 2022
3ee4d50
[CI] Auto-commit changed files from 'node scripts/build_plugin_list_d…
kibanamachine May 11, 2022
4204428
[ML] Remove duplicate license header.
walterra May 11, 2022
a91b226
Merge branch 'ml-aiops-plugin' of github.com:walterra/kibana into ml-…
walterra May 11, 2022
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
5 changes: 3 additions & 2 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,11 @@
/x-pack/test/screenshot_creation/apps/ml_docs @elastic/ml-ui
/x-pack/test/screenshot_creation/services/ml_screenshots.ts @elastic/ml-ui

# ML team owns and maintains the transform plugin despite it living in the Data management section.
/x-pack/plugins/transform/ @elastic/ml-ui
# Additional plugins maintained by the ML team.
/x-pack/plugins/aiops/ @elastic/ml-ui
/x-pack/plugins/data_visualizer/ @elastic/ml-ui
/x-pack/plugins/file_upload/ @elastic/ml-ui
/x-pack/plugins/transform/ @elastic/ml-ui
/x-pack/test/accessibility/apps/transform.ts @elastic/ml-ui
/x-pack/test/api_integration/apis/transform/ @elastic/ml-ui
/x-pack/test/api_integration_basic/apis/transform/ @elastic/ml-ui
Expand Down
4 changes: 4 additions & 0 deletions docs/developer/plugin-list.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,10 @@ The plugin exposes the static DefaultEditorController class to consume.
|The Kibana actions plugin provides a framework to create executable actions. You can:


|{kib-repo}blob/{branch}/x-pack/plugins/aiops/README.md[aiops]
|The plugin provides APIs and components for AIOps features, including the “Explain log rate spikes” UI, maintained by the ML team.


|{kib-repo}blob/{branch}/x-pack/plugins/alerting/README.md[alerting]
|The Kibana Alerting plugin provides a common place to set up rules. You can:

Expand Down
1 change: 1 addition & 0 deletions packages/kbn-optimizer/limits.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pageLoadAssetSize:
advancedSettings: 27596
actions: 20000
aiops: 10000
alerting: 106936
apm: 64385
canvas: 1066647
Expand Down
2 changes: 2 additions & 0 deletions tsconfig.base.json
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,8 @@
"@kbn/ui-actions-enhanced-examples-plugin/*": ["x-pack/examples/ui_actions_enhanced_examples/*"],
"@kbn/actions-plugin": ["x-pack/plugins/actions"],
"@kbn/actions-plugin/*": ["x-pack/plugins/actions/*"],
"@kbn/aiops-plugin": ["x-pack/plugins/aiops"],
"@kbn/aiops-plugin/*": ["x-pack/plugins/aiops/*"],
"@kbn/alerting-plugin": ["x-pack/plugins/alerting"],
"@kbn/alerting-plugin/*": ["x-pack/plugins/alerting/*"],
"@kbn/apm-plugin": ["x-pack/plugins/apm"],
Expand Down
1 change: 1 addition & 0 deletions x-pack/.i18nrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"xpack.logstash": ["plugins/logstash"],
"xpack.main": "legacy/plugins/xpack_main",
"xpack.maps": ["plugins/maps"],
"xpack.aiops": ["plugins/aiops"],
"xpack.ml": ["plugins/ml"],
"xpack.monitoring": ["plugins/monitoring"],
"xpack.osquery": ["plugins/osquery"],
Expand Down
9 changes: 9 additions & 0 deletions x-pack/plugins/aiops/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# aiops

The plugin provides APIs and components for AIOps features, including the “Explain log rate spikes” UI, maintained by the ML team.

---

## Development

See the [kibana contributing guide](https://github.com/elastic/kibana/blob/main/CONTRIBUTING.md) for instructions setting up your development environment.
68 changes: 68 additions & 0 deletions x-pack/plugins/aiops/common/api/example_stream.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* 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.
*/

import { schema, TypeOf } from '@kbn/config-schema';

export const aiopsExampleStreamSchema = schema.object({
/** Boolean flag to enable/disabling simulation of response errors. */
simulateErrors: schema.maybe(schema.boolean()),
/** Maximum timeout between streaming messages. */
timeout: schema.maybe(schema.number()),
});

export type AiopsExampleStreamSchema = TypeOf<typeof aiopsExampleStreamSchema>;

export const API_ACTION_NAME = {
UPDATE_PROGRESS: 'update_progress',
ADD_TO_ENTITY: 'add_to_entity',
DELETE_ENTITY: 'delete_entity',
} as const;
export type ApiActionName = typeof API_ACTION_NAME[keyof typeof API_ACTION_NAME];

interface ApiActionUpdateProgress {
type: typeof API_ACTION_NAME.UPDATE_PROGRESS;
payload: number;
}

export function updateProgressAction(payload: number): ApiActionUpdateProgress {
return {
type: API_ACTION_NAME.UPDATE_PROGRESS,
payload,
};
}

interface ApiActionAddToEntity {
type: typeof API_ACTION_NAME.ADD_TO_ENTITY;
payload: {
entity: string;
value: number;
};
}

export function addToEntityAction(entity: string, value: number): ApiActionAddToEntity {
return {
type: API_ACTION_NAME.ADD_TO_ENTITY,
payload: {
entity,
value,
},
};
}

interface ApiActionDeleteEntity {
type: typeof API_ACTION_NAME.DELETE_ENTITY;
payload: string;
}

export function deleteEntityAction(payload: string): ApiActionDeleteEntity {
return {
type: API_ACTION_NAME.DELETE_ENTITY,
payload,
};
}

export type ApiAction = ApiActionUpdateProgress | ApiActionAddToEntity | ApiActionDeleteEntity;
19 changes: 19 additions & 0 deletions x-pack/plugins/aiops/common/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* 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.
*/

import type { AiopsExampleStreamSchema } from './example_stream';

export const API_ENDPOINT = {
EXAMPLE_STREAM: '/internal/aiops/example_stream',
ANOTHER: '/internal/aiops/another',
} as const;
export type ApiEndpoint = typeof API_ENDPOINT[keyof typeof API_ENDPOINT];

export interface ApiEndpointOptions {
[API_ENDPOINT.EXAMPLE_STREAM]: AiopsExampleStreamSchema;
[API_ENDPOINT.ANOTHER]: { anotherOption: string };
}
22 changes: 22 additions & 0 deletions x-pack/plugins/aiops/common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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.
*/

/**
* PLUGIN_ID is used as a unique identifier for the aiops plugin
*/
export const PLUGIN_ID = 'aiops';

/**
* PLUGIN_NAME is used as the display name for the aiops plugin
*/
export const PLUGIN_NAME = 'AIOps';

/**
* This is an internal hard coded feature flag so we can easily turn on/off the
* "Explain log rate spikes UI" during development until the first release.
*/
export const AIOPS_ENABLED = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

Will you set this to false before merging?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed, we'll leave it as true for now for easier internal testing and will switch to false right before feature freeze.

15 changes: 15 additions & 0 deletions x-pack/plugins/aiops/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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.
*/

module.exports = {
preset: '@kbn/test',
rootDir: '../../..',
roots: ['<rootDir>/x-pack/plugins/aiops'],
coverageDirectory: '<rootDir>/target/kibana-coverage/jest/x-pack/plugins/aiops',
coverageReporters: ['text', 'html'],
collectCoverageFrom: ['<rootDir>/x-pack/plugins/aiops/{common,public,server}/**/*.{js,ts,tsx}'],
};
16 changes: 16 additions & 0 deletions x-pack/plugins/aiops/kibana.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"id": "aiops",
"version": "1.0.0",
"kibanaVersion": "kibana",
"owner": {
"name": "Machine Learning UI",
"githubTeam": "ml-ui"
},
"description": "AIOps plugin maintained by ML team.",
"server": true,
"ui": true,
"requiredPlugins": [],
"optionalPlugins": [],
"requiredBundles": ["kibanaReact"],
"extraPublicDirs": ["common"]
}
15 changes: 15 additions & 0 deletions x-pack/plugins/aiops/public/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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.
*/

import { lazyLoadModules } from '../lazy_load_bundle';

import type { ExplainLogRateSpikesSpec } from '../components/explain_log_rate_spikes';

export async function getExplainLogRateSpikesComponent(): Promise<() => ExplainLogRateSpikesSpec> {
const modules = await lazyLoadModules();
return () => modules.ExplainLogRateSpikes;
}
167 changes: 167 additions & 0 deletions x-pack/plugins/aiops/public/components/app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* 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.
*/

import React, { useEffect, useState } from 'react';

import { Chart, Settings, Axis, BarSeries, Position, ScaleType } from '@elastic/charts';

import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { useKibana } from '@kbn/kibana-react-plugin/public';

import {
EuiBadge,
EuiButton,
EuiCheckbox,
EuiFlexGroup,
EuiFlexItem,
EuiPage,
EuiPageBody,
EuiPageContent,
EuiPageContentBody,
EuiPageContentHeader,
EuiProgress,
EuiSpacer,
EuiTitle,
EuiText,
} from '@elastic/eui';

import { getStatusMessage } from './get_status_message';
import { initialState, resetStream, streamReducer } from './stream_reducer';
import { useStreamFetchReducer } from './use_stream_fetch_reducer';

export const AiopsApp = () => {
const { notifications } = useKibana();

const [simulateErrors, setSimulateErrors] = useState(false);

const { dispatch, start, cancel, data, isCancelled, isRunning } = useStreamFetchReducer(
'/internal/aiops/example_stream',
streamReducer,
initialState,
{ simulateErrors }
);

const { errors, progress, entities } = data;

const onClickHandler = async () => {
if (isRunning) {
cancel();
} else {
dispatch(resetStream());
start();
}
};

useEffect(() => {
if (errors.length > 0) {
notifications.toasts.danger({ body: errors[errors.length - 1] });
}
}, [errors, notifications.toasts]);

const buttonLabel = isRunning
? i18n.translate('xpack.aiops.stopbuttonText', {
defaultMessage: 'Stop development',
})
: i18n.translate('xpack.aiops.startbuttonText', {
defaultMessage: 'Start development',
});

return (
<EuiPage restrictWidth="1000px">
<EuiPageBody>
<EuiPageContent>
<EuiPageContentHeader>
<EuiTitle>
<h2>
<FormattedMessage
id="xpack.aiops.congratulationsTitle"
defaultMessage="Single endpoint streaming demo"
/>
</h2>
</EuiTitle>
</EuiPageContentHeader>
<EuiPageContentBody>
<EuiText>
<EuiFlexGroup alignItems="center">
<EuiFlexItem grow={false}>
<EuiButton
type="primary"
size="s"
onClick={onClickHandler}
aria-label={buttonLabel}
>
{buttonLabel}
</EuiButton>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiText>
<EuiBadge>{progress}%</EuiBadge>
</EuiText>
</EuiFlexItem>
<EuiFlexItem>
<EuiProgress value={progress} max={100} size="xs" />
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer />
<div style={{ height: '300px' }}>
<Chart>
<Settings rotation={90} />
<Axis
id="entities"
position={Position.Bottom}
title={i18n.translate('xpack.aiops.barChart.commitsTitle', {
defaultMessage: 'Commits',
})}
showOverlappingTicks
/>
<Axis
id="left2"
title={i18n.translate('xpack.aiops.barChart.developersTitle', {
defaultMessage: 'Developers',
})}
position={Position.Left}
/>

<BarSeries
id="commits"
xScaleType={ScaleType.Linear}
yScaleType={ScaleType.Linear}
xAccessor="x"
yAccessors={['y']}
data={Object.entries(entities)
.map(([x, y]) => {
return {
x,
y,
};
})
.sort((a, b) => b.y - a.y)}
/>
</Chart>
</div>
<p>{getStatusMessage(isRunning, isCancelled, data.progress)}</p>
<EuiCheckbox
id="aiopSimulateErrorsCheckbox"
label={i18n.translate(
'xpack.aiops.explainLogRateSpikes.simulateErrorsCheckboxLabel',
{
defaultMessage:
'Simulate errors (gets applied to new streams only, not currently running ones).',
}
)}
checked={simulateErrors}
onChange={(e) => setSimulateErrors(!simulateErrors)}
compressed
/>
</EuiText>
</EuiPageContentBody>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
);
};
Loading