Skip to content

Commit

Permalink
[8.x] feat(investigation): Add eventTypes filter on the API (#202829) (
Browse files Browse the repository at this point in the history
…#204089)

# Backport

This will backport the following commits from `main` to `8.x`:
- [feat(investigation): Add eventTypes filter on the API
(#202829)](#202829)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Kevin
Delemme","email":"kevin.delemme@elastic.co"},"sourceCommit":{"committedDate":"2024-12-12T16:49:34Z","message":"feat(investigation):
Add eventTypes filter on the API
(#202829)","sha":"2ab38a3664cf7f103ac1a57f664c736a8e3d495b","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","backport:prev-minor","ci:project-deploy-observability","Team:obs-ux-management","v8.18.0"],"title":"feat(investigation):
Add eventTypes filter on the
API","number":202829,"url":"https://github.com/elastic/kibana/pull/202829","mergeCommit":{"message":"feat(investigation):
Add eventTypes filter on the API
(#202829)","sha":"2ab38a3664cf7f103ac1a57f664c736a8e3d495b"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/202829","number":202829,"mergeCommit":{"message":"feat(investigation):
Add eventTypes filter on the API
(#202829)","sha":"2ab38a3664cf7f103ac1a57f664c736a8e3d495b"}},{"branch":"8.x","label":"v8.18.0","branchLabelMappingKey":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Kevin Delemme <kevin.delemme@elastic.co>
  • Loading branch information
kibanamachine and kdelemme authored Dec 12, 2024
1 parent 7e15aa9 commit f5e047c
Show file tree
Hide file tree
Showing 36 changed files with 536 additions and 437 deletions.
19 changes: 0 additions & 19 deletions packages/kbn-investigation-shared/src/rest_specs/event.ts

This file was deleted.

16 changes: 14 additions & 2 deletions packages/kbn-investigation-shared/src/rest_specs/get_events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*/

import { z } from '@kbn/zod';
import { eventResponseSchema } from './event';
import { eventTypeSchema, eventSchema } from '../schema';

const getEventsParamsSchema = z
.object({
Expand All @@ -17,12 +17,24 @@ const getEventsParamsSchema = z
rangeFrom: z.string(),
rangeTo: z.string(),
filter: z.string(),
eventTypes: z.string().transform((val, ctx) => {
const eventTypes = val.split(',');
const hasInvalidType = eventTypes.some((eventType) => !eventTypeSchema.parse(eventType));
if (hasInvalidType) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'Invalid event type',
});
return z.NEVER;
}
return val.split(',').map((v) => eventTypeSchema.parse(v));
}),
})
.partial(),
})
.partial();

const getEventsResponseSchema = z.array(eventResponseSchema);
const getEventsResponseSchema = z.array(eventSchema);

type GetEventsParams = z.infer<typeof getEventsParamsSchema.shape.query>;
type GetEventsResponse = z.output<typeof getEventsResponseSchema>;
Expand Down
2 changes: 0 additions & 2 deletions packages/kbn-investigation-shared/src/rest_specs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ export type * from './investigation_note';
export type * from './update';
export type * from './update_item';
export type * from './update_note';
export type * from './event';
export type * from './get_events';
export type * from './entity';
export type * from './get_entities';
Expand All @@ -48,7 +47,6 @@ export * from './investigation_note';
export * from './update';
export * from './update_item';
export * from './update_note';
export * from './event';
export * from './get_events';
export * from './entity';
export * from './get_entities';
33 changes: 19 additions & 14 deletions packages/kbn-investigation-shared/src/schema/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@ const eventTypeSchema = z.union([
z.literal('anomaly'),
]);

const sourceSchema = z.record(z.string(), z.any());

const annotationEventSchema = z.object({
eventType: z.literal('annotation'),
id: z.string(),
title: z.string(),
description: z.string(),
timestamp: z.number(),
source: sourceSchema.optional(),
annotationType: z.string().optional(),
});

Expand All @@ -31,21 +38,19 @@ const alertStatusSchema = z.union([

const alertEventSchema = z.object({
eventType: z.literal('alert'),
id: z.string(),
title: z.string(),
description: z.string(),
timestamp: z.number(),
source: sourceSchema.optional(),
alertStatus: alertStatusSchema,
});

const sourceSchema = z.record(z.string(), z.any());
const eventSchema = z.discriminatedUnion('eventType', [annotationEventSchema, alertEventSchema]);

type EventResponse = z.output<typeof eventSchema>;
type AlertEventResponse = z.output<typeof alertEventSchema>;
type AnnotationEventResponse = z.output<typeof annotationEventSchema>;

const eventSchema = z.intersection(
z.object({
id: z.string(),
title: z.string(),
description: z.string(),
timestamp: z.number(),
eventType: eventTypeSchema,
source: sourceSchema.optional(),
}),
z.discriminatedUnion('eventType', [annotationEventSchema, alertEventSchema])
);

export { eventSchema };
export type { EventResponse, AlertEventResponse, AnnotationEventResponse };
export { eventSchema, eventTypeSchema, alertEventSchema, annotationEventSchema };
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,12 @@ export const investigationKeys = {
userProfiles: (profileIds: Set<string>) =>
[...investigationKeys.all, 'userProfiles', ...profileIds] as const,
tags: () => [...investigationKeys.all, 'tags'] as const,
events: (rangeFrom?: string, rangeTo?: string, filter?: string) =>
[...investigationKeys.all, 'events', rangeFrom, rangeTo, filter] as const,
events: (params: {
rangeFrom?: string;
rangeTo?: string;
filter?: string;
eventTypes?: string[];
}) => [...investigationKeys.all, 'events', params] as const,
stats: () => [...investigationKeys.all, 'stats'] as const,
lists: () => [...investigationKeys.all, 'list'] as const,
list: (params: { page: number; perPage: number; search?: string; filter?: string }) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import {
CreateInvestigationNoteParams,
CreateInvestigationNoteResponse,
} from '@kbn/investigation-shared';
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useKibana } from './use_kibana';
import { investigationKeys } from './query_key_factory';

type ServerError = IHttpFetchError<ResponseErrorBody>;

Expand All @@ -23,6 +24,7 @@ export function useAddInvestigationNote() {
notifications: { toasts },
},
} = useKibana();
const queryClient = useQueryClient();

return useMutation<
CreateInvestigationNoteResponse,
Expand All @@ -39,7 +41,12 @@ export function useAddInvestigationNote() {
);
},
{
onSuccess: (response, {}) => {
onSuccess: (_, { investigationId }) => {
queryClient.invalidateQueries({
queryKey: investigationKeys.detailNotes(investigationId),
exact: false,
});

toasts.addSuccess(
i18n.translate('xpack.investigateApp.addInvestigationNote.successMessage', {
defaultMessage: 'Note saved',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@
*/

import { IHttpFetchError, ResponseErrorBody } from '@kbn/core/public';
import { useMutation } from '@tanstack/react-query';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { i18n } from '@kbn/i18n';
import { useKibana } from './use_kibana';
import { investigationKeys } from './query_key_factory';

type ServerError = IHttpFetchError<ResponseErrorBody>;

export function useDeleteInvestigationNote() {
const queryClient = useQueryClient();
const {
core: {
http,
Expand All @@ -34,7 +36,12 @@ export function useDeleteInvestigationNote() {
);
},
{
onSuccess: (response, {}) => {
onSuccess: (response, { investigationId }) => {
queryClient.invalidateQueries({
queryKey: investigationKeys.detailNotes(investigationId),
exact: false,
});

toasts.addSuccess(
i18n.translate('xpack.investigateApp.useDeleteInvestigationNote.successMessage', {
defaultMessage: 'Note deleted',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function useFetchAlert({ investigation }: UseFetchAlertParams): UseFetchA
});
},
staleTime: 60 * 1000,
retry: false,
refetchOnWindowFocus: false,
onError: (error: Error) => {
toasts.addError(error, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ export function useFetchAllInvestigationStats(): Response {
};
},
retry: false,
cacheTime: 600 * 1000, // 10 minutes
staleTime: 0,
staleTime: 15 * 1000,
onError: (error: Error) => {
toasts.addError(error, {
title: i18n.translate('xpack.investigateApp.useFetchAllInvestigationStats.errorTitle', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ export function useFetchAllInvestigationTags(): Response {
signal,
});
},
cacheTime: 600 * 1000, // 10_minutes
staleTime: 0,
staleTime: 15 * 1000,
refetchOnWindowFocus: false,
retry: false,
onError: (error: Error) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ export function useFetchEntities({
});
},
refetchOnWindowFocus: false,
onError: (error: Error) => {
// ignore error
},
retry: false,
enabled: Boolean(investigationId && (serviceName || hostName || containerId)),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,14 @@
*/

import { i18n } from '@kbn/i18n';
import { useQuery } from '@tanstack/react-query';
import { GetEventsResponse } from '@kbn/investigation-shared';
import { useQuery } from '@tanstack/react-query';
import { isArray } from 'lodash';
import { investigationKeys } from './query_key_factory';
import { useKibana } from './use_kibana';

export interface Response {
isInitialLoading: boolean;
isLoading: boolean;
isRefetching: boolean;
isSuccess: boolean;
isError: boolean;
data?: GetEventsResponse;
}
Expand All @@ -24,10 +22,12 @@ export function useFetchEvents({
rangeFrom,
rangeTo,
filter,
eventTypes,
}: {
rangeFrom?: string;
rangeTo?: string;
filter?: string;
eventTypes?: string[];
}): Response {
const {
core: {
Expand All @@ -36,21 +36,20 @@ export function useFetchEvents({
},
} = useKibana();

const { isInitialLoading, isLoading, isError, isSuccess, isRefetching, data } = useQuery({
queryKey: investigationKeys.events(rangeFrom, rangeTo, filter),
const { isLoading, isError, data } = useQuery({
queryKey: investigationKeys.events({ rangeFrom, rangeTo, filter, eventTypes }),
queryFn: async ({ signal }) => {
return await http.get<GetEventsResponse>(`/api/observability/events`, {
return http.get<GetEventsResponse>(`/api/observability/events`, {
query: {
rangeFrom,
rangeTo,
filter,
...(isArray(eventTypes) && eventTypes.length > 0 && { eventTypes: eventTypes.join(',') }),
},
version: '2023-10-31',
signal,
});
},
cacheTime: 600 * 1000, // 10_minutes
staleTime: 0,
refetchOnWindowFocus: false,
retry: false,
onError: (error: Error) => {
Expand All @@ -64,10 +63,7 @@ export function useFetchEvents({

return {
data,
isInitialLoading,
isLoading,
isRefetching,
isSuccess,
isError,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,6 @@ export function useFetchInvestigationList({
retry: false,
refetchInterval: 60 * 1000,
refetchOnWindowFocus: false,
cacheTime: 600 * 1000, // 10 minutes
staleTime: 0,
onError: (error: Error) => {
toasts.addError(error, {
title: i18n.translate('xpack.investigateApp.useFetchInvestigationList.errorTitle', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,16 @@ export function useUpdateInvestigationNote() {
},
{
onSuccess: (response, { investigationId }) => {
queryClient.invalidateQueries({
queryKey: investigationKeys.detailNotes(investigationId),
exact: false,
});

toasts.addSuccess(
i18n.translate('xpack.investigateApp.useUpdateInvestigationNote.successMessage', {
defaultMessage: 'Note updated',
})
);
queryClient.invalidateQueries({ queryKey: investigationKeys.detailNotes(investigationId) });
},
onError: (error, {}, context) => {
toasts.addError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import { css } from '@emotion/css';
import { ESQLLangEditor } from '@kbn/esql/public';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { AddFromLibraryButton } from '../add_from_library_button';
import { useInvestigation } from '../../contexts/investigation_context';
import { AddFromLibraryButton } from '../add_from_library_button';
import { EsqlWidgetPreview } from './esql_widget_preview';

const emptyPreview = css`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { i18n } from '@kbn/i18n';
import type { RootCauseAnalysisEvent } from '@kbn/observability-ai-server/root_cause_analysis';
import { EcsFieldsResponse } from '@kbn/rule-registry-plugin/common';
import React, { useState, useRef, useEffect } from 'react';
import { omit } from 'lodash';
import {
ALERT_FLAPPING_HISTORY,
ALERT_RULE_EXECUTION_TIMESTAMP,
Expand All @@ -17,17 +16,19 @@ import {
EVENT_KIND,
} from '@kbn/rule-registry-plugin/common/technical_rule_data_field_names';
import { isRequestAbortedError } from '@kbn/server-route-repository-client';
import { omit } from 'lodash';
import React, { useEffect, useRef, useState } from 'react';
import { useKibana } from '../../../../hooks/use_kibana';
import { useInvestigation } from '../../contexts/investigation_context';
import { useUpdateInvestigation } from '../../../../hooks/use_update_investigation';
import { useInvestigation } from '../../contexts/investigation_context';

export interface InvestigationContextualInsight {
key: string;
description: string;
data: unknown;
}

export function AssistantHypothesis({ investigationId }: { investigationId: string }) {
export function AssistantHypothesis() {
const {
alert,
globalParams: { timeRange },
Expand Down Expand Up @@ -87,7 +88,7 @@ export function AssistantHypothesis({ investigationId }: { investigationId: stri
.stream('POST /internal/observability/investigation/root_cause_analysis', {
params: {
body: {
investigationId,
investigationId: investigation!.id,
connectorId,
context: `The user is investigating an alert for the ${serviceName} service,
and wants to find the root cause. Here is the alert:
Expand Down Expand Up @@ -156,7 +157,7 @@ export function AssistantHypothesis({ investigationId }: { investigationId: stri
setEvents([]);
if (investigation?.rootCauseAnalysis) {
updateInvestigation({
investigationId,
investigationId: investigation!.id,
payload: {
rootCauseAnalysis: {
events: [],
Expand Down
Loading

0 comments on commit f5e047c

Please sign in to comment.