Logs: Add a feature toggle to run logs volume query automatically (#40579)

* Add a feature toggle to run logs volume query automatically

* Add missing default value

* Move feature toggle after moving auto-load button

* Remove unused import
This commit is contained in:
Piotr Jamróz 2021-10-21 15:56:31 +02:00 committed by GitHub
parent 447a088750
commit f86fa876f2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 40 additions and 4 deletions

View File

@ -53,6 +53,7 @@ export interface FeatureToggles {
prometheusMonaco: boolean; prometheusMonaco: boolean;
newNavigation: boolean; newNavigation: boolean;
fullRangeLogsVolume: boolean; fullRangeLogsVolume: boolean;
autoLoadFullRangeLogsVolume: boolean;
} }
/** /**

View File

@ -69,6 +69,7 @@ export class GrafanaBootConfig implements GrafanaConfig {
prometheusMonaco: false, prometheusMonaco: false,
newNavigation: false, newNavigation: false,
fullRangeLogsVolume: false, fullRangeLogsVolume: false,
autoLoadFullRangeLogsVolume: false,
}; };
licenseInfo: LicenseInfo = {} as LicenseInfo; licenseInfo: LicenseInfo = {} as LicenseInfo;
rendererAvailable = false; rendererAvailable = false;

View File

@ -22,6 +22,7 @@ import { Logs } from './Logs';
import { LogsCrossFadeTransition } from './utils/LogsCrossFadeTransition'; import { LogsCrossFadeTransition } from './utils/LogsCrossFadeTransition';
import { LiveTailControls } from './useLiveTailControls'; import { LiveTailControls } from './useLiveTailControls';
import { getFieldLinksForExplore } from './utils/links'; import { getFieldLinksForExplore } from './utils/links';
import { config } from 'app/core/config';
interface LogsContainerProps extends PropsFromRedux { interface LogsContainerProps extends PropsFromRedux {
width: number; width: number;
@ -150,7 +151,11 @@ export class LogsContainer extends PureComponent<LogsContainerProps> {
getFieldLinks={this.getFieldLinks} getFieldLinks={this.getFieldLinks}
addResultsToCache={() => addResultsToCache(exploreId)} addResultsToCache={() => addResultsToCache(exploreId)}
clearCache={() => clearCache(exploreId)} clearCache={() => clearCache(exploreId)}
loadingLogsVolumeAvailable={hasLogsVolumeSupport(datasourceInstance) && !!logsVolumeDataProvider} loadingLogsVolumeAvailable={
hasLogsVolumeSupport(datasourceInstance) &&
!!logsVolumeDataProvider &&
!config.featureToggles.autoLoadFullRangeLogsVolume
}
onClickLoadLogsVolume={() => loadLogsVolumeData(exploreId)} onClickLoadLogsVolume={() => loadLogsVolumeData(exploreId)}
/> />
</Collapse> </Collapse>

View File

@ -3,6 +3,19 @@ import { noop } from 'lodash';
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import { SecondaryActions } from './SecondaryActions'; import { SecondaryActions } from './SecondaryActions';
import { config } from '@grafana/runtime';
jest.mock('@grafana/runtime', () => ({
...((jest.requireActual('@grafana/runtime') as unknown) as object),
config: {
...((jest.requireActual('@grafana/runtime') as unknown) as any).config,
featureToggles: {
fullRangeLogsVolume: true,
autoLoadFullRangeLogsVolume: false,
},
},
}));
const addQueryRowButtonSelector = '[aria-label="Add row button"]'; const addQueryRowButtonSelector = '[aria-label="Add row button"]';
const richHistoryButtonSelector = '[aria-label="Rich history button"]'; const richHistoryButtonSelector = '[aria-label="Rich history button"]';
const queryInspectorButtonSelector = '[aria-label="Query inspector button"]'; const queryInspectorButtonSelector = '[aria-label="Query inspector button"]';
@ -66,4 +79,8 @@ describe('SecondaryActions', () => {
wrapper.find(queryInspectorButtonSelector).simulate('click'); wrapper.find(queryInspectorButtonSelector).simulate('click');
expect(onClickQueryInspector).toBeCalled(); expect(onClickQueryInspector).toBeCalled();
}); });
it('does not render load logs volume button when auto loading is enabled', () => {
config.featureToggles.autoLoadFullRangeLogsVolume = true;
});
}); });

View File

@ -33,6 +33,7 @@ import { reducerTester } from '../../../../test/core/redux/reducerTester';
import { configureStore } from '../../../store/configureStore'; import { configureStore } from '../../../store/configureStore';
import { setTimeSrv } from '../../dashboard/services/TimeSrv'; import { setTimeSrv } from '../../dashboard/services/TimeSrv';
import Mock = jest.Mock; import Mock = jest.Mock;
import { config } from '@grafana/runtime';
jest.mock('@grafana/runtime', () => ({ jest.mock('@grafana/runtime', () => ({
...((jest.requireActual('@grafana/runtime') as unknown) as object), ...((jest.requireActual('@grafana/runtime') as unknown) as object),
@ -40,6 +41,7 @@ jest.mock('@grafana/runtime', () => ({
...((jest.requireActual('@grafana/runtime') as unknown) as any).config, ...((jest.requireActual('@grafana/runtime') as unknown) as any).config,
featureToggles: { featureToggles: {
fullRangeLogsVolume: true, fullRangeLogsVolume: true,
autoLoadFullRangeLogsVolume: false,
}, },
}, },
})); }));
@ -322,6 +324,7 @@ describe('reducer', () => {
describe('logs volume', () => { describe('logs volume', () => {
let dispatch: ThunkDispatch, let dispatch: ThunkDispatch,
getState: () => StoreState, getState: () => StoreState,
unsubscribes: Function[],
mockLogsVolumeDataProvider: () => Observable<DataQueryResponse>; mockLogsVolumeDataProvider: () => Observable<DataQueryResponse>;
beforeEach(() => { beforeEach(() => {
@ -352,11 +355,9 @@ describe('reducer', () => {
dispatch = store.dispatch; dispatch = store.dispatch;
getState = store.getState; getState = store.getState;
});
it('should cancel any unfinished logs volume queries', async () => {
setupQueryResponse(getState()); setupQueryResponse(getState());
let unsubscribes: Function[] = []; unsubscribes = [];
mockLogsVolumeDataProvider = () => { mockLogsVolumeDataProvider = () => {
return ({ return ({
@ -369,7 +370,9 @@ describe('reducer', () => {
}, },
} as unknown) as Observable<DataQueryResponse>; } as unknown) as Observable<DataQueryResponse>;
}; };
});
it('should cancel any unfinished logs volume queries', async () => {
await dispatch(runQueries(ExploreId.left)); await dispatch(runQueries(ExploreId.left));
// no subscriptions created yet // no subscriptions created yet
expect(unsubscribes).toHaveLength(0); expect(unsubscribes).toHaveLength(0);
@ -391,5 +394,11 @@ describe('reducer', () => {
expect(unsubscribes[0]).toBeCalled(); expect(unsubscribes[0]).toBeCalled();
expect(unsubscribes[1]).not.toBeCalled(); expect(unsubscribes[1]).not.toBeCalled();
}); });
it('should load logs volume after running the query', async () => {
config.featureToggles.autoLoadFullRangeLogsVolume = true;
await dispatch(runQueries(ExploreId.left));
expect(unsubscribes).toHaveLength(1);
});
}); });
}); });

View File

@ -485,6 +485,9 @@ export const runQueries = (
const { logsVolumeData, absoluteRange } = getState().explore[exploreId]!; const { logsVolumeData, absoluteRange } = getState().explore[exploreId]!;
if (!canReuseLogsVolumeData(logsVolumeData, queries, absoluteRange)) { if (!canReuseLogsVolumeData(logsVolumeData, queries, absoluteRange)) {
dispatch(cleanLogsVolumeAction({ exploreId })); dispatch(cleanLogsVolumeAction({ exploreId }));
if (config.featureToggles.autoLoadFullRangeLogsVolume) {
dispatch(loadLogsVolumeData(exploreId));
}
} }
} else { } else {
dispatch( dispatch(