Skip to content

Commit

Permalink
Merge branch 'main' into 145409-alert-summary-to-alert-details-app-se…
Browse files Browse the repository at this point in the history
…ction-apm
  • Loading branch information
fkanout authored Dec 15, 2022
2 parents cf47806 + 91d26d2 commit e50602f
Show file tree
Hide file tree
Showing 120 changed files with 6,313 additions and 1,365 deletions.
Binary file modified docs/user/alerting/images/rule-types-es-query-conditions.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 11 additions & 12 deletions docs/user/alerting/rule-types/es-query.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,34 @@ threshold condition is met.
=== Create the rule

Fill in the <<defining-rules-general-details, rule details>>, then select
*{es} query*.

*{es} query*. {es} query rule can be defined using KQL/Lucene or Query DSL.

[float]
=== Define the conditions

Define properties to detect the condition.

[role="screenshot"]
image::user/alerting/images/rule-types-es-query-conditions.png[Six clauses define the condition to detect]
image::user/alerting/images/rule-types-es-query-conditions.png[Eight clauses define the condition to detect]

Index:: Specifies an *index or data view* and a *time field* that is used for
the *time window*.
Size:: Specifies the number of documents to pass to the configured actions when
the threshold condition is met.
{es} query:: Specifies the ES DSL query. The number of documents that
match this query is evaluated against the threshold condition. Only the `query`, `fields`, `_source` and `runtime_mappings`
fields are used, other DSL fields are not considered.
{es} query:: Specifies the ES DSL query. Only the `query`, `fields`, `_source` and `runtime_mappings` fields are used, other DSL fields are not considered.
When:: Specifies how the value to be compared to the threshold is calculated. The value is calculated by aggregating a numeric field within the *time window*. The aggregation options are: `count`, `average`, `sum`, `min`, and `max`. When using `count` the document count is used and an aggregation field is not necessary.
Over or Grouped Over:: Specifies whether the aggregation is applied over all documents or split into groups using a grouping field. If grouping is used, an <<alerting-concepts-alerts,alert>> will be created for each group when it meets the condition. To limit the number of alerts on high cardinality fields, you must specify the number of groups to check against the threshold. Only the *top* groups are checked.
Threshold:: Defines a threshold value and a comparison operator (`is above`,
`is above or equals`, `is below`, `is below or equals`, or `is between`). The
number of documents that match the specified query is compared to this
threshold.
`is above or equals`, `is below`, `is below or equals`, or `is between`). The value
calculated by the aggregation is compared to this threshold.
Time window:: Defines how far back to search for documents, using the
*time field* set in the *index* clause. Generally this value should be set to a
value higher than the *check every* value in the
<<defining-rules-general-details, general rule details>>, to avoid gaps in
detection.
Size:: Specifies the number of documents to pass to the configured actions when
the threshold condition is met.
Exclude matches from previous run:: Turn on to avoid alert duplication by
excluding documents that have already been detected by the previous rule run.
excluding documents that have already been detected by the previous rule run. This
option is not available when a grouping field is specified.

[float]
=== Add action variables
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* Side Public License, v 1.
*/

import React from 'react';
import React, { useState, useCallback } from 'react';
import { css } from '@emotion/react';
import { EuiButton, EuiProgress, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -50,7 +50,7 @@ export interface GuideCardFooterProps {
guides: GuideState[];
useCase: GuideCardUseCase;
telemetryId: string;
activateGuide: (useCase: GuideCardUseCase, guideState?: GuideState) => void;
activateGuide: (useCase: GuideCardUseCase, guideState?: GuideState) => Promise<void>;
}
export const GuideCardFooter = ({
guides,
Expand All @@ -59,14 +59,21 @@ export const GuideCardFooter = ({
activateGuide,
}: GuideCardFooterProps) => {
const guideState = guides.find((guide) => guide.guideId === (useCase as GuideId));
const [isLoading, setIsLoading] = useState<boolean>(false);
const activateGuideCallback = useCallback(async () => {
setIsLoading(true);
await activateGuide(useCase, guideState);
setIsLoading(false);
}, [activateGuide, guideState, useCase]);
const viewGuideButton = (
<EuiFlexGroup justifyContent="center">
<EuiFlexItem grow={false}>
<EuiButton
isLoading={isLoading}
// Used for FS tracking
data-test-subj={`onboarding--guideCard--view--${telemetryId}`}
fill
onClick={() => activateGuide(useCase, guideState)}
onClick={activateGuideCallback}
>
{viewGuideLabel}
</EuiButton>
Expand Down Expand Up @@ -122,10 +129,11 @@ export const GuideCardFooter = ({
<EuiFlexGroup justifyContent="center">
<EuiFlexItem grow={false}>
<EuiButton
isLoading={isLoading}
// Used for FS tracking
data-test-subj={`onboarding--guideCard--continue--${telemetryId}`}
fill
onClick={() => activateGuide(useCase, guideState)}
onClick={activateGuideCallback}
>
{continueGuideLabel}
</EuiButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ describe('checking migration metadata changes on all registered SO types', () =>
Object {
"action": "7858e6d5a9f231bf23f6f2e57328eb0095b26735",
"action_task_params": "bbd38cbfd74bf6713586fe078e3fa92db2234299",
"alert": "d95e8ef645ae9f797b93a9a64d8ab9d35d484064",
"alert": "c29c5e28a6f1d075e528a9273a1a07b080625565",
"api_key_pending_invalidation": "9b4bc1235337da9a87ef05a1d1f4858b2a3b77c6",
"apm-indices": "ceb0870f3a74e2ffc3a1cd3a3c73af76baca0999",
"apm-server-schema": "2bfd2998d3873872e1366458ce553def85418f91",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
* Side Public License, v 1.
*/

import { EuiTabs, EuiTab, useEuiPaddingSize, EuiBetaBadge } from '@elastic/eui';
import { EuiTabs, EuiTab, useEuiPaddingSize } from '@elastic/eui';
import React from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { css } from '@emotion/react';
import { euiThemeVars } from '@kbn/ui-theme';
import { i18n } from '@kbn/i18n';
import { VIEW_MODE } from './constants';
import { SHOW_FIELD_STATISTICS } from '../../../common';
import { useDiscoverServices } from '../../hooks/use_discover_services';
Expand All @@ -30,10 +29,6 @@ export const DocumentViewModeToggle = ({
background-color: ${euiThemeVars.euiPageBackgroundColor};
`;

const betaBadgeCss = css`
vertical-align: middle;
`;

const showViewModeToggle = uiSettings.get(SHOW_FIELD_STATISTICS) ?? false;

if (!showViewModeToggle) {
Expand All @@ -55,16 +50,6 @@ export const DocumentViewModeToggle = ({
onClick={() => setDiscoverViewMode(VIEW_MODE.AGGREGATED_LEVEL)}
className="dscViewModeToggle__tab"
data-test-subj="dscViewModeFieldStatsButton"
append={
<EuiBetaBadge
label={i18n.translate('discover.viewModes.fieldStatistics.betaTitle', {
defaultMessage: 'Beta',
})}
size="s"
className="fieldStatsBetaBadge"
css={betaBadgeCss}
/>
}
>
<FormattedMessage
id="discover.viewModes.fieldStatistics.label"
Expand Down
9 changes: 8 additions & 1 deletion src/plugins/guided_onboarding/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,11 @@

export { PLUGIN_ID, PLUGIN_NAME, API_BASE_PATH } from './constants';
export { testGuideConfig, testGuideId } from './test_guide_config';
export type { PluginStatus, PluginState, StepConfig, GuideConfig, GuidesConfig } from './types';
export type {
PluginStatus,
PluginState,
StepConfig,
GuideConfig,
GuidesConfig,
StepDescriptionWithLink,
} from './types';
8 changes: 7 additions & 1 deletion src/plugins/guided_onboarding/common/test_guide_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,13 @@ export const testGuideConfig: GuideConfig = {
title: 'Step 2 (manual completion after navigation)',
descriptionList: [
'This step is set to ready_to_complete on page navigation.',
'After that click the popover on the guide button in the header and mark the step done',
{
descriptionText:
'After that click the popover on the guide button in the header and mark the step done.',
linkText: 'Example link',
linkUrl: 'https://www.elastic.co',
isLinkExternal: true,
},
],
location: {
appID: 'guidedOnboardingExample',
Expand Down
21 changes: 19 additions & 2 deletions src/plugins/guided_onboarding/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,30 @@ export interface PluginState {
activeGuide?: GuideState;
}

/* To append a link to the description, specify its text and url in the properties.
* An example:
* {
* description: 'This is a description with a link'.
* linkText: 'My link',
* linkUrl: 'example.com',
* isLinkExternal: true,
* }
*
*/
export interface StepDescriptionWithLink {
descriptionText: string;
linkText: string;
linkUrl: string;
isLinkExternal?: boolean;
}

export interface StepConfig {
id: GuideStepIds;
title: string;
// description is displayed as a single paragraph, can be combined with description list
description?: string;
description?: string | StepDescriptionWithLink;
// description list is displayed as an unordered list, can be combined with description
descriptionList?: Array<string | React.ReactNode>;
descriptionList?: Array<string | StepDescriptionWithLink>;
location?: {
appID: string;
path: string;
Expand Down
71 changes: 37 additions & 34 deletions src/plugins/guided_onboarding/public/components/guide_button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@ interface GuideButtonProps {
toggleGuidePanel: () => void;
isGuidePanelOpen: boolean;
navigateToLandingPage: () => void;
isLoading: boolean;
}

const getStepNumber = (state: GuideState): number | undefined => {
const getStepNumber = (state?: GuideState): number | undefined => {
let stepNumber: number | undefined;

state.steps.forEach((step, stepIndex) => {
state?.steps.forEach((step, stepIndex) => {
// If the step is in_progress or ready_to_complete, show that step number
if (step.status === 'in_progress' || step.status === 'ready_to_complete') {
stepNumber = stepIndex + 1;
Expand All @@ -46,43 +47,15 @@ export const GuideButton = ({
toggleGuidePanel,
isGuidePanelOpen,
navigateToLandingPage,
isLoading,
}: GuideButtonProps) => {
// TODO handle loading state
// https://github.com/elastic/kibana/issues/139799

// if there is no active guide
if (!pluginState || !pluginState.activeGuide || !pluginState.activeGuide.isActive) {
// if still active period and the user has not started a guide or skipped the guide,
// display the button that redirects to the landing page
if (
!(
pluginState?.isActivePeriod &&
(pluginState?.status === 'not_started' || pluginState?.status === 'skipped')
)
) {
return null;
} else {
return (
<EuiButton
onClick={navigateToLandingPage}
color="success"
fill
size="s"
data-test-subj="guideButtonRedirect"
>
{i18n.translate('guidedOnboarding.guidedSetupRedirectButtonLabel', {
defaultMessage: 'Setup guides',
})}
</EuiButton>
);
}
}
const stepNumber = getStepNumber(pluginState.activeGuide);
const stepReadyToComplete = pluginState.activeGuide.steps.find(
const stepNumber = getStepNumber(pluginState?.activeGuide);
const stepReadyToComplete = pluginState?.activeGuide?.steps.find(
(step) => step.status === 'ready_to_complete'
);
const button = (
<EuiButton
isLoading={isLoading}
onClick={toggleGuidePanel}
color="success"
fill
Expand All @@ -101,6 +74,36 @@ export const GuideButton = ({
})}
</EuiButton>
);
// if there is no active guide
if (!pluginState || !pluginState.activeGuide || !pluginState.activeGuide.isActive) {
// if still active period and the user has not started a guide or skipped the guide,
// display the button that redirects to the landing page
if (
pluginState?.isActivePeriod &&
(pluginState?.status === 'not_started' || pluginState?.status === 'skipped')
) {
return (
<EuiButton
onClick={navigateToLandingPage}
color="success"
fill
size="s"
data-test-subj="guideButtonRedirect"
>
{i18n.translate('guidedOnboarding.guidedSetupRedirectButtonLabel', {
defaultMessage: 'Setup guides',
})}
</EuiButton>
);
}
// if error state, display the header button (error section is in the dropdown panel)
if (pluginState?.status === 'error') {
return button;
}
// otherwise hide the button (the guide is completed, quit, skipped or not started)
return null;
}

if (stepReadyToComplete) {
const stepConfig = guideConfig?.steps.find((step) => step.id === stepReadyToComplete.id);
// check if the stepConfig has manualCompletion info
Expand Down
Loading

0 comments on commit e50602f

Please sign in to comment.