mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[SecuritySolution] Fix topN histograms for custom fields (#123489)
* custom fields topN histograms fixed * add runtime_mappings to response inspect mock Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
5aa26ed37d
commit
e0a7a1bb9e
11 changed files with 64 additions and 1 deletions
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import type { IEsSearchResponse } from '../../../../../../../src/plugins/data/common';
|
||||
import { AuthenticationHit } from '../hosts';
|
||||
import { Inspect, Maybe, TimerangeInput } from '../../common';
|
||||
|
@ -64,6 +65,7 @@ export interface MatrixHistogramRequestOptions extends RequestBasicOptions {
|
|||
inspect?: Maybe<Inspect>;
|
||||
isPtrIncluded?: boolean;
|
||||
includeMissingData?: boolean;
|
||||
runtimeMappings?: MappingRuntimeFields;
|
||||
}
|
||||
|
||||
export interface MatrixHistogramStrategyResponse extends IEsSearchResponse {
|
||||
|
|
|
@ -12,6 +12,7 @@ import { MatrixHistogram } from '.';
|
|||
import { useMatrixHistogramCombined } from '../../containers/matrix_histogram';
|
||||
import { MatrixHistogramType } from '../../../../common/search_strategy/security_solution';
|
||||
import { TestProviders } from '../../mock';
|
||||
import { mockRuntimeMappings } from '../../containers/source/mock';
|
||||
|
||||
jest.mock('../../lib/kibana');
|
||||
|
||||
|
@ -58,6 +59,7 @@ describe('Matrix Histogram Component', () => {
|
|||
subtitle: 'mockSubtitle',
|
||||
totalCount: -1,
|
||||
title: 'mockTitle',
|
||||
runtimeMappings: mockRuntimeMappings,
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
|
@ -75,6 +77,19 @@ describe('Matrix Histogram Component', () => {
|
|||
});
|
||||
|
||||
describe('on initial load', () => {
|
||||
test('it requests Matrix Histogram', () => {
|
||||
expect(useMatrixHistogramCombined).toHaveBeenCalledWith({
|
||||
endDate: mockMatrixOverTimeHistogramProps.endDate,
|
||||
errorMessage: mockMatrixOverTimeHistogramProps.errorMessage,
|
||||
histogramType: mockMatrixOverTimeHistogramProps.histogramType,
|
||||
indexNames: mockMatrixOverTimeHistogramProps.indexNames,
|
||||
startDate: mockMatrixOverTimeHistogramProps.startDate,
|
||||
stackByField: mockMatrixOverTimeHistogramProps.defaultStackByOption.value,
|
||||
runtimeMappings: mockMatrixOverTimeHistogramProps.runtimeMappings,
|
||||
isPtrIncluded: mockMatrixOverTimeHistogramProps.isPtrIncluded,
|
||||
skip: mockMatrixOverTimeHistogramProps.skip,
|
||||
});
|
||||
});
|
||||
test('it renders MatrixLoader', () => {
|
||||
expect(wrapper.find('MatrixLoader').exists()).toBe(true);
|
||||
});
|
||||
|
|
|
@ -75,6 +75,7 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
|
|||
hideHistogramIfEmpty = false,
|
||||
id,
|
||||
indexNames,
|
||||
runtimeMappings,
|
||||
isPtrIncluded,
|
||||
legendPosition,
|
||||
mapping,
|
||||
|
@ -145,6 +146,7 @@ export const MatrixHistogramComponent: React.FC<MatrixHistogramComponentProps> =
|
|||
onError,
|
||||
startDate,
|
||||
stackByField: selectedStackByOption.value,
|
||||
runtimeMappings,
|
||||
isPtrIncluded,
|
||||
docValueFields,
|
||||
skip,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import type React from 'react';
|
||||
import { EuiTitleSize } from '@elastic/eui';
|
||||
import { ScaleType, Position, TickFormatter } from '@elastic/charts';
|
||||
import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import { ActionCreator } from 'redux';
|
||||
import { ESQuery } from '../../../../common/typed_json';
|
||||
import { InputsModelId } from '../../store/inputs/constants';
|
||||
|
@ -81,6 +82,7 @@ export interface MatrixHistogramQueryProps {
|
|||
skip?: boolean;
|
||||
isPtrIncluded?: boolean;
|
||||
includeMissingData?: boolean;
|
||||
runtimeMappings?: MappingRuntimeFields;
|
||||
}
|
||||
|
||||
export interface MatrixHistogramProps extends MatrixHistogramBasicProps {
|
||||
|
|
|
@ -89,7 +89,9 @@ const TopNComponent: React.FC<Props> = ({
|
|||
(value: string) => setView(value as TimelineEventsType),
|
||||
[setView]
|
||||
);
|
||||
const { selectedPatterns } = useSourcererDataView(getSourcererScopeName({ timelineId, view }));
|
||||
const { selectedPatterns, runtimeMappings } = useSourcererDataView(
|
||||
getSourcererScopeName({ timelineId, view })
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setView(defaultView);
|
||||
|
@ -134,6 +136,7 @@ const TopNComponent: React.FC<Props> = ({
|
|||
headerChildren={headerChildren}
|
||||
indexPattern={indexPattern}
|
||||
indexNames={selectedPatterns}
|
||||
runtimeMappings={runtimeMappings}
|
||||
onlyField={field}
|
||||
paddingSize={paddingSize}
|
||||
query={query}
|
||||
|
@ -156,6 +159,7 @@ const TopNComponent: React.FC<Props> = ({
|
|||
showLegend={showLegend}
|
||||
setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget}
|
||||
timelineId={timelineId}
|
||||
runtimeMappings={runtimeMappings}
|
||||
/>
|
||||
)}
|
||||
</TopNContent>
|
||||
|
|
|
@ -56,6 +56,7 @@ export const useMatrixHistogram = ({
|
|||
isPtrIncluded,
|
||||
onError,
|
||||
stackByField,
|
||||
runtimeMappings,
|
||||
startDate,
|
||||
threshold,
|
||||
skip = false,
|
||||
|
@ -97,6 +98,7 @@ export const useMatrixHistogram = ({
|
|||
histogramType: initialHistogramType ?? histogramType,
|
||||
timerange: initialTimerange,
|
||||
stackByField,
|
||||
runtimeMappings,
|
||||
threshold,
|
||||
...(isPtrIncluded != null ? { isPtrIncluded } : {}),
|
||||
...(!isEmpty(docValueFields) ? { docValueFields } : {}),
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import { Position } from '@elastic/charts';
|
||||
import numeral from '@elastic/numeral';
|
||||
import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
import React, { useEffect, useMemo, useCallback } from 'react';
|
||||
import uuid from 'uuid';
|
||||
|
||||
|
@ -44,6 +45,7 @@ interface Props extends Pick<GlobalTimeArgs, 'from' | 'to' | 'deleteQuery' | 'se
|
|||
headerChildren?: React.ReactNode;
|
||||
indexPattern: DataViewBase;
|
||||
indexNames: string[];
|
||||
runtimeMappings?: MappingRuntimeFields;
|
||||
onlyField?: string;
|
||||
paddingSize?: 's' | 'm' | 'l' | 'none';
|
||||
query: Query;
|
||||
|
@ -67,6 +69,7 @@ const EventsByDatasetComponent: React.FC<Props> = ({
|
|||
headerChildren,
|
||||
indexPattern,
|
||||
indexNames,
|
||||
runtimeMappings,
|
||||
onlyField,
|
||||
paddingSize,
|
||||
query,
|
||||
|
@ -176,6 +179,7 @@ const EventsByDatasetComponent: React.FC<Props> = ({
|
|||
headerChildren={headerContent}
|
||||
id={uniqueQueryId}
|
||||
indexNames={indexNames}
|
||||
runtimeMappings={runtimeMappings}
|
||||
onError={toggleTopN}
|
||||
paddingSize={paddingSize}
|
||||
setAbsoluteRangeDatePickerTarget={setAbsoluteRangeDatePickerTarget}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
import React, { useCallback } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { Filter, Query } from '@kbn/es-query';
|
||||
import { MappingRuntimeFields } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import { AlertsHistogramPanel } from '../../../detections/components/alerts_kpis/alerts_histogram_panel';
|
||||
import { useSignalIndex } from '../../../detections/containers/detection_engine/alerts/use_signal_index';
|
||||
|
@ -33,6 +34,7 @@ interface Props {
|
|||
setAbsoluteRangeDatePickerTarget?: InputsModelId;
|
||||
showLegend?: boolean;
|
||||
timelineId?: string;
|
||||
runtimeMappings?: MappingRuntimeFields;
|
||||
}
|
||||
|
||||
const SignalsByCategoryComponent: React.FC<Props> = ({
|
||||
|
@ -45,6 +47,7 @@ const SignalsByCategoryComponent: React.FC<Props> = ({
|
|||
showLegend,
|
||||
setAbsoluteRangeDatePickerTarget = 'global',
|
||||
timelineId,
|
||||
runtimeMappings,
|
||||
}) => {
|
||||
const dispatch = useDispatch();
|
||||
const { signalIndexName } = useSignalIndex();
|
||||
|
@ -81,6 +84,7 @@ const SignalsByCategoryComponent: React.FC<Props> = ({
|
|||
showStackBy={onlyField == null}
|
||||
showTotalAlertsCount={true}
|
||||
signalIndexName={signalIndexName}
|
||||
runtimeMappings={runtimeMappings}
|
||||
timelineId={timelineId}
|
||||
title={i18n.ALERT_COUNT}
|
||||
titleSize={onlyField == null ? 'm' : 's'}
|
||||
|
|
|
@ -999,6 +999,14 @@ export const formattedEventsSearchStrategyResponse: MatrixHistogramStrategyRespo
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: {
|
||||
'@a.runtime.field': {
|
||||
script: {
|
||||
source: 'emit("Radically mocked dude: " + doc[\'host.name\'].value)',
|
||||
},
|
||||
type: 'keyword',
|
||||
},
|
||||
},
|
||||
size: 0,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -11,6 +11,15 @@ import {
|
|||
MatrixHistogramType,
|
||||
} from '../../../../../../../common/search_strategy';
|
||||
|
||||
const runtimeMappings: MatrixHistogramRequestOptions['runtimeMappings'] = {
|
||||
'@a.runtime.field': {
|
||||
script: {
|
||||
source: 'emit("Radically mocked dude: " + doc[\'host.name\'].value)',
|
||||
},
|
||||
type: 'keyword',
|
||||
},
|
||||
};
|
||||
|
||||
export const mockOptions: MatrixHistogramRequestOptions = {
|
||||
defaultIndex: [
|
||||
'apm-*-transaction*',
|
||||
|
@ -27,6 +36,7 @@ export const mockOptions: MatrixHistogramRequestOptions = {
|
|||
histogramType: MatrixHistogramType.events,
|
||||
timerange: { interval: '12h', from: '2020-09-08T16:11:26.215Z', to: '2020-09-09T16:11:26.215Z' },
|
||||
stackByField: 'event.action',
|
||||
runtimeMappings,
|
||||
};
|
||||
|
||||
export const expectedDsl = {
|
||||
|
@ -80,6 +90,7 @@ export const expectedDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
@ -137,6 +148,7 @@ export const expectedThresholdDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
@ -192,6 +204,7 @@ export const expectedThresholdMissingFieldDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
@ -242,6 +255,7 @@ export const expectedThresholdWithCardinalityDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
ignore_unavailable: true,
|
||||
|
@ -311,6 +325,7 @@ export const expectedThresholdWithGroupFieldsAndCardinalityDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
@ -363,6 +378,7 @@ export const expectedThresholdGroupWithCardinalityDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
ignore_unavailable: true,
|
||||
|
@ -438,6 +454,7 @@ export const expectedIpIncludingMissingDataDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
@ -496,6 +513,7 @@ export const expectedIpNotIncludingMissingDataDsl = {
|
|||
],
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@ export const buildEventsHistogramQuery = ({
|
|||
stackByField = 'event.action',
|
||||
threshold,
|
||||
includeMissingData = true,
|
||||
runtimeMappings,
|
||||
}: MatrixHistogramRequestOptions) => {
|
||||
const [queryFilterFirstClause, ...queryFilterClauses] = createQueryFilterClauses(filterQuery);
|
||||
const stackByIpField =
|
||||
|
@ -162,6 +163,7 @@ export const buildEventsHistogramQuery = ({
|
|||
filter,
|
||||
},
|
||||
},
|
||||
runtime_mappings: runtimeMappings,
|
||||
size: 0,
|
||||
},
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue