mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[ML] Explain Log Rate Spikes: Support WindowParameters
for autoAnalysisStart
. (#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`.
This commit is contained in:
parent
34ada8a9a6
commit
6b99a51824
6 changed files with 44 additions and 23 deletions
|
@ -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.
|
||||
*
|
||||
|
@ -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:
|
||||
*
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
"@kbn/logging",
|
||||
"@kbn/core-http-server",
|
||||
"@kbn/core-http-common",
|
||||
"@kbn/ml-is-populated-object",
|
||||
],
|
||||
"exclude": [
|
||||
"target/**/*",
|
||||
|
|
|
@ -41,6 +41,11 @@ declare global {
|
|||
}
|
||||
}
|
||||
|
||||
interface TimeFilterRange {
|
||||
from: number;
|
||||
to: number;
|
||||
}
|
||||
|
||||
export interface DocumentCountChartPoint {
|
||||
time: number | string;
|
||||
value: number;
|
||||
|
@ -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';
|
||||
|
@ -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',
|
||||
});
|
||||
},
|
||||
|
@ -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);
|
||||
|
|
|
@ -33,7 +33,7 @@ export interface DocumentCountContentProps {
|
|||
totalCount: number;
|
||||
sampleProbability: number;
|
||||
windowParameters?: WindowParameters;
|
||||
incomingInitialAnalysisStart?: number;
|
||||
incomingInitialAnalysisStart?: number | WindowParameters;
|
||||
}
|
||||
|
||||
export const DocumentCountContent: FC<DocumentCountContentProps> = ({
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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';
|
||||
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue