Skip to content

Commit

Permalink
replace alerts histograms with Lens
Browse files Browse the repository at this point in the history
  • Loading branch information
angorayc committed Dec 20, 2022
1 parent 7b39762 commit b68afd1
Show file tree
Hide file tree
Showing 17 changed files with 565 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ import { DEFAULT_STACK_BY_FIELD0_SIZE, getAlertsRiskQuery } from '../alerts_tree
import type { AlertsTreeMapAggregation } from '../alerts_treemap/types';
import { InputsModelId } from '../../store/inputs/constants';
import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features';
import { useRefetchByRestartingSession } from '../page/use_refetch_by_session';
import { LensEmbeddable } from '../visualization_actions/lens_embeddable';
import { getAlertsTreemapLensAttributes as getLensAttributes } from '../visualization_actions/lens_attributes/common/alerts/alerts_treemap';
import { SourcererScopeName } from '../../store/sourcerer/model';
import type { Status } from '../../../../common/detection_engine/schemas/common';

const DEFAULT_HEIGHT = DEFAULT_MIN_CHART_HEIGHT + 134; // px

Expand Down Expand Up @@ -56,6 +61,9 @@ export interface Props {
stackByField1ComboboxRef?: React.RefObject<EuiComboBox<string | number | string[] | undefined>>;
stackByWidth?: number;
title: React.ReactNode;
showBuildingBlockAlerts: boolean;
status: Status;
showOnlyThreatIndicatorAlerts: boolean;
}

