From b10f0834638591ca92552a35a988b6266250403a Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Fri, 26 Jan 2024 17:07:42 +0000 Subject: [PATCH] [ML] [AIOps] Adding expanded rows to pattern analysis table (#175320) Changes the syntax highlighting of the example text so that it is now based on the pattern's tokens, rather than being the default "log" format supplied by `EuiCode` Adds an expanded row to the able which lists the tokens, the regex and 4 examples so we can see how the non-token parts of each example vary. Highlighting colors have been copied from the `EuiCode` component. image --- .../create_category_request.ts | 2 +- .../process_category_results.ts | 1 + .../common/api/log_categorization/types.ts | 2 + .../build_extended_base_filter_criteria.ts | 3 + .../category_table/category_table.tsx | 60 ++++-- .../category_table/expanded_row.tsx | 69 +++++++ .../format_category.test.tsx | 97 ++++++++++ .../log_categorization/format_category.tsx | 180 ++++++++++++++++++ .../log_rate_analysis_results_table.tsx | 1 + .../aiops/public/hooks/use_eui_theme.ts | 7 +- .../analysis_handlers/histogram_handler.ts | 2 +- .../queries/fetch_categories.test.ts | 2 +- .../queries/fetch_categories.ts | 1 + .../queries/fetch_category_counts.test.ts | 4 +- .../fetch_terms_2_categories_counts.ts | 4 +- .../queries/get_group_filter.ts | 1 + .../aiops/log_pattern_analysis_page.ts | 2 +- 17 files changed, 417 insertions(+), 21 deletions(-) create mode 100644 x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx create mode 100644 x-pack/plugins/aiops/public/components/log_categorization/format_category.test.tsx create mode 100644 x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx diff --git a/x-pack/plugins/aiops/common/api/log_categorization/create_category_request.ts b/x-pack/plugins/aiops/common/api/log_categorization/create_category_request.ts index 15b99f9d92cb4..1c5a4745064b5 100644 --- a/x-pack/plugins/aiops/common/api/log_categorization/create_category_request.ts +++ b/x-pack/plugins/aiops/common/api/log_categorization/create_category_request.ts @@ -15,7 +15,7 @@ import { createRandomSamplerWrapper } from '@kbn/ml-random-sampler-utils'; import { createCategorizeQuery } from './create_categorize_query'; const CATEGORY_LIMIT = 1000; -const EXAMPLE_LIMIT = 1; +const EXAMPLE_LIMIT = 4; export interface CategorizationAdditionalFilter { from: number; diff --git a/x-pack/plugins/aiops/common/api/log_categorization/process_category_results.ts b/x-pack/plugins/aiops/common/api/log_categorization/process_category_results.ts index a60c18d2a6651..e8a9cd6f37cdd 100644 --- a/x-pack/plugins/aiops/common/api/log_categorization/process_category_results.ts +++ b/x-pack/plugins/aiops/common/api/log_categorization/process_category_results.ts @@ -47,6 +47,7 @@ export function processCategoryResults( subFieldExamples: b.sub_time_range?.buckets[0].examples.hits.hits.map((h) => get(h._source, field)) ?? undefined, + regex: b.regex, }; }); return { diff --git a/x-pack/plugins/aiops/common/api/log_categorization/types.ts b/x-pack/plugins/aiops/common/api/log_categorization/types.ts index 25d9b4aad0f6d..445c976ef13c1 100644 --- a/x-pack/plugins/aiops/common/api/log_categorization/types.ts +++ b/x-pack/plugins/aiops/common/api/log_categorization/types.ts @@ -15,6 +15,7 @@ export interface Category { subFieldExamples?: string[]; examples: string[]; sparkline?: Record; + regex: string; } interface CategoryExamples { @@ -27,6 +28,7 @@ export interface CategoriesAgg { key: string; doc_count: number; examples: CategoryExamples; + regex: string; sparkline: { buckets: Array<{ key_as_string: string; key: number; doc_count: number }>; }; diff --git a/x-pack/plugins/aiops/public/application/utils/build_extended_base_filter_criteria.ts b/x-pack/plugins/aiops/public/application/utils/build_extended_base_filter_criteria.ts index d01951b6b8655..ea3ee8b528d38 100644 --- a/x-pack/plugins/aiops/public/application/utils/build_extended_base_filter_criteria.ts +++ b/x-pack/plugins/aiops/public/application/utils/build_extended_base_filter_criteria.ts @@ -50,6 +50,7 @@ export function buildExtendedBaseFilterCriteria( key, count: docCount, examples: [], + regex: '', }, ]) ); @@ -70,6 +71,7 @@ export function buildExtendedBaseFilterCriteria( key: `${selectedSignificantItem.key}`, count: selectedSignificantItem.doc_count, examples: [], + regex: '', }, ]) ); @@ -97,6 +99,7 @@ export function buildExtendedBaseFilterCriteria( key: `${selectedSignificantItem.key}`, count: selectedSignificantItem.doc_count, examples: [], + regex: '', }, ]), ], diff --git a/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx b/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx index 048ed1d1f91c2..690dd1d56cdc4 100644 --- a/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx +++ b/x-pack/plugins/aiops/public/components/log_categorization/category_table/category_table.tsx @@ -5,17 +5,16 @@ * 2.0. */ -import React, { FC, useMemo, useState } from 'react'; +import React, { FC, useCallback, useMemo, useState } from 'react'; import { useEuiBackgroundColor, EuiInMemoryTable, EuiBasicTableColumn, - EuiCode, - EuiText, EuiTableSelectionType, EuiHorizontalRule, EuiSpacer, + EuiButtonIcon, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -42,6 +41,8 @@ import type { EventRate } from '../use_categorize_request'; import { getLabels } from './labels'; import { TableHeader } from './table_header'; +import { ExpandedRow } from './expanded_row'; +import { FormattedPatternExamples } from '../format_category'; interface Props { categories: Category[]; @@ -83,6 +84,9 @@ export const CategoryTable: FC = ({ const { openInDiscoverWithFilter } = useDiscoverLinks(); const [selectedCategories, setSelectedCategories] = useState([]); const { onTableChange, pagination, sorting } = useTableState(categories ?? [], 'key'); + const [itemIdToExpandedRowMap, setItemIdToExpandedRowMap] = useState>( + {} + ); const labels = useMemo(() => { const isFlyout = onAddFilter !== undefined && onClose !== undefined; @@ -132,7 +136,42 @@ export const CategoryTable: FC = ({ ); }; + const toggleDetails = useCallback( + (category: Category) => { + const itemIdToExpandedRowMapValues = { ...itemIdToExpandedRowMap }; + if (itemIdToExpandedRowMapValues[category.key]) { + delete itemIdToExpandedRowMapValues[category.key]; + } else { + itemIdToExpandedRowMapValues[category.key] = ; + } + setItemIdToExpandedRowMap(itemIdToExpandedRowMapValues); + }, + [itemIdToExpandedRowMap] + ); + const columns: Array> = [ + { + align: 'left', + width: '40px', + isExpander: true, + render: (item: Category) => ( + toggleDetails(item)} + aria-label={ + itemIdToExpandedRowMap[item.key] + ? i18n.translate('xpack.aiops.logCategorization.column.collapseRow', { + defaultMessage: 'Collapse', + }) + : i18n.translate('xpack.aiops.logCategorization.column.expandRow', { + defaultMessage: 'Expand', + }) + } + iconType={itemIdToExpandedRowMap[item.key] ? 'arrowDown' : 'arrowRight'} + /> + ), + 'data-test-subj': 'aiopsLogPatternsExpandRowToggle', + }, { field: 'count', name: i18n.translate('xpack.aiops.logCategorization.column.count', { @@ -142,20 +181,13 @@ export const CategoryTable: FC = ({ width: '80px', }, { - field: 'examples', name: i18n.translate('xpack.aiops.logCategorization.column.examples', { defaultMessage: 'Examples', }), sortable: true, - render: (examples: string[]) => ( + render: (item: Category) => ( <> - {examples.map((e) => ( - - - {e} - - - ))} + ), }, @@ -187,7 +219,7 @@ export const CategoryTable: FC = ({ ] as Array>; if (showSparkline === true) { - columns.splice(1, 0, { + columns.splice(2, 0, { field: 'sparkline', name: i18n.translate('xpack.aiops.logCategorization.column.logRate', { defaultMessage: 'Log rate', @@ -271,6 +303,8 @@ export const CategoryTable: FC = ({ pagination={pagination} sorting={sorting} data-test-subj="aiopsLogPatternsTable" + isExpandable={true} + itemIdToExpandedRowMap={itemIdToExpandedRowMap} rowProps={(category) => { return enableRowActions ? { diff --git a/x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx b/x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx new file mode 100644 index 0000000000000..dfc1a3b7e9943 --- /dev/null +++ b/x-pack/plugins/aiops/public/components/log_categorization/category_table/expanded_row.tsx @@ -0,0 +1,69 @@ +/* + * 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, { FC } from 'react'; +import { EuiText, EuiSpacer, useEuiTheme } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { css } from '@emotion/react'; +import type { Category } from '../../../../common/api/log_categorization/types'; +import { FormattedPatternExamples, FormattedRegex, FormattedTokens } from '../format_category'; + +interface ExpandedRowProps { + category: Category; +} + +export const ExpandedRow: FC = ({ category }) => { + const { euiTheme } = useEuiTheme(); + const cssExpandedRow = css({ + marginRight: euiTheme.size.xxl, + width: '100%', + }); + + return ( +
+ + +
+ +
+ +
+ +
+ +
+ +
+
+ ); +}; + +const Section: FC<{ title: string }> = ({ title, children }) => { + return ( + <> + + {title} + + + {children} + + + ); +}; diff --git a/x-pack/plugins/aiops/public/components/log_categorization/format_category.test.tsx b/x-pack/plugins/aiops/public/components/log_categorization/format_category.test.tsx new file mode 100644 index 0000000000000..b3eabc36cb735 --- /dev/null +++ b/x-pack/plugins/aiops/public/components/log_categorization/format_category.test.tsx @@ -0,0 +1,97 @@ +/* + * 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 { Category } from '../../../common/api/log_categorization/types'; +import { useCreateFormattedExample } from './format_category'; +import { renderHook } from '@testing-library/react-hooks'; + +jest.mock('../../hooks/use_eui_theme', () => ({ + useIsDarkTheme: () => false, +})); + +const categoryData: Array<{ + category: Category; + elementCount: number; +}> = [ + { + category: { + key: 'Processed messages out of', + count: 0, + examples: ['Processed 676 messages out of 676'], + regex: '.*?Processed.+?messages.+?out.+?of.*?', + }, + elementCount: 9, + }, + { + category: { + key: 'Processed messages out of', + count: 0, + examples: ['Processed out 676 messages messages out of 676 Processed'], + regex: '.*?Processed.+?messages.+?out.+?of.*?', + }, + elementCount: 9, + }, + { + category: { + key: 'Processed of', + count: 0, + examples: ['Processed 676 messages out of 676'], + regex: '.*?Processed.+?of.*?', + }, + elementCount: 5, + }, + { + category: { + key: 'Processed messages out of', + count: 0, + examples: ['Processed messages out of'], + regex: '.*?Processed.+?messages.+?out.+?of.*?', + }, + elementCount: 9, + }, + { + category: { + key: '', + count: 0, + examples: ['Processed messages out of'], + regex: '.*?', + }, + elementCount: 3, + }, + { + category: { + key: 'Processed messages out of', + count: 0, + examples: ['Processed 676 (*?) message* out of 676'], + regex: '.*?Processed.+?messages.+?out.+?of.*?', + }, + elementCount: 9, + }, + { + category: { + key: '2024 0000 admin to admin console.prod 6000 api HTTP 1.1 https admin Mozilla 5.0 AppleWebKit KHTML like Gecko Chrome Safari', + count: 0, + examples: [ + '[05/Jan/2024 04:11:42 +0000] 40.69.144.53 - Lucio77 admin-console.you-got.mail to: admin-console.prod.008:6000: "GET /api/listCustomers HTTP/1.1" 200 383 "https://admin-console.you-got.mail" "Mozilla/5.0 (Windows; U; Windows NT 6.3) AppleWebKit/531.1.1 (KHTML, like Gecko) Chrome/23.0.835.0 Safari/531.1.1"', + ], + regex: + '.*?2024.+?0000.+?admin.+?to.+?admin.+?console.prod.+?6000.+?api.+?HTTP.+?1.1.+?https.+?admin.+?Mozilla.+?5.0.+?AppleWebKit.+?KHTML.+?like.+?Gecko.+?Chrome.+?Safari.*?', + }, + elementCount: 41, + }, +]; + +describe('FormattedPatternExamples', () => { + it('correctly splits each example into correct number of html elements', () => { + categoryData.forEach(({ category, elementCount }) => { + const { result } = renderHook(() => useCreateFormattedExample()); + const createFormattedExample = result.current; + const resp = createFormattedExample(category.key, category.examples[0]); + expect(resp.length).toEqual(elementCount); + }); + }); +}); diff --git a/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx b/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx new file mode 100644 index 0000000000000..9c3d298c5ecfd --- /dev/null +++ b/x-pack/plugins/aiops/public/components/log_categorization/format_category.tsx @@ -0,0 +1,180 @@ +/* + * 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, { FC, useCallback, useMemo } from 'react'; +import { EuiText, EuiHorizontalRule } from '@elastic/eui'; +import { css, SerializedStyles } from '@emotion/react'; +import type { Category } from '../../../common/api/log_categorization/types'; +import { useIsDarkTheme } from '../../hooks/use_eui_theme'; + +interface Props { + category: Category; + count?: number; +} + +// copies of the syntax colors used in EuiCode +const tokenStyleLight = css` + color: #765b96; +`; +const wildcardStyleLight = css` + color: #357160; +`; +const tokenStyleDark = css` + color: #a68ac5; +`; +const wildcardStyleDark = css` + color: #54b399; +`; + +interface Styles { + tokenStyle: SerializedStyles; + wildcardStyle: SerializedStyles; +} + +const useStyles = (): Styles => { + const isDarkTheme = useIsDarkTheme(); + + return useMemo( + () => + isDarkTheme + ? { + tokenStyle: tokenStyleDark, + wildcardStyle: wildcardStyleDark, + } + : { + tokenStyle: tokenStyleLight, + wildcardStyle: wildcardStyleLight, + }, + [isDarkTheme] + ); +}; + +export const useCreateFormattedExample = () => { + const { tokenStyle, wildcardStyle } = useStyles(); + + const createFormattedExample = useCallback( + (key: string, example: string): JSX.Element[] => { + const keyTokens = key.split(' '); + let tempExample = ` ${example} `; + const positions = keyTokens.map((t) => ({ + id: t, + start: 0, + end: 0, + })); + let offset = 0; + // match each token in order and record the start and end position + for (let i = 0; i < keyTokens.length; i++) { + const token = keyTokens[i]; + const tokenReg = new RegExp(`(\\W)(${token})(\\W)`); + + let j = 0; + const result = tokenReg.exec(tempExample); + if (!result) { + continue; + } + j = result.index; + const localEndOFToken = j + token.length + 1; + positions[i].start = offset + j + 1; + positions[i].end = offset + localEndOFToken; + // slice the example string to remove the token and preceding text + // to ensure we don't match future tokens in earlier text + tempExample = tempExample.slice(localEndOFToken); + offset += localEndOFToken; + } + + tempExample = ` ${example} `; + + // build up the list ot elements by chopping up the example string + // using the token positions found above + const elements: JSX.Element[] = []; + let pos = 0; + for (let i = 0; i < positions.length; i++) { + elements.push( + {tempExample.substring(pos, positions[i].start)} + ); + + elements.push( + + {tempExample.substring(positions[i].start, positions[i].end)} + + ); + pos = positions[i].end; + } + + elements.push( + + {tempExample.substring(positions[positions.length - 1].end)} + + ); + + return elements; + }, + [tokenStyle, wildcardStyle] + ); + + return createFormattedExample; +}; + +export const FormattedPatternExamples: FC = ({ category, count }) => { + const createFormattedExample = useCreateFormattedExample(); + + const e = useMemo(() => { + const { key, examples } = category; + const tempCount = count === undefined || count > examples.length ? examples.length : count; + const formattedExamples = new Array(tempCount) + .fill(0) + .map((_, i) => createFormattedExample(key, examples[i])); + return formattedExamples.map((example, i) => ( + <> + {example} + {i < formattedExamples.length - 1 ? : null} + + )); + }, [category, count, createFormattedExample]); + + return {e}; +}; + +export const FormattedRegex: FC = ({ category }) => { + const { tokenStyle, wildcardStyle } = useStyles(); + + const { regex } = category; + const formattedRegex = useMemo(() => { + const regexTokens = regex.split(/(\.\*\?)|(\.\+\?)/).filter((d) => d !== undefined); + const elements: JSX.Element[] = []; + for (let i = 0; i < regexTokens.length; i++) { + const token = regexTokens[i]; + if (token.match(/\.\*\?|\.\+\?/)) { + elements.push({token}); + } else { + elements.push({token}); + } + } + return elements; + }, [regex, tokenStyle, wildcardStyle]); + return ( + + {formattedRegex} + + ); +}; + +export const FormattedTokens: FC = ({ category }) => { + const { tokenStyle } = useStyles(); + + return ( + + {category.key} + + ); +}; + +const WrapInText: FC = ({ children }) => ( + + {children} + +); diff --git a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx index b0b4d699919be..55de63e7fb25d 100644 --- a/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx +++ b/x-pack/plugins/aiops/public/components/log_rate_analysis_results_table/log_rate_analysis_results_table.tsx @@ -136,6 +136,7 @@ export const LogRateAnalysisResultsTable: FC = key, count, examples: [], + regex: '', }, ]); return ( diff --git a/x-pack/plugins/aiops/public/hooks/use_eui_theme.ts b/x-pack/plugins/aiops/public/hooks/use_eui_theme.ts index fa1374a22800b..7da2bd6be954a 100644 --- a/x-pack/plugins/aiops/public/hooks/use_eui_theme.ts +++ b/x-pack/plugins/aiops/public/hooks/use_eui_theme.ts @@ -5,10 +5,15 @@ * 2.0. */ -import { useCurrentEuiThemeVars } from '@kbn/ml-kibana-theme'; +import { useCurrentEuiThemeVars, useIsDarkTheme as useIsDarkThemeMl } from '@kbn/ml-kibana-theme'; import { useAiopsAppContext } from './use_aiops_app_context'; export function useEuiTheme() { const { theme } = useAiopsAppContext(); return useCurrentEuiThemeVars(theme).euiTheme; } + +export function useIsDarkTheme() { + const { theme } = useAiopsAppContext(); + return useIsDarkThemeMl(theme); +} diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts index 1ddb624c99056..35c6d74fcf83f 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/analysis_handlers/histogram_handler.ts @@ -181,7 +181,7 @@ export const histogramHandlerFactory = const significantCategoriesHistogramQueries = significantCategories.map((d) => { const histogramQuery = getHistogramQuery(requestBody); const categoryQuery = getCategoryQuery(d.fieldName, [ - { key: `${d.key}`, count: d.doc_count, examples: [] }, + { key: `${d.key}`, count: d.doc_count, examples: [], regex: '' }, ]); if (Array.isArray(histogramQuery.bool?.filter)) { histogramQuery.bool?.filter?.push(categoryQuery); diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.test.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.test.ts index 8d43c552a443e..e6e79108435e2 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.test.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.test.ts @@ -145,7 +145,7 @@ describe('getCategoryRequest', () => { }, aggs: { examples: { - top_hits: { size: 1, sort: ['the-time-field-name'], _source: 'the-field-name' }, + top_hits: { size: 4, sort: ['the-time-field-name'], _source: 'the-field-name' }, }, }, }, diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.ts index 48fb888e58430..bbb64bc95cd30 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_categories.ts @@ -169,6 +169,7 @@ export const fetchCategories = async ( count: b.doc_count, examples: b.examples.hits.hits.map((h) => get(h._source, fieldName)), sparkline, + regex: b.regex, }; }); result.push({ diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_category_counts.test.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_category_counts.test.ts index b3fa6ff5f31a8..1593bf7dd5b18 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_category_counts.test.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_category_counts.test.ts @@ -15,6 +15,7 @@ describe('getCategoryCountRequest', () => { key: 'runTask ended no files to process', count: 667, examples: ['[runTask()] ended: no files to process'], + regex: '', }; const query = getCategoryCountRequest( @@ -65,8 +66,9 @@ describe('getCategoryCountMSearchRequest', () => { key: 'SLO summary transforms installed and started', count: 500, examples: ['SLO summary transforms installed and started'], + regex: '', }, - { key: 'Trusted Apps', count: 500, examples: ['Trusted Apps: '] }, + { key: 'Trusted Apps', count: 500, examples: ['Trusted Apps: '], regex: '' }, ]; const query = getCategoryCountMSearchRequest( diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_terms_2_categories_counts.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_terms_2_categories_counts.ts index b9eac01041be1..a39418807e40a 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_terms_2_categories_counts.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/fetch_terms_2_categories_counts.ts @@ -93,7 +93,7 @@ export async function fetchTerms2CategoriesCounts( params, [{ fieldName: term.fieldName, fieldValue: term.fieldValue }], category.fieldName, - { key: `${category.key}`, count: category.doc_count, examples: [] }, + { key: `${category.key}`, count: category.doc_count, examples: [], regex: '' }, from, to ) as estypes.MsearchMultisearchBody @@ -121,7 +121,7 @@ export async function fetchTerms2CategoriesCounts( fieldValue, })), category.fieldName, - { key: `${category.key}`, count: category.doc_count, examples: [] }, + { key: `${category.key}`, count: category.doc_count, examples: [], regex: '' }, from, to ) as estypes.MsearchMultisearchBody diff --git a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/get_group_filter.ts b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/get_group_filter.ts index e2ae795004e18..b70ee26ae7f2a 100644 --- a/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/get_group_filter.ts +++ b/x-pack/plugins/aiops/server/routes/log_rate_analysis/queries/get_group_filter.ts @@ -43,6 +43,7 @@ export function getGroupFilter( key: d.key, count: d.docCount, examples: [], + regex: '', }, ]) ); diff --git a/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts b/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts index 18b5004393027..4ee9f40b3f55d 100644 --- a/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts +++ b/x-pack/test/functional/services/aiops/log_pattern_analysis_page.ts @@ -128,7 +128,7 @@ export function LogPatternAnalysisPageProvider({ getService, getPageObject }: Ft const rows = await tableListContainer.findAllByClassName('euiTableRow'); const row = rows[rowIndex]; const cells = await row.findAllByClassName('euiTableRowCell'); - return Number(await cells[0].getVisibleText()); + return Number(await cells[1].getVisibleText()); }, async assertDiscoverDocCountExists() {