From 743cce0a65ff62357025875acf08bc97db66891b Mon Sep 17 00:00:00 2001 From: Karl Godard Date: Fri, 6 May 2022 09:17:16 -0700 Subject: [PATCH] Sessions tab improvements (#131583) * session tab query modified query all events, not just entry leaders. solves a few problems wrt to query ability. default columns modified and display names provided for each * snapshot updated * readded test * Default sort set to process.entry_leader.start desc * sessions tab timeline id changed to cache bust localstorage for table column configs * missed a couple spots for session tab timeline id update Co-authored-by: mitodrummer --- .../common/types/timeline/index.ts | 2 +- .../__snapshots__/index.test.tsx.snap | 22 +++------ .../sessions_viewer/cell_renderer.tsx | 25 ---------- .../sessions_viewer/default_headers.ts | 47 +++++++++++------- .../components/sessions_viewer/index.test.tsx | 3 +- .../components/sessions_viewer/index.tsx | 19 +++---- .../sessions_viewer/translations.ts | 49 +++++++++++++++++++ .../timelines/common/types/timeline/index.ts | 2 +- .../timelines/public/store/t_grid/types.ts | 2 +- .../server/search_strategy/timeline/index.ts | 10 ++-- 10 files changed, 99 insertions(+), 82 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/common/components/sessions_viewer/cell_renderer.tsx diff --git a/x-pack/plugins/security_solution/common/types/timeline/index.ts b/x-pack/plugins/security_solution/common/types/timeline/index.ts index caeeaa0c17bee..cb03788aa17ba 100644 --- a/x-pack/plugins/security_solution/common/types/timeline/index.ts +++ b/x-pack/plugins/security_solution/common/types/timeline/index.ts @@ -318,7 +318,7 @@ export enum TimelineId { usersPageExternalAlerts = 'users-page-external-alerts', hostsPageEvents = 'hosts-page-events', hostsPageExternalAlerts = 'hosts-page-external-alerts', - hostsPageSessions = 'hosts-page-sessions', + hostsPageSessions = 'hosts-page-sessions-v2', // the v2 is to cache bust localstorage settings as default columns were reworked. detectionsRulesDetailsPage = 'detections-rules-details-page', detectionsPage = 'detections-page', networkPageExternalAlerts = 'network-page-external-alerts', diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/__snapshots__/index.test.tsx.snap b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/__snapshots__/index.test.tsx.snap index 32268e2f21e7f..9d32d2c23b18b 100644 --- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/__snapshots__/index.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/__snapshots__/index.test.tsx.snap @@ -70,34 +70,28 @@ exports[`SessionsView renders correctly against snapshot 1`] = `
- hosts-page-sessions + hosts-page-sessions-v2
- process.start + Started
- process.end + Executable
- process.executable + User
- user.name + Interactive
- process.interactive + Hostname
- process.pid + Type
- host.hostname -
-
- process.entry_leader.entry_meta.type -
-
- process.entry_leader.entry_meta.source.ip + Source IP
diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/cell_renderer.tsx b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/cell_renderer.tsx deleted file mode 100644 index 088935b32ce34..0000000000000 --- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/cell_renderer.tsx +++ /dev/null @@ -1,25 +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 React from 'react'; -import { CellValueElementProps } from '../../../timelines/components/timeline/cell_rendering'; -import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer'; -import { getEmptyValue } from '../empty_value'; -import { MAPPED_PROCESS_END_COLUMN } from './default_headers'; - -const hasEcsDataEndEventAction = (ecsData: CellValueElementProps['ecsData']) => { - return ecsData?.event?.action?.includes('end'); -}; - -export const CellRenderer: React.FC = (props: CellValueElementProps) => { - // We only want to render process.end for event.actions of type 'end' - if (props.columnId === MAPPED_PROCESS_END_COLUMN && !hasEcsDataEndEventAction(props.ecsData)) { - return <>{getEmptyValue()}; - } - - return ; -}; diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts index d73ab1b690f61..4c045e358e1d6 100644 --- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts +++ b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/default_headers.ts @@ -10,50 +10,52 @@ import { defaultColumnHeaderType } from '../../../timelines/components/timeline/ import { DEFAULT_DATE_COLUMN_MIN_WIDTH } from '../../../timelines/components/timeline/body/constants'; import { SubsetTimelineModel } from '../../../timelines/store/timeline/model'; import { timelineDefaults } from '../../../timelines/store/timeline/defaults'; - -// Using @timestamp as an way of getting the end time of the process. (Currently endpoint doesn't populate process.end) -// @timestamp of an event.action with value of "end" is what we consider that to be the end time of the process -// Current action are: 'start', 'exec', 'end', so we might have up to three events per process. -export const MAPPED_PROCESS_END_COLUMN = '@timestamp'; +import { + COLUMN_SESSION_START, + COLUMN_EXECUTABLE, + COLUMN_ENTRY_USER, + COLUMN_INTERACTIVE, + COLUMN_HOST_NAME, + COLUMN_ENTRY_TYPE, + COLUMN_ENTRY_IP, +} from './translations'; export const sessionsHeaders: ColumnHeaderOptions[] = [ { columnHeaderType: defaultColumnHeaderType, - id: 'process.start', + id: 'process.entry_leader.start', initialWidth: DEFAULT_DATE_COLUMN_MIN_WIDTH, + display: COLUMN_SESSION_START, }, { columnHeaderType: defaultColumnHeaderType, - id: MAPPED_PROCESS_END_COLUMN, - display: 'process.end', + id: 'process.entry_leader.executable', + display: COLUMN_EXECUTABLE, }, { columnHeaderType: defaultColumnHeaderType, - id: 'process.executable', + id: 'process.entry_leader.user.name', + display: COLUMN_ENTRY_USER, }, { columnHeaderType: defaultColumnHeaderType, - id: 'user.name', - }, - { - columnHeaderType: defaultColumnHeaderType, - id: 'process.interactive', - }, - { - columnHeaderType: defaultColumnHeaderType, - id: 'process.pid', + id: 'process.entry_leader.interactive', + display: COLUMN_INTERACTIVE, }, { columnHeaderType: defaultColumnHeaderType, id: 'host.hostname', + display: COLUMN_HOST_NAME, }, { columnHeaderType: defaultColumnHeaderType, id: 'process.entry_leader.entry_meta.type', + display: COLUMN_ENTRY_TYPE, }, { - columnHeaderType: defaultColumnHeaderType, id: 'process.entry_leader.entry_meta.source.ip', + columnHeaderType: defaultColumnHeaderType, + display: COLUMN_ENTRY_IP, }, ]; @@ -62,4 +64,11 @@ export const sessionsDefaultModel: SubsetTimelineModel = { columns: sessionsHeaders, defaultColumns: sessionsHeaders, excludedRowRendererIds: Object.values(RowRendererId), + sort: [ + { + columnId: 'process.entry_leader.start', + columnType: 'date', + sortDirection: 'desc', + }, + ], }; diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.test.tsx index 043a2aa378427..5280f298ba99e 100644 --- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.test.tsx @@ -109,10 +109,11 @@ describe('SessionsView', () => { expect(wrapper.getByTestId(`${TEST_PREFIX}:startDate`)).toHaveTextContent(startDate); expect(wrapper.getByTestId(`${TEST_PREFIX}:endDate`)).toHaveTextContent(endDate); expect(wrapper.getByTestId(`${TEST_PREFIX}:timelineId`)).toHaveTextContent( - 'hosts-page-sessions' + 'hosts-page-sessions-v2' ); }); }); + it('passes in the right filters to TGrid', async () => { render( diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.tsx b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.tsx index 6834553a5eee8..4d89b969e5c17 100644 --- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/index.tsx @@ -12,7 +12,7 @@ import { ESBoolQuery } from '../../../../common/typed_json'; import { StatefulEventsViewer } from '../events_viewer'; import { sessionsDefaultModel } from './default_headers'; import { defaultRowRenderers } from '../../../timelines/components/timeline/body/renderers'; -import { CellRenderer } from './cell_renderer'; +import { DefaultCellRenderer } from '../../../timelines/components/timeline/cell_rendering/default_cell_renderer'; import * as i18n from './translations'; import { SourcererScopeName } from '../../store/sourcerer/model'; import { getDefaultControlColumn } from '../../../timelines/components/timeline/body/control_columns'; @@ -24,15 +24,8 @@ export const defaultSessionsFilter: Required> = { bool: { filter: [ { - bool: { - should: [ - { - match: { - 'process.entry_leader.same_as_process': true, - }, - }, - ], - minimum_should_match: 1, + exists: { + field: 'process.entry_leader.entity_id', // to exclude any records which have no entry_leader.entity_id }, }, ], @@ -41,10 +34,10 @@ export const defaultSessionsFilter: Required> = { meta: { alias: null, disabled: false, - key: 'process.entry_leader.same_as_process', + key: 'process.entry_leader.entity_id', negate: false, params: {}, - type: 'boolean', + type: 'string', }, }; @@ -95,7 +88,7 @@ const SessionsViewComponent: React.FC = ({ entityType={entityType} id={timelineId} leadingControlColumns={leadingControlColumns} - renderCellValue={CellRenderer} + renderCellValue={DefaultCellRenderer} rowRenderers={defaultRowRenderers} scopeId={SourcererScopeName.default} start={startDate} diff --git a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts index 606ae2b46fc6a..ea35892f3a2f9 100644 --- a/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/sessions_viewer/translations.ts @@ -20,3 +20,52 @@ export const SINGLE_COUNT_OF_SESSIONS = i18n.translate( defaultMessage: 'session', } ); + +export const COLUMN_SESSION_START = i18n.translate( + 'xpack.securitySolution.sessionsView.columnSessionStart', + { + defaultMessage: 'Started', + } +); + +export const COLUMN_EXECUTABLE = i18n.translate( + 'xpack.securitySolution.sessionsView.columnExecutable', + { + defaultMessage: 'Executable', + } +); + +export const COLUMN_ENTRY_USER = i18n.translate( + 'xpack.securitySolution.sessionsView.columnEntryUser', + { + defaultMessage: 'User', + } +); + +export const COLUMN_INTERACTIVE = i18n.translate( + 'xpack.securitySolution.sessionsView.columnInteractive', + { + defaultMessage: 'Interactive', + } +); + +export const COLUMN_HOST_NAME = i18n.translate( + 'xpack.securitySolution.sessionsView.columnHostName', + { + defaultMessage: 'Hostname', + } +); + +export const COLUMN_ENTRY_TYPE = i18n.translate( + 'xpack.securitySolution.sessionsView.columnEntryType', + { + defaultMessage: 'Type', + } +); + +export const COLUMN_ENTRY_IP = i18n.translate( + 'xpack.securitySolution.sessionsView.columnEntrySourceIp', + { + defaultMessage: 'Source IP', + } +); diff --git a/x-pack/plugins/timelines/common/types/timeline/index.ts b/x-pack/plugins/timelines/common/types/timeline/index.ts index 867264fa81546..528c6e4293cf4 100644 --- a/x-pack/plugins/timelines/common/types/timeline/index.ts +++ b/x-pack/plugins/timelines/common/types/timeline/index.ts @@ -314,7 +314,7 @@ export enum TimelineId { usersPageExternalAlerts = 'users-page-external-alerts', hostsPageEvents = 'hosts-page-events', hostsPageExternalAlerts = 'hosts-page-external-alerts', - hostsPageSessions = 'hosts-page-sessions', + hostsPageSessions = 'hosts-page-sessions-v2', detectionsRulesDetailsPage = 'detections-rules-details-page', detectionsPage = 'detections-page', networkPageExternalAlerts = 'network-page-external-alerts', diff --git a/x-pack/plugins/timelines/public/store/t_grid/types.ts b/x-pack/plugins/timelines/public/store/t_grid/types.ts index c4627b3accd71..8e0b7e995dbcd 100644 --- a/x-pack/plugins/timelines/public/store/t_grid/types.ts +++ b/x-pack/plugins/timelines/public/store/t_grid/types.ts @@ -46,7 +46,7 @@ export enum TimelineId { usersPageExternalAlerts = 'users-page-external-alerts', hostsPageEvents = 'hosts-page-events', hostsPageExternalAlerts = 'hosts-page-external-alerts', - hostsPageSessions = 'hosts-page-sessions', + hostsPageSessions = 'hosts-page-sessions-v2', detectionsRulesDetailsPage = 'detections-rules-details-page', detectionsPage = 'detections-page', networkPageExternalAlerts = 'network-page-external-alerts', diff --git a/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts index 980f19ac2950c..d450daadf4689 100644 --- a/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts +++ b/x-pack/plugins/timelines/server/search_strategy/timeline/index.ts @@ -209,17 +209,13 @@ const timelineSessionsSearchStrategy = ({ }; const collapse = { - field: 'process.entity_id', - inner_hits: { - name: 'last_event', - size: 1, - sort: [{ '@timestamp': 'desc' }], - }, + field: 'process.entry_leader.entity_id', }; + const aggs = { total: { cardinality: { - field: 'process.entity_id', + field: 'process.entry_leader.entity_id', }, }, };