mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[ML] AIOps: Tweak log rate changes in log rate analysis results table. (#188648)
## Summary Part of #187684. This moves functions related to log rate changes to the `@kbn/aiops_log_rate_analysis` package. - `getLogRateAnalysisType` was renamed to `getLogRateAnalysisTypeForHistogram` to indicate its use with histogram data. - `getLogRateAnalysisTypeForCounts` was added for cases where we don't have the histogram data available but just the doc counts for baseline an deviation time ranges. This isn't used yet as of this PR but will be in a follow up in combination with the o11y AI assistant. - `getSwappedWindowParameters` is a helper to consolidate inline code that's used to swap baseline and deviation when we detected a dip in log rate. - Rounding for the log rate change messages was tweaked. Changes below `10x` will now be rounded to one digit to avoid messages like `1x increase`. - Tweaked/Shortened the message for 0 in baseline or deviation to just `45 up from 0 in baseline` / `down to 0 from 45 in baseline`. ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [x] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
This commit is contained in:
parent
3af5893f3b
commit
dffc044211
23 changed files with 551 additions and 159 deletions
|
@ -5,6 +5,7 @@
|
|||
"xpack.aiops": [
|
||||
"packages/ml/aiops_components",
|
||||
"packages/ml/aiops_log_pattern_analysis",
|
||||
"packages/ml/aiops_log_rate_analysis",
|
||||
"plugins/aiops"
|
||||
],
|
||||
"xpack.alerting": "plugins/alerting",
|
||||
|
|
|
@ -24,7 +24,7 @@ import { getTimeZone } from '@kbn/visualization-utils';
|
|||
import { i18n } from '@kbn/i18n';
|
||||
import type { IUiSettingsClient } from '@kbn/core/public';
|
||||
import {
|
||||
getLogRateAnalysisType,
|
||||
getLogRateAnalysisTypeForHistogram,
|
||||
getSnappedTimestamps,
|
||||
getSnappedWindowParameters,
|
||||
getWindowParametersForTrigger,
|
||||
|
@ -334,7 +334,7 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = (props) => {
|
|||
brushSelectionUpdateHandler({
|
||||
windowParameters: wpSnap,
|
||||
force: true,
|
||||
analysisType: getLogRateAnalysisType(adjustedChartPoints, wpSnap),
|
||||
analysisType: getLogRateAnalysisTypeForHistogram(adjustedChartPoints, wpSnap),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -391,7 +391,7 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = (props) => {
|
|||
brushSelectionUpdateHandler({
|
||||
windowParameters: wp,
|
||||
force: false,
|
||||
analysisType: getLogRateAnalysisType(adjustedChartPoints, wp),
|
||||
analysisType: getLogRateAnalysisTypeForHistogram(adjustedChartPoints, wp),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import { finalSignificantItemGroups } from '@kbn/aiops-test-utils/artificial_log
|
|||
import {
|
||||
addSignificantItems,
|
||||
addSignificantItemsGroup,
|
||||
resetAll,
|
||||
resetResults,
|
||||
resetGroups,
|
||||
updateLoadingState,
|
||||
getDefaultState,
|
||||
|
@ -58,7 +58,7 @@ describe('streamReducer', () => {
|
|||
|
||||
expect(state1.significantItems).toHaveLength(1);
|
||||
|
||||
const state2 = streamReducer(state1, resetAll());
|
||||
const state2 = streamReducer(state1, resetResults());
|
||||
|
||||
expect(state2.significantItems).toHaveLength(0);
|
||||
});
|
||||
|
|
|
@ -15,8 +15,13 @@ import type {
|
|||
SignificantItemGroupHistogram,
|
||||
} from '@kbn/ml-agg-utils';
|
||||
|
||||
import type { WindowParameters } from '../window_parameters';
|
||||
import type { LogRateAnalysisType } from '../log_rate_analysis_type';
|
||||
|
||||
export interface StreamState {
|
||||
ccsWarning: boolean;
|
||||
currentAnalysisType?: LogRateAnalysisType;
|
||||
currentAnalysisWindowParameters?: WindowParameters;
|
||||
significantItems: SignificantItem[];
|
||||
significantItemsGroups: SignificantItemGroup[];
|
||||
errors: string[];
|
||||
|
@ -80,7 +85,12 @@ export const logRateAnalysisResultsSlice = createSlice({
|
|||
resetGroups: (state) => {
|
||||
state.significantItemsGroups = [];
|
||||
},
|
||||
resetAll: () => getDefaultState(),
|
||||
// Reset the results but keep the current analysis type and window parameters.
|
||||
resetResults: (state) => ({
|
||||
...getDefaultState(),
|
||||
currentAnalysisType: state.currentAnalysisType,
|
||||
currentAnalysisWindowParameters: state.currentAnalysisWindowParameters,
|
||||
}),
|
||||
updateLoadingState: (
|
||||
state,
|
||||
action: PayloadAction<{
|
||||
|
@ -96,6 +106,15 @@ export const logRateAnalysisResultsSlice = createSlice({
|
|||
setZeroDocsFallback: (state, action: PayloadAction<boolean>) => {
|
||||
state.zeroDocsFallback = action.payload;
|
||||
},
|
||||
setCurrentAnalysisType: (state, action: PayloadAction<LogRateAnalysisType | undefined>) => {
|
||||
state.currentAnalysisType = action.payload;
|
||||
},
|
||||
setCurrentAnalysisWindowParameters: (
|
||||
state,
|
||||
action: PayloadAction<WindowParameters | undefined>
|
||||
) => {
|
||||
state.currentAnalysisWindowParameters = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -113,9 +132,11 @@ export const {
|
|||
addSignificantItemsGroupHistogram,
|
||||
addSignificantItemsHistogram,
|
||||
ping,
|
||||
resetAll,
|
||||
resetResults,
|
||||
resetErrors,
|
||||
resetGroups,
|
||||
setCurrentAnalysisType,
|
||||
setCurrentAnalysisWindowParameters,
|
||||
setZeroDocsFallback,
|
||||
updateLoadingState,
|
||||
} = logRateAnalysisResultsSlice.actions;
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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 { getBaselineAndDeviationRates } from './get_baseline_and_deviation_rates';
|
||||
import { LOG_RATE_ANALYSIS_TYPE } from './log_rate_analysis_type';
|
||||
|
||||
describe('getBaselineAndDeviationRates', () => {
|
||||
it('calculates rates for SPIKE analysis', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.SPIKE;
|
||||
const baselineBuckets = 10;
|
||||
const deviationBuckets = 5;
|
||||
const docCount = 100;
|
||||
const bgCount = 50;
|
||||
const expected = {
|
||||
baselineBucketRate: 5, // 50 / 10
|
||||
deviationBucketRate: 20, // 100 / 5
|
||||
};
|
||||
|
||||
const result = getBaselineAndDeviationRates(
|
||||
analysisType,
|
||||
baselineBuckets,
|
||||
deviationBuckets,
|
||||
docCount,
|
||||
bgCount
|
||||
);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('calculates rates for DIP analysis', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.DIP;
|
||||
const baselineBuckets = 8;
|
||||
const deviationBuckets = 4;
|
||||
const docCount = 80; // Now represents baseline period in DIP
|
||||
const bgCount = 40; // Now represents deviation period in DIP
|
||||
const expected = {
|
||||
baselineBucketRate: 10, // 80 / 8
|
||||
deviationBucketRate: 10, // 40 / 4
|
||||
};
|
||||
|
||||
const result = getBaselineAndDeviationRates(
|
||||
analysisType,
|
||||
baselineBuckets,
|
||||
deviationBuckets,
|
||||
docCount,
|
||||
bgCount
|
||||
);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
|
||||
it('handles zero buckets without throwing error', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.SPIKE;
|
||||
const baselineBuckets = 0;
|
||||
const deviationBuckets = 0;
|
||||
const docCount = 100;
|
||||
const bgCount = 50;
|
||||
const expected = {
|
||||
baselineBucketRate: 0,
|
||||
deviationBucketRate: 0,
|
||||
};
|
||||
|
||||
const result = getBaselineAndDeviationRates(
|
||||
analysisType,
|
||||
baselineBuckets,
|
||||
deviationBuckets,
|
||||
docCount,
|
||||
bgCount
|
||||
);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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 { LOG_RATE_ANALYSIS_TYPE, type LogRateAnalysisType } from './log_rate_analysis_type';
|
||||
|
||||
/**
|
||||
* Calculates the baseline and deviation rates for log rate analysis based on the specified analysis type.
|
||||
*
|
||||
* This function computes the rates by dividing the document count (docCount) and background count (bgCount)
|
||||
* by the number of buckets allocated for baseline and deviation periods, respectively. The calculation
|
||||
* method varies depending on whether the analysis type is a "spike" or a "dip". For a "spike", the baseline
|
||||
* rate is derived from the background count and the deviation rate from the document count. For a "dip",
|
||||
* the roles are reversed.
|
||||
*
|
||||
* @param analysisType The type of analysis to perform, can be either "spike" or "dip".
|
||||
* @param baselineBuckets The number of buckets into which the baseline period is divided.
|
||||
* @param deviationBuckets The number of buckets into which the deviation period is divided.
|
||||
* @param docCount The total document count observed in the deviation period.
|
||||
* @param bgCount The total background count observed in the baseline period.
|
||||
* @returns An object containing the calculated baseline and deviation bucket rates.
|
||||
*/
|
||||
export function getBaselineAndDeviationRates(
|
||||
analysisType: LogRateAnalysisType,
|
||||
baselineBuckets: number,
|
||||
deviationBuckets: number,
|
||||
docCount: number,
|
||||
bgCount: number
|
||||
): { baselineBucketRate: number; deviationBucketRate: number } {
|
||||
if (baselineBuckets === 0 || deviationBuckets === 0) {
|
||||
return { baselineBucketRate: 0, deviationBucketRate: 0 };
|
||||
} else if (analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE) {
|
||||
return {
|
||||
baselineBucketRate: Math.round(bgCount / baselineBuckets),
|
||||
deviationBucketRate: Math.round(docCount / deviationBuckets),
|
||||
};
|
||||
} else {
|
||||
// For dip, the "doc count" refers to the amount of documents in the baseline time range so we set baselineBucketRate
|
||||
return {
|
||||
baselineBucketRate: Math.round(docCount / baselineBuckets),
|
||||
deviationBucketRate: Math.round(bgCount / deviationBuckets),
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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 { LOG_RATE_ANALYSIS_TYPE } from './log_rate_analysis_type';
|
||||
import { getLogRateAnalysisTypeForCounts } from './get_log_rate_analysis_type_for_counts';
|
||||
|
||||
const windowParameters = {
|
||||
baselineMin: 1654579807500,
|
||||
baselineMax: 1654586107500,
|
||||
deviationMin: 1654586400000,
|
||||
deviationMax: 1654587007500,
|
||||
};
|
||||
|
||||
describe('getLogRateAnalysisTypeForCounts', () => {
|
||||
it('returns SPIKE when normalized deviation count is higher than baseline count', () => {
|
||||
const baselineCount = 100;
|
||||
const deviationCount = 200;
|
||||
|
||||
const result = getLogRateAnalysisTypeForCounts(baselineCount, deviationCount, windowParameters);
|
||||
|
||||
expect(result).toEqual(LOG_RATE_ANALYSIS_TYPE.SPIKE);
|
||||
});
|
||||
|
||||
it('returns DIP when normalized deviation count is lower than baseline count', () => {
|
||||
const baselineCount = 20000;
|
||||
const deviationCount = 10;
|
||||
|
||||
const result = getLogRateAnalysisTypeForCounts(baselineCount, deviationCount, windowParameters);
|
||||
|
||||
expect(result).toEqual(LOG_RATE_ANALYSIS_TYPE.DIP);
|
||||
});
|
||||
|
||||
it('handles zero baseline count without throwing error', () => {
|
||||
const baselineCount = 0;
|
||||
const deviationCount = 100;
|
||||
|
||||
const result = getLogRateAnalysisTypeForCounts(baselineCount, deviationCount, windowParameters);
|
||||
|
||||
expect(result).toBe(LOG_RATE_ANALYSIS_TYPE.SPIKE);
|
||||
});
|
||||
|
||||
it('handles zero deviation count without throwing error', () => {
|
||||
const baselineCount = 100;
|
||||
const deviationCount = 0;
|
||||
|
||||
const result = getLogRateAnalysisTypeForCounts(baselineCount, deviationCount, windowParameters);
|
||||
|
||||
expect(result).toBe(LOG_RATE_ANALYSIS_TYPE.DIP);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* 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 { LOG_RATE_ANALYSIS_TYPE, type LogRateAnalysisType } from './log_rate_analysis_type';
|
||||
import type { WindowParameters } from './window_parameters';
|
||||
|
||||
/**
|
||||
* Identify the log rate analysis type based on the baseline/deviation doc counts.
|
||||
*
|
||||
* @param baselineCount The baseline doc count.
|
||||
* @param deviationCount The deviation doc count.
|
||||
* @param windowParameters The window parameters with baseline and deviation time range.
|
||||
* @returns The log rate analysis type.
|
||||
*/
|
||||
export function getLogRateAnalysisTypeForCounts(
|
||||
baselineCount: number,
|
||||
deviationCount: number,
|
||||
windowParameters: WindowParameters
|
||||
): LogRateAnalysisType {
|
||||
const { baselineMin, baselineMax, deviationMin, deviationMax } = windowParameters;
|
||||
|
||||
const deviationDuration = deviationMax - deviationMin;
|
||||
const deviationPerBucket = deviationCount;
|
||||
|
||||
const baselineNormalizedDuration = (baselineMax - baselineMin) / deviationDuration;
|
||||
const baselinePerBucket = baselineCount / baselineNormalizedDuration;
|
||||
|
||||
return deviationPerBucket >= baselinePerBucket
|
||||
? LOG_RATE_ANALYSIS_TYPE.SPIKE
|
||||
: LOG_RATE_ANALYSIS_TYPE.DIP;
|
||||
}
|
|
@ -6,9 +6,9 @@
|
|||
*/
|
||||
|
||||
import type { LogRateHistogramItem } from './log_rate_histogram_item';
|
||||
import { getLogRateAnalysisType } from './get_log_rate_analysis_type';
|
||||
import { getLogRateAnalysisTypeForHistogram } from './get_log_rate_analysis_type_for_histogram';
|
||||
|
||||
describe('getLogRateAnalysisType', () => {
|
||||
describe('getLogRateAnalysisTypeForHistogram', () => {
|
||||
const LogRateHistogramMock: LogRateHistogramItem[] = [
|
||||
{ time: 0, value: 10 },
|
||||
{ time: 1, value: 10 },
|
||||
|
@ -24,7 +24,7 @@ describe('getLogRateAnalysisType', () => {
|
|||
|
||||
test('returns "spike" for the given parameters', () => {
|
||||
expect(
|
||||
getLogRateAnalysisType(LogRateHistogramMock, {
|
||||
getLogRateAnalysisTypeForHistogram(LogRateHistogramMock, {
|
||||
baselineMin: 4,
|
||||
baselineMax: 6,
|
||||
deviationMin: 7,
|
||||
|
@ -35,7 +35,7 @@ describe('getLogRateAnalysisType', () => {
|
|||
|
||||
test('returns "dip" for the given parameters', () => {
|
||||
expect(
|
||||
getLogRateAnalysisType(LogRateHistogramMock, {
|
||||
getLogRateAnalysisTypeForHistogram(LogRateHistogramMock, {
|
||||
baselineMin: 0,
|
||||
baselineMax: 2,
|
||||
deviationMin: 3,
|
||||
|
@ -46,7 +46,7 @@ describe('getLogRateAnalysisType', () => {
|
|||
|
||||
test('falls back to "spike" if both time range have the same median', () => {
|
||||
expect(
|
||||
getLogRateAnalysisType(LogRateHistogramMock, {
|
||||
getLogRateAnalysisTypeForHistogram(LogRateHistogramMock, {
|
||||
baselineMin: 0,
|
||||
baselineMax: 2,
|
||||
deviationMin: 4,
|
|
@ -19,7 +19,7 @@ import type { WindowParameters } from './window_parameters';
|
|||
* @param windowParameters The window parameters with baseline and deviation time range.
|
||||
* @returns The log rate analysis type.
|
||||
*/
|
||||
export function getLogRateAnalysisType(
|
||||
export function getLogRateAnalysisTypeForHistogram(
|
||||
logRateHistogram: LogRateHistogramItem[],
|
||||
windowParameters: WindowParameters
|
||||
): LogRateAnalysisType {
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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 { LOG_RATE_ANALYSIS_TYPE } from './log_rate_analysis_type';
|
||||
import { getLogRateChange } from './get_log_rate_change';
|
||||
|
||||
describe('getLogRateChange', () => {
|
||||
it('calculates the factor and message for a SPIKE analysis with factor < 10', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.SPIKE;
|
||||
const baselineBucketRate = 5;
|
||||
const deviationBucketRate = 44;
|
||||
const expectedFactor = 8.8;
|
||||
const expectedMessage = '8.8x higher';
|
||||
|
||||
const { message, factor } = getLogRateChange(
|
||||
analysisType,
|
||||
baselineBucketRate,
|
||||
deviationBucketRate
|
||||
);
|
||||
|
||||
expect(factor).toBe(expectedFactor);
|
||||
expect(message).toBe(expectedMessage);
|
||||
});
|
||||
|
||||
it('calculates the factor and message for a SPIKE analysis with factor >= 10', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.SPIKE;
|
||||
const baselineBucketRate = 5;
|
||||
const deviationBucketRate = 51;
|
||||
const expectedFactor = 10;
|
||||
const expectedMessage = '10x higher';
|
||||
|
||||
const { message, factor } = getLogRateChange(
|
||||
analysisType,
|
||||
baselineBucketRate,
|
||||
deviationBucketRate
|
||||
);
|
||||
|
||||
expect(factor).toEqual(expectedFactor);
|
||||
expect(message).toContain(expectedMessage);
|
||||
});
|
||||
|
||||
it('calculates the factor and message for a DIP analysis with factor < 10', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.DIP;
|
||||
const baselineBucketRate = 256;
|
||||
const deviationBucketRate = 44;
|
||||
const expectedFactor = 5.8;
|
||||
const expectedMessage = '5.8x lower';
|
||||
|
||||
const { message, factor } = getLogRateChange(
|
||||
analysisType,
|
||||
baselineBucketRate,
|
||||
deviationBucketRate
|
||||
);
|
||||
|
||||
expect(factor).toBe(expectedFactor);
|
||||
expect(message).toBe(expectedMessage);
|
||||
});
|
||||
|
||||
it('calculates the factor and message for a DIP analysis with factor >= 10', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.DIP;
|
||||
const baselineBucketRate = 1024;
|
||||
const deviationBucketRate = 51;
|
||||
const expectedFactor = 20;
|
||||
const expectedMessage = '20x lower';
|
||||
|
||||
const { message, factor } = getLogRateChange(
|
||||
analysisType,
|
||||
baselineBucketRate,
|
||||
deviationBucketRate
|
||||
);
|
||||
|
||||
expect(factor).toEqual(expectedFactor);
|
||||
expect(message).toContain(expectedMessage);
|
||||
});
|
||||
|
||||
it('handles a baseline rate of 0 without throwing an error', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.SPIKE;
|
||||
const baselineBucketRate = 0;
|
||||
const deviationBucketRate = 10;
|
||||
const expectedMessage = 'up to 10 from 0 in baseline';
|
||||
const { message, factor } = getLogRateChange(
|
||||
analysisType,
|
||||
baselineBucketRate,
|
||||
deviationBucketRate
|
||||
);
|
||||
|
||||
// Factor is undefined if baseline rate is 0
|
||||
expect(factor).toBe(undefined);
|
||||
expect(message).toContain(expectedMessage);
|
||||
});
|
||||
|
||||
it('handles a deviation rate of 0 without throwing an error', () => {
|
||||
const analysisType = LOG_RATE_ANALYSIS_TYPE.DIP;
|
||||
const baselineBucketRate = 500;
|
||||
const deviationBucketRate = 0;
|
||||
const expectedMessage = 'down to 0 from 500 in baseline';
|
||||
|
||||
const { message, factor } = getLogRateChange(
|
||||
analysisType,
|
||||
baselineBucketRate,
|
||||
deviationBucketRate
|
||||
);
|
||||
|
||||
// Factor is undefined if deviation rate is 0
|
||||
expect(factor).toBe(undefined);
|
||||
expect(message).toContain(expectedMessage);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
import { LOG_RATE_ANALYSIS_TYPE } from './log_rate_analysis_type';
|
||||
import type { LogRateAnalysisType } from './log_rate_analysis_type';
|
||||
|
||||
/**
|
||||
* Calculates the change in log rate between two time periods and generates a descriptive message.
|
||||
* It return the factor as a number as well as a human readable message.
|
||||
*
|
||||
* @param analysisType The type of log rate analysis (spike or dip).
|
||||
* @param baselineBucketRate The log rate (document count per unit time) during the baseline period.
|
||||
* @param deviationBucketRate The log rate (document count per unit time) during the deviation period.
|
||||
* @returns An object containing the message describing the rate change and the factor of change if applicable.
|
||||
*/
|
||||
export function getLogRateChange(
|
||||
analysisType: LogRateAnalysisType,
|
||||
baselineBucketRate: number,
|
||||
deviationBucketRate: number
|
||||
): { message: string; factor?: number } {
|
||||
if (analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE) {
|
||||
if (baselineBucketRate > 0) {
|
||||
const factor = deviationBucketRate / baselineBucketRate;
|
||||
const roundedFactor = factor < 10 ? Math.round(factor * 10) / 10 : Math.round(factor);
|
||||
|
||||
const message = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateFactorIncreaseLabel',
|
||||
{
|
||||
defaultMessage: '{roundedFactor}x higher',
|
||||
values: {
|
||||
roundedFactor,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return { message, factor: roundedFactor };
|
||||
} else {
|
||||
return {
|
||||
message: i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateDocIncreaseLabel',
|
||||
{
|
||||
defaultMessage: 'up to {deviationBucketRate} from 0 in baseline',
|
||||
values: { deviationBucketRate },
|
||||
}
|
||||
),
|
||||
};
|
||||
}
|
||||
} else {
|
||||
if (deviationBucketRate > 0) {
|
||||
// For dip, "doc count" refers to the amount of documents in the baseline time range so we use baselineBucketRate
|
||||
const factor = baselineBucketRate / deviationBucketRate;
|
||||
const roundedFactor = factor < 10 ? Math.round(factor * 10) / 10 : Math.round(factor);
|
||||
|
||||
const message = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateFactorDecreaseLabel',
|
||||
{
|
||||
defaultMessage: '{roundedFactor}x lower',
|
||||
values: {
|
||||
roundedFactor,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return { message, factor: roundedFactor };
|
||||
} else {
|
||||
return {
|
||||
message: i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateDocDecreaseLabel',
|
||||
{
|
||||
defaultMessage: 'down to 0 from {baselineBucketRate} in baseline',
|
||||
values: { baselineBucketRate },
|
||||
}
|
||||
),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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 { getSwappedWindowParameters } from './get_swapped_window_parameters';
|
||||
|
||||
describe('getSwappedWindowParameters', () => {
|
||||
it('swaps baseline and deviation parameters', () => {
|
||||
const windowParameters = {
|
||||
baselineMin: 1,
|
||||
baselineMax: 2,
|
||||
deviationMin: 3,
|
||||
deviationMax: 4,
|
||||
};
|
||||
const expected = {
|
||||
baselineMin: 3,
|
||||
baselineMax: 4,
|
||||
deviationMin: 1,
|
||||
deviationMax: 2,
|
||||
};
|
||||
|
||||
const result = getSwappedWindowParameters(windowParameters);
|
||||
|
||||
expect(result).toEqual(expected);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* 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 { WindowParameters } from './window_parameters';
|
||||
|
||||
/**
|
||||
* Swaps the baseline and deviation window parameters. To be used when we identify the type of analysis to be 'dip'.
|
||||
*
|
||||
* @param windowParameters An object containing the window parameters for baseline and deviation periods.
|
||||
* @returns A new `WindowParameters` object with the baseline and deviation parameters swapped.
|
||||
*/
|
||||
export const getSwappedWindowParameters = (
|
||||
windowParameters: WindowParameters
|
||||
): WindowParameters => ({
|
||||
baselineMin: windowParameters.deviationMin,
|
||||
baselineMax: windowParameters.deviationMax,
|
||||
deviationMin: windowParameters.baselineMin,
|
||||
deviationMax: windowParameters.baselineMax,
|
||||
});
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
export { LOG_RATE_ANALYSIS_HIGHLIGHT_COLOR } from './constants';
|
||||
export { getLogRateAnalysisType } from './get_log_rate_analysis_type';
|
||||
export { getLogRateAnalysisTypeForHistogram } from './get_log_rate_analysis_type_for_histogram';
|
||||
export { LOG_RATE_ANALYSIS_TYPE, type LogRateAnalysisType } from './log_rate_analysis_type';
|
||||
export type { LogRateHistogramItem } from './log_rate_histogram_item';
|
||||
export type { DocumentCountStats, DocumentStats, DocumentCountStatsChangePoint } from './types';
|
||||
|
@ -16,3 +16,6 @@ export { getSnappedWindowParameters } from './get_snapped_window_parameters';
|
|||
export { getWindowParameters } from './get_window_parameters';
|
||||
export { getWindowParametersForTrigger } from './get_window_parameters_for_trigger';
|
||||
export { getExtendedChangePoint } from './get_extended_change_point';
|
||||
export { getSwappedWindowParameters } from './get_swapped_window_parameters';
|
||||
export { getBaselineAndDeviationRates } from './get_baseline_and_deviation_rates';
|
||||
export { getLogRateChange } from './get_log_rate_change';
|
||||
|
|
|
@ -14,7 +14,7 @@ export {
|
|||
setInitialAnalysisStart,
|
||||
setIsBrushCleared,
|
||||
setStickyHistogram,
|
||||
setWindowParameters,
|
||||
setChartWindowParameters,
|
||||
type BrushSelectionUpdatePayload,
|
||||
} from './log_rate_analysis_slice';
|
||||
export {
|
||||
|
|
|
@ -35,7 +35,7 @@ export interface LogRateAnalysisState {
|
|||
initialAnalysisStart: InitialAnalysisStart;
|
||||
isBrushCleared: boolean;
|
||||
stickyHistogram: boolean;
|
||||
windowParameters?: WindowParameters;
|
||||
chartWindowParameters?: WindowParameters;
|
||||
earliest?: number;
|
||||
latest?: number;
|
||||
intervalMs?: number;
|
||||
|
@ -66,7 +66,7 @@ export const logRateAnalysisSlice = createSlice({
|
|||
action: PayloadAction<BrushSelectionUpdatePayload>
|
||||
) => {
|
||||
if (!state.isBrushCleared || action.payload.force) {
|
||||
state.windowParameters = action.payload.windowParameters;
|
||||
state.chartWindowParameters = action.payload.windowParameters;
|
||||
}
|
||||
if (action.payload.force) {
|
||||
state.isBrushCleared = false;
|
||||
|
@ -74,7 +74,7 @@ export const logRateAnalysisSlice = createSlice({
|
|||
state.analysisType = action.payload.analysisType;
|
||||
},
|
||||
clearSelection: (state: LogRateAnalysisState) => {
|
||||
state.windowParameters = undefined;
|
||||
state.chartWindowParameters = undefined;
|
||||
state.isBrushCleared = true;
|
||||
state.initialAnalysisStart = undefined;
|
||||
},
|
||||
|
@ -110,11 +110,11 @@ export const logRateAnalysisSlice = createSlice({
|
|||
setStickyHistogram: (state: LogRateAnalysisState, action: PayloadAction<boolean>) => {
|
||||
state.stickyHistogram = action.payload;
|
||||
},
|
||||
setWindowParameters: (
|
||||
setChartWindowParameters: (
|
||||
state: LogRateAnalysisState,
|
||||
action: PayloadAction<WindowParameters | undefined>
|
||||
) => {
|
||||
state.windowParameters = action.payload;
|
||||
state.chartWindowParameters = action.payload;
|
||||
state.isBrushCleared = action.payload === undefined;
|
||||
},
|
||||
},
|
||||
|
@ -130,5 +130,5 @@ export const {
|
|||
setInitialAnalysisStart,
|
||||
setIsBrushCleared,
|
||||
setStickyHistogram,
|
||||
setWindowParameters,
|
||||
setChartWindowParameters,
|
||||
} = logRateAnalysisSlice.actions;
|
||||
|
|
|
@ -30,5 +30,6 @@
|
|||
"@kbn/ml-chi2test",
|
||||
"@kbn/ml-string-hash",
|
||||
"@kbn/ml-response-stream",
|
||||
"@kbn/i18n",
|
||||
]
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ export const LogRateAnalysisContent: FC<LogRateAnalysisContentProps> = ({
|
|||
);
|
||||
const loaded = useAppSelector((s) => s.logRateAnalysisResults.loaded);
|
||||
const analysisType = useAppSelector((s) => s.logRateAnalysis.analysisType);
|
||||
const windowParameters = useAppSelector((s) => s.logRateAnalysis.windowParameters);
|
||||
const windowParameters = useAppSelector((s) => s.logRateAnalysis.chartWindowParameters);
|
||||
|
||||
// Window parameters stored in the url state use this components
|
||||
// `initialAnalysisStart` prop to set the initial params restore from url state.
|
||||
|
|
|
@ -31,9 +31,9 @@ import {
|
|||
useAppSelector,
|
||||
} from '@kbn/aiops-log-rate-analysis/state';
|
||||
import {
|
||||
getSwappedWindowParameters,
|
||||
LOG_RATE_ANALYSIS_TYPE,
|
||||
type LogRateAnalysisType,
|
||||
type WindowParameters,
|
||||
} from '@kbn/aiops-log-rate-analysis';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { FormattedMessage } from '@kbn/i18n-react';
|
||||
|
@ -41,6 +41,10 @@ import type { SignificantItem, SignificantItemGroup } from '@kbn/ml-agg-utils';
|
|||
import { AIOPS_TELEMETRY_ID } from '@kbn/aiops-common/constants';
|
||||
import type { AiopsLogRateAnalysisSchema } from '@kbn/aiops-log-rate-analysis/api/schema';
|
||||
import type { AiopsLogRateAnalysisSchemaSignificantItem } from '@kbn/aiops-log-rate-analysis/api/schema_v2';
|
||||
import {
|
||||
setCurrentAnalysisType,
|
||||
setCurrentAnalysisWindowParameters,
|
||||
} from '@kbn/aiops-log-rate-analysis/api/stream_reducer';
|
||||
|
||||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
import { useDataSource } from '../../hooks/use_data_source';
|
||||
|
@ -161,23 +165,20 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
analysisType,
|
||||
earliest,
|
||||
latest,
|
||||
windowParameters,
|
||||
chartWindowParameters,
|
||||
documentStats: { sampleProbability },
|
||||
stickyHistogram,
|
||||
isBrushCleared,
|
||||
} = useAppSelector((s) => s.logRateAnalysis);
|
||||
const { isRunning, errors: streamErrors } = useAppSelector((s) => s.logRateAnalysisStream);
|
||||
const data = useAppSelector((s) => s.logRateAnalysisResults);
|
||||
const { currentAnalysisType, currentAnalysisWindowParameters } = data;
|
||||
|
||||
// Store the performance metric's start time using a ref
|
||||
// to be able to track it across rerenders.
|
||||
const analysisStartTime = useRef<number | undefined>(window.performance.now());
|
||||
const abortCtrl = useRef(new AbortController());
|
||||
|
||||
const [currentAnalysisType, setCurrentAnalysisType] = useState<LogRateAnalysisType | undefined>();
|
||||
const [currentAnalysisWindowParameters, setCurrentAnalysisWindowParameters] = useState<
|
||||
WindowParameters | undefined
|
||||
>();
|
||||
const [groupResults, setGroupResults] = useState<boolean>(false);
|
||||
const [groupSkipFields, setGroupSkipFields] = useState<string[]>([]);
|
||||
const [uniqueFieldNames, setUniqueFieldNames] = useState<string[]>([]);
|
||||
|
@ -281,8 +282,8 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
dispatch(clearAllRowState());
|
||||
}
|
||||
|
||||
setCurrentAnalysisType(analysisType);
|
||||
setCurrentAnalysisWindowParameters(windowParameters);
|
||||
dispatch(setCurrentAnalysisType(analysisType));
|
||||
dispatch(setCurrentAnalysisWindowParameters(chartWindowParameters));
|
||||
|
||||
// We trigger hooks updates above so we cannot directly call `start()` here
|
||||
// because it would be run with stale arguments.
|
||||
|
@ -290,7 +291,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
}
|
||||
|
||||
const startParams = useMemo(() => {
|
||||
if (!windowParameters) {
|
||||
if (!chartWindowParameters) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
@ -311,13 +312,8 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
// If analysis type is `spike`, pass on window parameters as is,
|
||||
// if it's `dip`, swap baseline and deviation.
|
||||
...(analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE
|
||||
? windowParameters
|
||||
: {
|
||||
baselineMin: windowParameters.deviationMin,
|
||||
baselineMax: windowParameters.deviationMax,
|
||||
deviationMin: windowParameters.baselineMin,
|
||||
deviationMax: windowParameters.baselineMax,
|
||||
}),
|
||||
? chartWindowParameters
|
||||
: getSwappedWindowParameters(chartWindowParameters)),
|
||||
overrides,
|
||||
sampleProbability,
|
||||
},
|
||||
|
@ -330,7 +326,7 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
http,
|
||||
searchQuery,
|
||||
dataView,
|
||||
windowParameters,
|
||||
chartWindowParameters,
|
||||
sampleProbability,
|
||||
overrides,
|
||||
embeddingOrigin,
|
||||
|
@ -346,8 +342,8 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
|
||||
useEffect(() => {
|
||||
if (startParams) {
|
||||
setCurrentAnalysisType(analysisType);
|
||||
setCurrentAnalysisWindowParameters(windowParameters);
|
||||
dispatch(setCurrentAnalysisType(analysisType));
|
||||
dispatch(setCurrentAnalysisWindowParameters(chartWindowParameters));
|
||||
dispatch(startStream(startParams));
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
|
@ -361,8 +357,8 @@ export const LogRateAnalysisResults: FC<LogRateAnalysisResultsProps> = ({
|
|||
const shouldRerunAnalysis = useMemo(
|
||||
() =>
|
||||
currentAnalysisWindowParameters !== undefined &&
|
||||
!isEqual(currentAnalysisWindowParameters, windowParameters),
|
||||
[currentAnalysisWindowParameters, windowParameters]
|
||||
!isEqual(currentAnalysisWindowParameters, chartWindowParameters),
|
||||
[currentAnalysisWindowParameters, chartWindowParameters]
|
||||
);
|
||||
|
||||
const showLogRateAnalysisResultsTable = data?.significantItems.length > 0;
|
||||
|
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* 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 { i18n } from '@kbn/i18n';
|
||||
import { LOG_RATE_ANALYSIS_TYPE } from '@kbn/aiops-log-rate-analysis';
|
||||
|
||||
export function getLogRateChange(
|
||||
analysisType: typeof LOG_RATE_ANALYSIS_TYPE[keyof typeof LOG_RATE_ANALYSIS_TYPE],
|
||||
baselineBucketRate: number,
|
||||
deviationBucketRate: number
|
||||
) {
|
||||
let message;
|
||||
let factor;
|
||||
|
||||
if (analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE) {
|
||||
if (baselineBucketRate > 0) {
|
||||
factor = Math.round(((deviationBucketRate / baselineBucketRate) * 100) / 100);
|
||||
message = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateFactorIncreaseLabel',
|
||||
{
|
||||
defaultMessage: '{factor}x higher',
|
||||
values: {
|
||||
factor,
|
||||
},
|
||||
}
|
||||
);
|
||||
} else {
|
||||
message = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateDocIncreaseLabel',
|
||||
{
|
||||
defaultMessage:
|
||||
'{deviationBucketRate} {deviationBucketRate, plural, one {doc} other {docs}} rate up from 0 in baseline',
|
||||
values: { deviationBucketRate },
|
||||
}
|
||||
);
|
||||
}
|
||||
} else {
|
||||
if (deviationBucketRate > 0) {
|
||||
// For dip, "doc count" refers to the amount of documents in the baseline time range so we use baselineBucketRate
|
||||
factor = Math.round(((baselineBucketRate / deviationBucketRate) * 100) / 100);
|
||||
message = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateFactorDecreaseLabel',
|
||||
{
|
||||
defaultMessage: '{factor}x lower',
|
||||
values: {
|
||||
factor,
|
||||
},
|
||||
}
|
||||
);
|
||||
} else {
|
||||
message = i18n.translate(
|
||||
'xpack.aiops.logRateAnalysis.resultsTableGroups.logRateDocDecreaseLabel',
|
||||
{
|
||||
defaultMessage: 'docs rate down to 0 from {baselineBucketRate} in baseline',
|
||||
values: { baselineBucketRate },
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return { message, factor };
|
||||
}
|
||||
|
||||
export function getBaselineAndDeviationRates(
|
||||
analysisType: typeof LOG_RATE_ANALYSIS_TYPE[keyof typeof LOG_RATE_ANALYSIS_TYPE],
|
||||
baselineBuckets: number,
|
||||
deviationBuckets: number,
|
||||
docCount: number | undefined,
|
||||
bgCount: number | undefined
|
||||
) {
|
||||
let baselineBucketRate;
|
||||
let deviationBucketRate;
|
||||
if (analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE) {
|
||||
if (bgCount !== undefined) {
|
||||
baselineBucketRate = Math.round(bgCount / baselineBuckets);
|
||||
}
|
||||
|
||||
if (docCount !== undefined) {
|
||||
deviationBucketRate = Math.round(docCount / deviationBuckets);
|
||||
}
|
||||
} else {
|
||||
// For dip, the "doc count" refers to the amount of documents in the baseline time range so we set baselineBucketRate
|
||||
if (docCount !== undefined) {
|
||||
baselineBucketRate = Math.round(docCount / baselineBuckets);
|
||||
}
|
||||
|
||||
if (bgCount !== undefined) {
|
||||
deviationBucketRate = Math.round(bgCount / deviationBuckets);
|
||||
}
|
||||
}
|
||||
|
||||
return { baselineBucketRate, deviationBucketRate };
|
||||
}
|
|
@ -21,7 +21,11 @@ import { type SignificantItem, SIGNIFICANT_ITEM_TYPE } from '@kbn/ml-agg-utils';
|
|||
import { getCategoryQuery } from '@kbn/aiops-log-pattern-analysis/get_category_query';
|
||||
import type { FieldStatsServices } from '@kbn/unified-field-list/src/components/field_stats';
|
||||
import { useAppSelector } from '@kbn/aiops-log-rate-analysis/state';
|
||||
import { LOG_RATE_ANALYSIS_TYPE } from '@kbn/aiops-log-rate-analysis';
|
||||
import {
|
||||
getBaselineAndDeviationRates,
|
||||
getLogRateChange,
|
||||
LOG_RATE_ANALYSIS_TYPE,
|
||||
} from '@kbn/aiops-log-rate-analysis';
|
||||
import { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transactions_correlation_impact_label';
|
||||
import { FieldStatsPopover } from '../field_stats_popover';
|
||||
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
|
||||
|
@ -31,7 +35,6 @@ import { useViewInDiscoverAction } from './use_view_in_discover_action';
|
|||
import { useViewInLogPatternAnalysisAction } from './use_view_in_log_pattern_analysis_action';
|
||||
import { useCopyToClipboardAction } from './use_copy_to_clipboard_action';
|
||||
import { MiniHistogram } from '../mini_histogram';
|
||||
import { getBaselineAndDeviationRates, getLogRateChange } from './get_baseline_and_deviation_rates';
|
||||
|
||||
const TRUNCATE_TEXT_LINES = 3;
|
||||
const UNIQUE_COLUMN_WIDTH = '40px';
|
||||
|
@ -162,10 +165,11 @@ export const useColumns = (
|
|||
const loading = useAppSelector((s) => s.logRateAnalysisStream.isRunning);
|
||||
const zeroDocsFallback = useAppSelector((s) => s.logRateAnalysisResults.zeroDocsFallback);
|
||||
const {
|
||||
analysisType,
|
||||
windowParameters,
|
||||
documentStats: { documentCountStats },
|
||||
} = useAppSelector((s) => s.logRateAnalysis);
|
||||
const { currentAnalysisType, currentAnalysisWindowParameters } = useAppSelector(
|
||||
(s) => s.logRateAnalysisResults
|
||||
);
|
||||
|
||||
const isGroupsTable = tableType === LOG_RATE_ANALYSIS_RESULTS_TABLE_TYPE.GROUPS;
|
||||
const interval = documentCountStats?.interval ?? 0;
|
||||
|
@ -181,14 +185,15 @@ export const useColumns = (
|
|||
}, [uiSettings, data, fieldFormats, charts]);
|
||||
|
||||
const buckets = useMemo(() => {
|
||||
if (windowParameters === undefined) return;
|
||||
if (currentAnalysisWindowParameters === undefined) return;
|
||||
|
||||
const { baselineMin, baselineMax, deviationMin, deviationMax } = windowParameters;
|
||||
const { baselineMin, baselineMax, deviationMin, deviationMax } =
|
||||
currentAnalysisWindowParameters;
|
||||
const baselineBuckets = (baselineMax - baselineMin) / interval;
|
||||
const deviationBuckets = (deviationMax - deviationMin) / interval;
|
||||
|
||||
return { baselineBuckets, deviationBuckets };
|
||||
}, [windowParameters, interval]);
|
||||
}, [currentAnalysisWindowParameters, interval]);
|
||||
|
||||
const columnsMap: Record<ColumnNames, EuiBasicTableColumn<SignificantItem>> = useMemo(
|
||||
() => ({
|
||||
|
@ -365,14 +370,15 @@ export const useColumns = (
|
|||
render: (_, { bg_count: bgCount, doc_count: docCount }) => {
|
||||
if (
|
||||
interval === 0 ||
|
||||
windowParameters === undefined ||
|
||||
currentAnalysisType === undefined ||
|
||||
currentAnalysisWindowParameters === undefined ||
|
||||
buckets === undefined ||
|
||||
isGroupsTable
|
||||
)
|
||||
return NOT_AVAILABLE;
|
||||
|
||||
const { baselineBucketRate } = getBaselineAndDeviationRates(
|
||||
analysisType,
|
||||
currentAnalysisType,
|
||||
buckets.baselineBuckets,
|
||||
buckets.deviationBuckets,
|
||||
docCount,
|
||||
|
@ -407,14 +413,15 @@ export const useColumns = (
|
|||
render: (_, { doc_count: docCount, bg_count: bgCount }) => {
|
||||
if (
|
||||
interval === 0 ||
|
||||
windowParameters === undefined ||
|
||||
currentAnalysisType === undefined ||
|
||||
currentAnalysisWindowParameters === undefined ||
|
||||
buckets === undefined ||
|
||||
isGroupsTable
|
||||
)
|
||||
return NOT_AVAILABLE;
|
||||
|
||||
const { deviationBucketRate } = getBaselineAndDeviationRates(
|
||||
analysisType,
|
||||
currentAnalysisType,
|
||||
buckets.baselineBuckets,
|
||||
buckets.deviationBuckets,
|
||||
docCount,
|
||||
|
@ -448,14 +455,15 @@ export const useColumns = (
|
|||
render: ({ doc_count: docCount, bg_count: bgCount }: SignificantItem) => {
|
||||
if (
|
||||
interval === 0 ||
|
||||
windowParameters === undefined ||
|
||||
currentAnalysisType === undefined ||
|
||||
currentAnalysisWindowParameters === undefined ||
|
||||
buckets === undefined ||
|
||||
isGroupsTable
|
||||
)
|
||||
return NOT_AVAILABLE;
|
||||
|
||||
const { baselineBucketRate, deviationBucketRate } = getBaselineAndDeviationRates(
|
||||
analysisType,
|
||||
currentAnalysisType,
|
||||
buckets.baselineBuckets,
|
||||
buckets.deviationBuckets,
|
||||
docCount,
|
||||
|
@ -463,9 +471,9 @@ export const useColumns = (
|
|||
);
|
||||
|
||||
const logRateChange = getLogRateChange(
|
||||
analysisType,
|
||||
baselineBucketRate!,
|
||||
deviationBucketRate!
|
||||
currentAnalysisType,
|
||||
baselineBucketRate,
|
||||
deviationBucketRate
|
||||
);
|
||||
|
||||
return (
|
||||
|
@ -473,7 +481,7 @@ export const useColumns = (
|
|||
<EuiIcon
|
||||
size="s"
|
||||
color="subdued"
|
||||
type={analysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE ? 'sortUp' : 'sortDown'}
|
||||
type={currentAnalysisType === LOG_RATE_ANALYSIS_TYPE.SPIKE ? 'sortUp' : 'sortDown'}
|
||||
className="eui-alignTop"
|
||||
/>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import {
|
||||
resetAll,
|
||||
resetResults,
|
||||
resetErrors,
|
||||
resetGroups,
|
||||
} from '@kbn/aiops-log-rate-analysis/api/stream_reducer';
|
||||
|
@ -24,7 +24,7 @@ export const overridesHandlerFactory =
|
|||
() => {
|
||||
if (!requestBody.overrides) {
|
||||
logDebugMessage('Full Reset.');
|
||||
responseStream.push(resetAll());
|
||||
responseStream.push(resetResults());
|
||||
} else {
|
||||
logDebugMessage('Reset Errors.');
|
||||
responseStream.push(resetErrors());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue