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] [AIOps] Log Rate Analysis: Shows top N results when no docs in baseline or deviation #171924

Merged
merged 20 commits into from Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 17 additions & 1 deletion x-pack/plugins/aiops/common/api/log_rate_analysis/actions.ts
Expand Up @@ -36,6 +36,7 @@ export const API_ACTION_NAME = {
RESET_ALL: 'reset_all',
RESET_ERRORS: 'reset_errors',
RESET_GROUPS: 'reset_groups',
SET_ZERO_DOCS_FALLBACK: 'set_zero_docs_fallback',
UPDATE_LOADING_STATE: 'update_loading_state',
} as const;
export type ApiActionName = typeof API_ACTION_NAME[keyof typeof API_ACTION_NAME];
Expand Down Expand Up @@ -210,6 +211,20 @@ export function updateLoadingStateAction(
};
}

interface ApiActionSetZeroDocsFallback {
type: typeof API_ACTION_NAME.SET_ZERO_DOCS_FALLBACK;
payload: boolean;
}

export function setZeroDocsFallback(
payload: ApiActionSetZeroDocsFallback['payload']
): ApiActionSetZeroDocsFallback {
return {
type: API_ACTION_NAME.SET_ZERO_DOCS_FALLBACK,
payload,
};
}

export type AiopsLogRateAnalysisApiAction<T extends ApiVersion> =
| ApiActionAddSignificantItems<T>
| ApiActionAddSignificantItemsGroup<T>
Expand All @@ -220,4 +235,5 @@ export type AiopsLogRateAnalysisApiAction<T extends ApiVersion> =
| ApiActionResetAll
| ApiActionResetErrors
| ApiActionResetGroups
| ApiActionUpdateLoadingState;
| ApiActionUpdateLoadingState
| ApiActionSetZeroDocsFallback;
1 change: 1 addition & 0 deletions x-pack/plugins/aiops/common/api/stream_reducer.test.ts
Expand Up @@ -31,6 +31,7 @@ describe('streamReducer', () => {
significantItems: [],
significantItemsGroups: [],
errors: [],
zeroDocsFallback: false,
});
});

Expand Down
4 changes: 4 additions & 0 deletions x-pack/plugins/aiops/common/api/stream_reducer.ts
Expand Up @@ -18,6 +18,7 @@ interface StreamState {
loadingState: string;
remainingFieldCandidates?: string[];
groupsMissing?: boolean;
zeroDocsFallback: boolean;
}