const AlertsTreemapPanelComponent: React.FC<Props> = ({
Expand All @@ -81,6 +89,9 @@ const AlertsTreemapPanelComponent: React.FC<Props> = ({
stackByField1ComboboxRef,
stackByWidth,
title,
showBuildingBlockAlerts,
showOnlyThreatIndicatorAlerts,
status,
}: Props) => {
const { to, from, deleteQuery, setQuery } = useGlobalTime(false);

Expand Down Expand Up @@ -146,6 +157,22 @@ const AlertsTreemapPanelComponent: React.FC<Props> = ({
to,
]);

const isChartEmbeddablesEnabled = useIsExperimentalFeatureEnabled('chartEmbeddablesEnabled');
const timerange = useMemo(() => ({ from, to }), [from, to]);
const { searchSessionId, refetchByRestartingSession } = useRefetchByRestartingSession({
inputId: InputsModelId.global,
queryId: uniqueQueryId,
});
const alertsOptions = useMemo(
() => ({
showBuildingBlockAlerts,
showOnlyThreatIndicatorAlerts,
status,
breakdownField: stackByField1,
}),
[showBuildingBlockAlerts, showOnlyThreatIndicatorAlerts, status, stackByField1]
);

useInspectButton({
deleteQuery,
loading: isLoadingAlerts,
Expand Down Expand Up @@ -181,7 +208,9 @@ const AlertsTreemapPanelComponent: React.FC<Props> = ({
>
{isPanelExpanded && (
<FieldSelection
chartOptionsContextMenu={chartOptionsContextMenu}
chartOptionsContextMenu={
isChartEmbeddablesEnabled ? undefined : chartOptionsContextMenu
}
setStackByField0={setStackByField0}
setStackByField0ComboboxInputRef={setStackByField0ComboboxInputRef}
setStackByField1={setStackByField1}
Expand All @@ -196,21 +225,35 @@ const AlertsTreemapPanelComponent: React.FC<Props> = ({
)}
</HeaderSection>

{isLoadingAlerts && isPanelExpanded ? (
<EuiProgress color="accent" data-test-subj="progress" position="absolute" size="xs" />
) : (
<>
{alertsData != null && isPanelExpanded && (
<AlertsTreemap
addFilter={addFilter}
data={alertsData}
maxBuckets={DEFAULT_STACK_BY_FIELD0_SIZE}
stackByField0={stackByField0}
stackByField1={stackByField1}
/>
)}
</>
)}
{isPanelExpanded ? (
isChartEmbeddablesEnabled && getLensAttributes && timerange ? (
<LensEmbeddable
data-test-subj="embeddable-matrix-histogram"
getLensAttributes={getLensAttributes}
height={`${DEFAULT_MIN_CHART_HEIGHT}px`}
id={uniqueQueryId}
inspectTitle={inspectTitle}
stackByField={stackByField0}
timerange={timerange}
scopeId={SourcererScopeName.detections}
alertsOptions={alertsOptions}
/>
) : isLoadingAlerts ? (
<EuiProgress color="accent" data-test-subj="progress" position="absolute" size="xs" />
) : (
<>
{alertsData != null && isPanelExpanded && (
<AlertsTreemap
addFilter={addFilter}
data={alertsData}
maxBuckets={DEFAULT_STACK_BY_FIELD0_SIZE}
stackByField0={stackByField0}
stackByField1={stackByField1}
/>
)}
</>
)
) : null}
</KpiPanel>
</InspectButtonContainer>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ import { InputsModelId } from '../../store/inputs/constants';
import { HoverVisibilityContainer } from '../hover_visibility_container';
import { HISTOGRAM_ACTIONS_BUTTON_CLASS, VisualizationActions } from '../visualization_actions';
import type { GetLensAttributes, LensAttributes } from '../visualization_actions/types';
import { SecurityPageName } from '../../../../common/constants';
import { useRouteSpy } from '../../utils/route/use_route_spy';
import { useQueryToggle } from '../../containers/query_toggle';
import { LensEmbeddable } from '../visualization_actions/lens_embeddable';
import { useIsExperimentalFeatureEnabled } from '../../hooks/use_experimental_features';
Expand Down Expand Up @@ -74,7 +72,6 @@ const HistogramPanel = styled(Panel)<{ height?: number }>`

const ChartHeight = '150px';

// eslint-disable-next-line complexity
export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> = ({
chartHeight,
defaultStackByOption,
Expand Down Expand Up @@ -191,12 +188,6 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
};
const [loading, { data, inspect, totalCount, refetch }] =
useMatrixHistogramCombined(matrixHistogramRequest);
const [{ pageName }] = useRouteSpy();

const onHostOrNetworkOrUserPage =
pageName === SecurityPageName.hosts ||
pageName === SecurityPageName.network ||
pageName === SecurityPageName.users;

const titleWithStackByField = useMemo(
() => (title != null && typeof title === 'function' ? title(selectedStackByOption) : title),
Expand Down Expand Up @@ -282,11 +273,11 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
toggleQuery={toggleQuery}
subtitle={subtitleWithCounts}
inspectMultiple
showInspectButton={showInspectButton || !onHostOrNetworkOrUserPage}
showInspectButton={showInspectButton && !isChartEmbeddablesEnabled}
isInspectDisabled={filterQuery === undefined}
>
<EuiFlexGroup alignItems="center" gutterSize="none">
{onHostOrNetworkOrUserPage && (getLensAttributes || lensAttributes) && timerange && (
{(getLensAttributes || lensAttributes) && timerange && (
<EuiFlexItem grow={false}>
<VisualizationActions
className="histogram-viz-actions"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@
* 2.0.
*/

import type { GetLensAttributes, LensAttributes } from '../../types';
import type { GetLensAttributes, LensAttributes } from '../../../types';
import { buildAlertsOptionsFilters } from './utils';

export const getAlertsHistogramLensAttributes: GetLensAttributes = (
stackByField = 'kibana.alert.rule.name'
stackByField = 'kibana.alert.rule.name',
alertsOptions = {
showOnlyThreatIndicatorAlerts: false,
showBuildingBlockAlerts: false,
}
) =>
({
title: 'Alerts',
Expand Down Expand Up @@ -53,26 +58,7 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = (
query: '',
language: 'kuery',
},
filters: [
{
meta: {
index: '.alerts-security.alerts-id',
alias: null,
negate: true,
disabled: false,
type: 'exists',
key: 'kibana.alert.building_block_type',
},
query: {
exists: {
field: 'kibana.alert.building_block_type',
},
},
$state: {
store: 'appState',
},
},
],
filters: buildAlertsOptionsFilters(alertsOptions),
datasourceStates: {
formBased: {
layers: {
Expand Down Expand Up @@ -102,10 +88,10 @@ export const getAlertsHistogramLensAttributes: GetLensAttributes = (
dataType: 'string',
operationType: 'terms',
scale: 'ordinal',
sourceField: `${stackByField}`,
sourceField: stackByField,
isBucketed: true,
params: {
size: 10,
size: 1000,
orderBy: {
type: 'column',
columnId: 'e09e0380-0740-4105-becc-0a4ca12e3944',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* 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 { GetLensAttributes } from '../../../types';
import { buildAlertsOptionsFilters } from './utils';

export const getAlertsTableLensAttributes: GetLensAttributes = (
stackByField = 'kibana.alert.rule.name',
alertsOptions = {
showOnlyThreatIndicatorAlerts: false,
showBuildingBlockAlerts: false,
}
) => ({
title: 'Alerts',
description: '',
visualizationType: 'lnsDatatable',
state: {
visualization: {
columns: [
{
columnId: '2881fedd-54b7-42ba-8c97-5175dec86166',
isTransposed: false,
width: 362,
},
{
columnId: 'f04a71a3-399f-4d32-9efc-8a005e989991',
isTransposed: false,
},
{
columnId: '75ce269b-ee9c-4c7d-a14e-9226ba0fe059',
isTransposed: false,
},
],
layerId: '4aa7cf71-cf20-4e62-8ca6-ca6be6b0988b',
layerType: 'data',
paging: {
size: 10,
enabled: true,
},
},
query: {
query: '',
language: 'kuery',
},
filters: buildAlertsOptionsFilters(alertsOptions),
datasourceStates: {
formBased: {
layers: {
'4aa7cf71-cf20-4e62-8ca6-ca6be6b0988b': {
columns: {
'2881fedd-54b7-42ba-8c97-5175dec86166': {
label: `Top values of ${stackByField}`,
dataType: 'string',
operationType: 'terms',
scale: 'ordinal',
sourceField: stackByField,
isBucketed: true,
params: {
size: 1000,
orderBy: {
type: 'column',
columnId: 'f04a71a3-399f-4d32-9efc-8a005e989991',
},
orderDirection: 'desc',
otherBucket: true,
missingBucket: false,
parentFormat: {
id: 'terms',
},
include: [],
exclude: [],
includeIsRegex: false,
excludeIsRegex: false,
},
},
'f04a71a3-399f-4d32-9efc-8a005e989991': {
label: `Count of ${alertsOptions.breakdownField}`,
dataType: 'number',
operationType: 'count',
isBucketed: false,
scale: 'ratio',
sourceField: alertsOptions.breakdownField,
params: {
emptyAsNull: true,
},
},
'75ce269b-ee9c-4c7d-a14e-9226ba0fe059': {
label: `Top values of ${alertsOptions.breakdownField}`,
dataType: 'string',
operationType: 'terms',
scale: 'ordinal',
sourceField: alertsOptions.breakdownField,
isBucketed: true,
params: {
size: 1000,
orderBy: {
type: 'column',
columnId: 'f04a71a3-399f-4d32-9efc-8a005e989991',
},
orderDirection: 'desc',
otherBucket: true,
missingBucket: false,
parentFormat: {
id: 'terms',
},
include: [],
exclude: [],
includeIsRegex: false,
excludeIsRegex: false,
},
},
},
columnOrder: [
'2881fedd-54b7-42ba-8c97-5175dec86166',
'75ce269b-ee9c-4c7d-a14e-9226ba0fe059',
'f04a71a3-399f-4d32-9efc-8a005e989991',
],
sampling: 1,
incompleteColumns: {},
},
},
},
textBased: {
layers: {},
},
},
internalReferences: [],
adHocDataViews: {},
},
references: [
{
type: 'index-pattern',
id: '{dataViewId}',
name: 'indexpattern-datasource-layer-4aa7cf71-cf20-4e62-8ca6-ca6be6b0988b',
},
],
});
Loading

0 comments on commit b68afd1

Please sign in to comment.