Skip to content

Commit

Permalink
[ML] Explain Log Rate Spikes: Support WindowParameters for `autoAna…
Browse files Browse the repository at this point in the history
…lysisStart`. (#159111)

To allow for more fine grained control of the baseline and deviation
time ranges for `autoAnalysisStart` this PR allows to pass in a
`WindowParameters` object as an alternative to the plain timestamp. When
more useful metadata is available this might lead to better selections
then the default one provided by `getWindowParameters`.
  • Loading branch information
walterra authored Jun 7, 2023
1 parent 34ada8a commit 6b99a51
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 23 deletions.
12 changes: 12 additions & 0 deletions x-pack/packages/ml/aiops_utils/src/get_window_parameters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* 2.0.
*/

import { isPopulatedObject } from '@kbn/ml-is-populated-object';

/**
* Time range definition for baseline and deviation to be used by spike log analysis.
*
Expand Down Expand Up @@ -35,6 +37,16 @@ export interface WindowParameters {
deviationMax: number;
}

/**
* Type guard for WindowParameters
*
* @param {unknown} arg - The argument to be checked.
* @returns {arg is WindowParameters}
*/
export const isWindowParameters = (arg: unknown): arg is WindowParameters =>
isPopulatedObject(arg, ['baselineMin', 'baselineMax', 'deviationMin', 'deviationMax']) &&
Object.values(arg).every((d) => typeof d === 'number');

/**
* Given a point in time (e.g. where a user clicks), use simple heuristics to compute:
*
Expand Down
1 change: 1 addition & 0 deletions x-pack/packages/ml/aiops_utils/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@kbn/logging",
"@kbn/core-http-server",
"@kbn/core-http-common",
"@kbn/ml-is-populated-object",
],
"exclude": [
"target/**/*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ declare global {
}
}

interface TimeFilterRange {
from: number;
to: number;
}

export interface DocumentCountChartPoint {
time: number | string;
value: number;
Expand All @@ -57,7 +62,7 @@ interface DocumentCountChartProps {
chartPointsSplitLabel: string;
isBrushCleared: boolean;
/* Timestamp for start of initial analysis */
autoAnalysisStart?: number;
autoAnalysisStart?: number | WindowParameters;
}

const SPEC_ID = 'document_count';
Expand Down Expand Up @@ -186,10 +191,10 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = ({
}, [timeRangeEarliest, timeRangeLatest, interval]);

const timefilterUpdateHandler = useCallback(
(ranges: { from: number; to: number }) => {
(range: TimeFilterRange) => {
data.query.timefilter.timefilter.setTime({
from: moment(ranges.from).toISOString(),
to: moment(ranges.to).toISOString(),
from: moment(range.from).toISOString(),
to: moment(range.to).toISOString(),
mode: 'absolute',
});
},
Expand All @@ -215,26 +220,28 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = ({
>();

const triggerAnalysis = useCallback(
(startRange: number) => {
const range = {
from: startRange,
to: startRange + interval,
};
(startRange: number | WindowParameters) => {
if (viewMode === VIEW_MODE.ZOOM && typeof startRange === 'number') {
const range: TimeFilterRange = {
from: startRange,
to: startRange + interval,
};

if (viewMode === VIEW_MODE.ZOOM) {
timefilterUpdateHandler(range);
} else {
} else if (viewMode === VIEW_MODE.BRUSH) {
if (
typeof startRange === 'number' &&
originalWindowParameters === undefined &&
windowParameters === undefined &&
adjustedChartPoints !== undefined
) {
const wp = getWindowParameters(
startRange + interval / 2,
timeRangeEarliest,
timeRangeLatest + interval
);
const wp =
typeof startRange === 'number'
? getWindowParameters(
startRange + interval / 2,
timeRangeEarliest,
timeRangeLatest + interval
)
: startRange;
const wpSnap = getSnappedWindowParameters(wp, snapTimestamps);
setOriginalWindowParameters(wpSnap);
setWindowParameters(wpSnap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface DocumentCountContentProps {
totalCount: number;
sampleProbability: number;
windowParameters?: WindowParameters;
incomingInitialAnalysisStart?: number;
incomingInitialAnalysisStart?: number | WindowParameters;
}

export const DocumentCountContent: FC<DocumentCountContentProps> = ({
Expand All @@ -48,9 +48,9 @@ export const DocumentCountContent: FC<DocumentCountContentProps> = ({
incomingInitialAnalysisStart,
}) => {
const [isBrushCleared, setIsBrushCleared] = useState(true);
const [initialAnalysisStart, setInitialAnalysisStart] = useState<number | undefined>(
incomingInitialAnalysisStart
);
const [initialAnalysisStart, setInitialAnalysisStart] = useState<
number | WindowParameters | undefined
>(incomingInitialAnalysisStart);

useEffect(() => {
setIsBrushCleared(windowParameters === undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export interface ExplainLogRateSpikesContentProps {
dataView: DataView;
setGlobalState?: (params: Dictionary<unknown>) => void;
/** Timestamp for the start of the range for initial analysis */
initialAnalysisStart?: number;
initialAnalysisStart?: number | WindowParameters;
timeRange?: { min: Moment; max: Moment };
/** Elasticsearch query to pass to analysis endpoint */
esSearchQuery?: estypes.QueryDslQueryContainer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';

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

import type { WindowParameters } from '@kbn/aiops-utils';
import { i18n } from '@kbn/i18n';
import type { DataView } from '@kbn/data-views-plugin/public';
import { StorageContextProvider } from '@kbn/ml-local-storage';
Expand Down Expand Up @@ -39,7 +40,7 @@ export interface ExplainLogRateSpikesContentWrapperProps {
/** On global timefilter update */
setGlobalState?: any;
/** Timestamp for start of initial analysis */
initialAnalysisStart?: number;
initialAnalysisStart?: number | WindowParameters;
timeRange?: { min: Moment; max: Moment };
/** Elasticsearch query to pass to analysis endpoint */
esSearchQuery?: estypes.QueryDslQueryContainer;
Expand Down

0 comments on commit 6b99a51

Please sign in to comment.