export const initialState: StreamState = {
Expand All @@ -27,6 +28,7 @@ export const initialState: StreamState = {
errors: [],
loaded: 0,
loadingState: '',
zeroDocsFallback: false,
};

export function streamReducer(
Expand Down Expand Up @@ -72,6 +74,8 @@ export function streamReducer(
return initialState;
case API_ACTION_NAME.UPDATE_LOADING_STATE:
return { ...state, ...action.payload };
case API_ACTION_NAME.SET_ZERO_DOCS_FALLBACK:
return { ...state, zeroDocsFallback: action.payload };
default:
return state;
}
Expand Down
Expand Up @@ -46,6 +46,7 @@ import {
import { useLogRateAnalysisResultsTableRowContext } from '../log_rate_analysis_results_table/log_rate_analysis_results_table_row_provider';

import { FieldFilterPopover } from './field_filter_popover';
import { LogRateAnalysisTypeCallOut } from './log_rate_analysis_type_callout';

const groupResultsMessage = i18n.translate(
'xpack.aiops.logRateAnalysis.resultsTable.groupedSwitchLabel.groupResults',
Expand Down Expand Up @@ -209,7 +210,8 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
{ [AIOPS_TELEMETRY_ID.AIOPS_ANALYSIS_RUN_ORIGIN]: embeddingOrigin }
);

const { significantItems } = data;
const { significantItems, zeroDocsFallback } = data;

useEffect(
() => setUniqueFieldNames(uniq(significantItems.map((d) => d.fieldName)).sort()),
[significantItems]
Expand Down Expand Up @@ -362,37 +364,13 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
/>
</EuiFlexItem>
</ProgressControls>
{showLogRateAnalysisResultsTable && (
{showLogRateAnalysisResultsTable && currentAnalysisType !== undefined && (
<>
<EuiSpacer size="s" />
<EuiCallOut
title={
<span data-test-subj="aiopsAnalysisTypeCalloutTitle">
{currentAnalysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE
? i18n.translate('xpack.aiops.analysis.analysisTypeSpikeCallOutTitle', {
defaultMessage: 'Analysis type: Log rate spike',
})
: i18n.translate('xpack.aiops.analysis.analysisTypeDipCallOutTitle', {
defaultMessage: 'Analysis type: Log rate dip',
})}
</span>
}
color="primary"
iconType="pin"
size="s"
>
<EuiText size="s">
{currentAnalysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE
? i18n.translate('xpack.aiops.analysis.analysisTypeSpikeCallOutContent', {
defaultMessage:
'The median log rate in the selected deviation time range is higher than the baseline. Therefore, the analysis results table shows statistically significant items within the deviation time range that are contributors to the spike. The "doc count" column refers to the amount of documents in the deviation time range.',
})
: i18n.translate('xpack.aiops.analysis.analysisTypeDipCallOutContent', {
defaultMessage:
'The median log rate in the selected deviation time range is lower than the baseline. Therefore, the analysis results table shows statistically significant items within the baseline time range that are less in number or missing within the deviation time range. The "doc count" column refers to the amount of documents in the baseline time range.',
})}
</EuiText>
</EuiCallOut>
<LogRateAnalysisTypeCallOut
analysisType={currentAnalysisType}
zeroDocsFallback={zeroDocsFallback}
/>
<EuiSpacer size="xs" />
</>
)}
Expand Down Expand Up @@ -490,6 +468,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
searchQuery={searchQuery}
barColorOverride={barColorOverride}
barHighlightColorOverride={barHighlightColorOverride}
zeroDocsFallback={zeroDocsFallback}
/>
) : null}
{showLogRateAnalysisResultsTable && !groupResults ? (
Expand All @@ -501,6 +480,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
searchQuery={searchQuery}
barColorOverride={barColorOverride}
barHighlightColorOverride={barHighlightColorOverride}
zeroDocsFallback={zeroDocsFallback}
/>
) : null}
</div>
Expand Down
@@ -0,0 +1,73 @@
/*
* 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, { type FC } from 'react';

import { EuiCallOut, EuiText } from '@elastic/eui';

import { LOG_RATE_ANALYSIS_TYPE, type LogRateAnalysisType } from '@kbn/aiops-utils';
import { i18n } from '@kbn/i18n';

interface LogRateAnalysisTypeCallOutProps {
analysisType: LogRateAnalysisType;
zeroDocsFallback: boolean;
}

export const LogRateAnalysisTypeCallOut: FC<LogRateAnalysisTypeCallOutProps> = ({
analysisType,
zeroDocsFallback,
}) => {
let callOutTitle: string;
let callOutText: string;

if (!zeroDocsFallback && analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE) {
callOutTitle = i18n.translate('xpack.aiops.analysis.analysisTypeSpikeCallOutTitle', {
defaultMessage: 'Analysis type: Log rate spike',
});
callOutText = i18n.translate('xpack.aiops.analysis.analysisTypeSpikeCallOutContent', {
defaultMessage:
'The median log rate in the selected deviation time range is higher than the baseline. Therefore, the analysis results table shows statistically significant items within the deviation time range that are contributors to the spike. The "doc count" column refers to the amount of documents in the deviation time range.',
});
} else if (!zeroDocsFallback && analysisType === LOG_RATE_ANALYSIS_TYPE.DIP) {
callOutTitle = i18n.translate('xpack.aiops.analysis.analysisTypeDipCallOutTitle', {
defaultMessage: 'Analysis type: Log rate dip',
});
callOutText = i18n.translate('xpack.aiops.analysis.analysisTypeDipCallOutContent', {
defaultMessage:
'The median log rate in the selected deviation time range is lower than the baseline. Therefore, the analysis results table shows statistically significant items within the baseline time range that are less in number or missing within the deviation time range. The "doc count" column refers to the amount of documents in the baseline time range.',
});
} else if (zeroDocsFallback && analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE) {
callOutTitle = i18n.translate('xpack.aiops.analysis.analysisTypeSpikeFallbackCallOutTitle', {
defaultMessage: 'Analysis type: Top items for deviation time range',
});
callOutText = i18n.translate('xpack.aiops.analysis.analysisTypeSpikeCallOutContentFallback', {
defaultMessage:
'The baseline time range does not contain any documents. Therefor the results show top log message categories and field values for the deviation time range.',
peteharverson marked this conversation as resolved.
Show resolved Hide resolved
});
} else if (zeroDocsFallback && analysisType === LOG_RATE_ANALYSIS_TYPE.DIP) {
callOutTitle = i18n.translate('xpack.aiops.analysis.analysisTypeDipFallbackCallOutTitle', {
defaultMessage: 'Analysis type: Top items for baseline time range',
});
callOutText = i18n.translate('xpack.aiops.analysis.analysisTypeDipCallOutContentFallback', {
defaultMessage:
'The deviation time range does not contain any documents. Therefor the results show top log message categories and field values for the baseline time range.',
peteharverson marked this conversation as resolved.
Show resolved Hide resolved
});
} else {
return null;
}

return (
<EuiCallOut
title={<span data-test-subj="aiopsAnalysisTypeCalloutTitle">{callOutTitle}</span>}
color="primary"
iconType="pin"
size="s"
>
<EuiText size="s">{callOutText}</EuiText>
</EuiCallOut>
);
};
Expand Up @@ -51,7 +51,9 @@ const NOT_AVAILABLE = '--';

const PAGINATION_SIZE_OPTIONS = [5, 10, 20, 50];
const DEFAULT_SORT_FIELD = 'pValue';
const DEFAULT_SORT_FIELD_ZERO_DOCS_FALLBACK = 'doc_count';
const DEFAULT_SORT_DIRECTION = 'asc';
const DEFAULT_SORT_DIRECTION_ZERO_DOCS_FALLBACK = 'desc';

const TRUNCATE_TEXT_LINES = 3;

Expand All @@ -66,6 +68,7 @@ interface LogRateAnalysisResultsTableProps {
barColorOverride?: string;
/** Optional color override for the highlighted bar color for charts */
barHighlightColorOverride?: string;
zeroDocsFallback?: boolean;
}

export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> = ({
Expand All @@ -77,6 +80,7 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
timeRangeMs,
barColorOverride,
barHighlightColorOverride,
zeroDocsFallback = false,
}) => {
const euiTheme = useEuiTheme();
const primaryBackgroundColor = useEuiBackgroundColor('primary');
Expand All @@ -93,8 +97,12 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =

const [pageIndex, setPageIndex] = useState(0);
const [pageSize, setPageSize] = useState(10);
const [sortField, setSortField] = useState<keyof SignificantItem>(DEFAULT_SORT_FIELD);
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>(DEFAULT_SORT_DIRECTION);
const [sortField, setSortField] = useState<keyof SignificantItem>(
zeroDocsFallback ? DEFAULT_SORT_FIELD_ZERO_DOCS_FALLBACK : DEFAULT_SORT_FIELD
);
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>(
zeroDocsFallback ? DEFAULT_SORT_DIRECTION_ZERO_DOCS_FALLBACK : DEFAULT_SORT_DIRECTION
);

const { data, uiSettings, fieldFormats, charts } = useAiopsAppContext();

Expand Down Expand Up @@ -236,7 +244,10 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
sortable: true,
valign: 'middle',
},
{
];

if (!zeroDocsFallback) {
columns.push({
'data-test-subj': 'aiopsLogRateAnalysisResultsTableColumnPValue',
width: NARROW_COLUMN_WIDTH,
field: 'pValue',
Expand All @@ -260,8 +271,9 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
render: (pValue: number | null) => pValue?.toPrecision(3) ?? NOT_AVAILABLE,
sortable: true,
valign: 'middle',
},
{
});

columns.push({
'data-test-subj': 'aiopsLogRateAnalysisResultsTableColumnImpact',
width: NARROW_COLUMN_WIDTH,
field: 'pValue',
Expand Down Expand Up @@ -291,21 +303,22 @@ export const LogRateAnalysisResultsTable: FC<LogRateAnalysisResultsTableProps> =
},
sortable: true,
valign: 'middle',
},
{
'data-test-subj': 'aiopsLogRateAnalysisResultsTableColumnAction',
name: i18n.translate('xpack.aiops.logRateAnalysis.resultsTable.actionsColumnName', {
defaultMessage: 'Actions',
}),
actions: [
...(viewInDiscoverAction ? [viewInDiscoverAction] : []),
...(viewInLogPatternAnalysisAction ? [viewInLogPatternAnalysisAction] : []),
copyToClipBoardAction,
],
width: ACTIONS_COLUMN_WIDTH,
valign: 'middle',
},
];
});
}

columns.push({
'data-test-subj': 'aiopsLogRateAnalysisResultsTableColumnAction',
name: i18n.translate('xpack.aiops.logRateAnalysis.resultsTable.actionsColumnName', {
defaultMessage: 'Actions',
}),
actions: [
...(viewInDiscoverAction ? [viewInDiscoverAction] : []),
...(viewInLogPatternAnalysisAction ? [viewInLogPatternAnalysisAction] : []),
copyToClipBoardAction,
],
width: ACTIONS_COLUMN_WIDTH,
valign: 'middle',
});

if (isExpandedRow === true) {
columns.unshift({
Expand Down