From e45718d0ff5bb76786a537cd1dd713da76dab755 Mon Sep 17 00:00:00 2001 From: Kerry Gallagher <471693+Kerry350@users.noreply.github.com> Date: Thu, 4 Mar 2021 19:50:14 +0000 Subject: [PATCH] [Logs UI] Fix log stream data fetching (#93201) * Use ReplaySubject and amend date comparisons * Assess date range expressions separately * Only add dataset filter to view in stream links if one exists --- .../logs/log_position/log_position_state.ts | 13 +++++++++++-- .../log_stream/use_fetch_log_entries_around.ts | 4 ++-- .../sections/anomalies/log_entry_example.tsx | 12 ++++++++---- .../pages/logs/stream/page_logs_content.tsx | 15 +++++++++------ 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts b/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts index 56f64b012fa0..59b7d0043145 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_position/log_position_state.ts @@ -21,6 +21,7 @@ interface DateRange { startTimestamp: number; endTimestamp: number; timestampsLastUpdate: number; + lastCompleteDateRangeExpressionUpdate: number; } interface VisiblePositions { @@ -46,6 +47,7 @@ export interface LogPositionStateParams { startTimestamp: number | null; endTimestamp: number | null; timestampsLastUpdate: number; + lastCompleteDateRangeExpressionUpdate: number; } export interface LogPositionCallbacks { @@ -121,6 +123,7 @@ export const useLogPositionState: () => LogPositionStateParams & LogPositionCall startTimestamp: datemathToEpochMillis(DEFAULT_DATE_RANGE.startDateExpression)!, endTimestamp: datemathToEpochMillis(DEFAULT_DATE_RANGE.endDateExpression, 'up')!, timestampsLastUpdate: Date.now(), + lastCompleteDateRangeExpressionUpdate: Date.now(), }); useEffect(() => { @@ -171,12 +174,18 @@ export const useLogPositionState: () => LogPositionStateParams & LogPositionCall jumpToTargetPosition(null); } - setDateRange({ + setDateRange((prevState) => ({ ...newDateRange, startTimestamp: nextStartTimestamp, endTimestamp: nextEndTimestamp, timestampsLastUpdate: Date.now(), - }); + // NOTE: Complete refers to the last time an update was requested with both expressions. These require a full refresh (unless streaming). Timerange expansion + // and pagination however do not. + lastCompleteDateRangeExpressionUpdate: + 'startDateExpression' in newDateRange && 'endDateExpression' in newDateRange + ? Date.now() + : prevState.lastCompleteDateRangeExpressionUpdate, + })); }, [setDateRange, dateRange, targetPosition] ); diff --git a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts index d96cb7f2b713..40a887686cb5 100644 --- a/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts +++ b/x-pack/plugins/infra/public/containers/logs/log_stream/use_fetch_log_entries_around.ts @@ -6,7 +6,7 @@ */ import { useCallback } from 'react'; -import { combineLatest, Observable, Subject } from 'rxjs'; +import { combineLatest, Observable, ReplaySubject } from 'rxjs'; import { last, map, startWith, switchMap } from 'rxjs/operators'; import { LogSourceColumnConfiguration } from '../../../../common/http_api/log_sources'; import { LogEntryCursor } from '../../../../common/log_entry'; @@ -53,7 +53,7 @@ export const useFetchLogEntriesAround = ({ type LogEntriesAfterRequest = NonNullable>; const logEntriesAroundSearchRequests$ = useObservable( - () => new Subject<[LogEntriesBeforeRequest, Observable]>(), + () => new ReplaySubject<[LogEntriesBeforeRequest, Observable]>(), [] ); diff --git a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx index 4362f412d5a7..4e1815e754a5 100644 --- a/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx +++ b/x-pack/plugins/infra/public/pages/logs/log_entry_rate/sections/anomalies/log_entry_example.tsx @@ -111,10 +111,14 @@ export const LogEntryExampleMessage: React.FunctionComponent = ({ flyoutOptions: encode({ surroundingLogsId: id, }), - logFilter: encode({ - expression: `${partitionField}: ${dataset}`, - kind: 'kuery', - }), + ...(dataset + ? { + logFilter: encode({ + expression: `${partitionField}: ${dataset}`, + kind: 'kuery', + }), + } + : {}), }, }); diff --git a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx index e3e576a22e6f..70279678a387 100644 --- a/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx +++ b/x-pack/plugins/infra/public/pages/logs/stream/page_logs_content.tsx @@ -60,6 +60,7 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { startDateExpression, endDateExpression, updateDateRange, + lastCompleteDateRangeExpressionUpdate, } = useContext(LogPositionState.Context); const { filterQuery, applyLogFilterQuery } = useContext(LogFilterState.Context); @@ -81,16 +82,16 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { const prevStartTimestamp = usePrevious(startTimestamp); const prevEndTimestamp = usePrevious(endTimestamp); const prevFilterQuery = usePrevious(filterQuery); + const prevLastCompleteDateRangeExpressionUpdate = usePrevious( + lastCompleteDateRangeExpressionUpdate + ); // Refetch entries if... useEffect(() => { const isFirstLoad = !prevStartTimestamp || !prevEndTimestamp; - const newDateRangeDoesNotOverlap = - (prevStartTimestamp != null && - startTimestamp != null && - prevStartTimestamp < startTimestamp) || - (prevEndTimestamp != null && endTimestamp != null && prevEndTimestamp > endTimestamp); + const completeDateRangeExpressionHasChanged = + lastCompleteDateRangeExpressionUpdate !== prevLastCompleteDateRangeExpressionUpdate; const isCenterPointOutsideLoadedRange = targetPosition != null && @@ -101,7 +102,7 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { if ( isFirstLoad || - newDateRangeDoesNotOverlap || + completeDateRangeExpressionHasChanged || isCenterPointOutsideLoadedRange || hasQueryChanged ) { @@ -124,6 +125,8 @@ export const LogsPageLogsContent: React.FunctionComponent = () => { bottomCursor, filterQuery, prevFilterQuery, + lastCompleteDateRangeExpressionUpdate, + prevLastCompleteDateRangeExpressionUpdate, ]); const { logSummaryHighlights, currentHighlightKey, logEntryHighlightsById } = useContext(