|
|
|
@ -1,6 +1,7 @@ |
|
|
|
|
import { mergeMap, throttleTime } from 'rxjs/operators'; |
|
|
|
|
import { identity, Observable, of, SubscriptionLike, Unsubscribable } from 'rxjs'; |
|
|
|
|
import { |
|
|
|
|
AbsoluteTimeRange, |
|
|
|
|
DataQuery, |
|
|
|
|
DataQueryErrorType, |
|
|
|
|
DataQueryResponse, |
|
|
|
@ -32,18 +33,13 @@ import { notifyApp } from '../../../core/actions'; |
|
|
|
|
import { runRequest } from '../../query/state/runRequest'; |
|
|
|
|
import { decorateData } from '../utils/decorators'; |
|
|
|
|
import { createErrorNotification } from '../../../core/copy/appNotification'; |
|
|
|
|
import { |
|
|
|
|
localStorageFullAction, |
|
|
|
|
richHistoryLimitExceededAction, |
|
|
|
|
richHistoryUpdatedAction, |
|
|
|
|
stateSave, |
|
|
|
|
storeAutoLoadLogsVolumeAction, |
|
|
|
|
} from './main'; |
|
|
|
|
import { localStorageFullAction, richHistoryLimitExceededAction, richHistoryUpdatedAction, stateSave } from './main'; |
|
|
|
|
import { AnyAction, createAction, PayloadAction } from '@reduxjs/toolkit'; |
|
|
|
|
import { updateTime } from './time'; |
|
|
|
|
import { historyUpdatedAction } from './history'; |
|
|
|
|
import { createCacheKey, createEmptyQueryResponse, getResultsFromCache } from './utils'; |
|
|
|
|
import { config } from '@grafana/runtime'; |
|
|
|
|
import deepEqual from 'fast-deep-equal'; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// Actions and Payloads
|
|
|
|
@ -124,6 +120,8 @@ const storeLogsVolumeDataProviderAction = createAction<StoreLogsVolumeDataProvid |
|
|
|
|
'explore/storeLogsVolumeDataProviderAction' |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
const cleanLogsVolumeAction = createAction<{ exploreId: ExploreId }>('explore/cleanLogsVolumeAction'); |
|
|
|
|
|
|
|
|
|
export interface StoreLogsVolumeDataSubscriptionPayload { |
|
|
|
|
exploreId: ExploreId; |
|
|
|
|
logsVolumeDataSubscription?: SubscriptionLike; |
|
|
|
@ -324,7 +322,7 @@ export const runQueries = ( |
|
|
|
|
dispatch(clearCache(exploreId)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const { richHistory, autoLoadLogsVolume } = getState().explore; |
|
|
|
|
const { richHistory } = getState().explore; |
|
|
|
|
const exploreItemState = getState().explore[exploreId]!; |
|
|
|
|
const { |
|
|
|
|
datasourceInstance, |
|
|
|
@ -468,7 +466,15 @@ export const runQueries = ( |
|
|
|
|
} |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
if (config.featureToggles.fullRangeLogsVolume && hasLogsVolumeSupport(datasourceInstance)) { |
|
|
|
|
if (live) { |
|
|
|
|
dispatch( |
|
|
|
|
storeLogsVolumeDataProviderAction({ |
|
|
|
|
exploreId, |
|
|
|
|
logsVolumeDataProvider: undefined, |
|
|
|
|
}) |
|
|
|
|
); |
|
|
|
|
dispatch(cleanLogsVolumeAction({ exploreId })); |
|
|
|
|
} else if (config.featureToggles.fullRangeLogsVolume && hasLogsVolumeSupport(datasourceInstance)) { |
|
|
|
|
const logsVolumeDataProvider = datasourceInstance.getLogsVolumeDataProvider(transaction.request); |
|
|
|
|
dispatch( |
|
|
|
|
storeLogsVolumeDataProviderAction({ |
|
|
|
@ -476,8 +482,9 @@ export const runQueries = ( |
|
|
|
|
logsVolumeDataProvider, |
|
|
|
|
}) |
|
|
|
|
); |
|
|
|
|
if (autoLoadLogsVolume && logsVolumeDataProvider) { |
|
|
|
|
dispatch(loadLogsVolumeData(exploreId)); |
|
|
|
|
const { logsVolumeData, absoluteRange } = getState().explore[exploreId]!; |
|
|
|
|
if (!canReuseLogsVolumeData(logsVolumeData, queries, absoluteRange)) { |
|
|
|
|
dispatch(cleanLogsVolumeAction({ exploreId })); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
dispatch( |
|
|
|
@ -493,6 +500,29 @@ export const runQueries = ( |
|
|
|
|
}; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Checks if after changing the time range the existing data can be used to show logs volume. |
|
|
|
|
* It can happen if queries are the same and new time range is within existing data time range. |
|
|
|
|
*/ |
|
|
|
|
function canReuseLogsVolumeData( |
|
|
|
|
logsVolumeData: DataQueryResponse | undefined, |
|
|
|
|
queries: DataQuery[], |
|
|
|
|
selectedTimeRange: AbsoluteTimeRange |
|
|
|
|
): boolean { |
|
|
|
|
if (logsVolumeData && logsVolumeData.data[0]) { |
|
|
|
|
// check if queries are the same
|
|
|
|
|
if (!deepEqual(logsVolumeData.data[0].meta?.custom?.targets, queries)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
const dataRange = logsVolumeData && logsVolumeData.data[0] && logsVolumeData.data[0].meta?.custom?.absoluteRange; |
|
|
|
|
// if selected range is within loaded logs volume
|
|
|
|
|
if (dataRange && dataRange.from <= selectedTimeRange.from && selectedTimeRange.to <= dataRange.to) { |
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Reset queries to the given queries. Any modifications will be discarded. |
|
|
|
|
* Use this action for clicks on query examples. Triggers a query run. |
|
|
|
@ -543,23 +573,6 @@ export function clearCache(exploreId: ExploreId): ThunkResult<void> { |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Uses storeLogsVolumeDataProviderAction to update the state and load logs volume when auto-load |
|
|
|
|
* is enabled and logs volume hasn't been loaded yet. |
|
|
|
|
*/ |
|
|
|
|
export function changeAutoLogsVolume(exploreId: ExploreId, autoLoadLogsVolume: boolean): ThunkResult<void> { |
|
|
|
|
return (dispatch, getState) => { |
|
|
|
|
dispatch(storeAutoLoadLogsVolumeAction(autoLoadLogsVolume)); |
|
|
|
|
const state = getState().explore[exploreId]!; |
|
|
|
|
|
|
|
|
|
// load logs volume automatically after switching
|
|
|
|
|
const logsVolumeData = state.logsVolumeData; |
|
|
|
|
if (!logsVolumeData?.data && autoLoadLogsVolume) { |
|
|
|
|
dispatch(loadLogsVolumeData(exploreId)); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Initializes loading logs volume data and stores emitted value. |
|
|
|
|
*/ |
|
|
|
@ -697,7 +710,12 @@ export const queryReducer = (state: ExploreItemState, action: AnyAction): Explor |
|
|
|
|
...state, |
|
|
|
|
logsVolumeDataProvider, |
|
|
|
|
logsVolumeDataSubscription: undefined, |
|
|
|
|
// clear previous data, with a new provider the previous data becomes stale
|
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (cleanLogsVolumeAction.match(action)) { |
|
|
|
|
return { |
|
|
|
|
...state, |
|
|
|
|
logsVolumeData: undefined, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|