mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudWatch Logs: Set default logs query and disable button when empty (#61956)
This commit is contained in:
parent
e46aa2e4e6
commit
7c85db5bfa
@ -6,6 +6,7 @@ import { config } from '@grafana/runtime';
|
||||
|
||||
import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource';
|
||||
import { validLogsQuery, validMetricSearchBuilderQuery } from '../__mocks__/queries';
|
||||
import { DEFAULT_LOGS_QUERY_STRING } from '../defaultQueries';
|
||||
|
||||
import QueryHeader from './QueryHeader';
|
||||
|
||||
@ -16,11 +17,10 @@ const ds = setupMockedDataSource({
|
||||
ds.datasource.resources.getRegions = jest.fn().mockResolvedValue([]);
|
||||
|
||||
describe('QueryHeader', () => {
|
||||
afterEach(() => {
|
||||
config.featureToggles.cloudWatchCrossAccountQuerying = originalFeatureToggleValue;
|
||||
});
|
||||
|
||||
describe('when changing region', () => {
|
||||
afterEach(() => {
|
||||
config.featureToggles.cloudWatchCrossAccountQuerying = originalFeatureToggleValue;
|
||||
});
|
||||
const { datasource } = setupMockedDataSource();
|
||||
datasource.resources.getRegions = jest.fn().mockResolvedValue([
|
||||
{ value: 'us-east-2', label: 'us-east-2' },
|
||||
@ -117,4 +117,91 @@ describe('QueryHeader', () => {
|
||||
expect(datasource.resources.isMonitoringAccount).not.toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when changing query mode', () => {
|
||||
const { datasource } = setupMockedDataSource();
|
||||
it('should set default log query when switching to log mode', async () => {
|
||||
const onChange = jest.fn();
|
||||
datasource.resources.isMonitoringAccount = jest.fn().mockResolvedValue(false);
|
||||
render(
|
||||
<QueryHeader
|
||||
datasource={datasource}
|
||||
query={{ ...validMetricSearchBuilderQuery, expression: 'foo' }}
|
||||
onChange={onChange}
|
||||
onRunQuery={jest.fn()}
|
||||
dataIsStale={false}
|
||||
/>
|
||||
);
|
||||
expect(await screen.findByText('CloudWatch Metrics')).toBeInTheDocument();
|
||||
await selectEvent.select(await screen.findByLabelText('Query mode'), 'CloudWatch Logs', {
|
||||
container: document.body,
|
||||
});
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
...validMetricSearchBuilderQuery,
|
||||
logGroupNames: undefined,
|
||||
logGroups: [],
|
||||
queryMode: 'Logs',
|
||||
sqlExpression: '',
|
||||
expression: DEFAULT_LOGS_QUERY_STRING,
|
||||
});
|
||||
});
|
||||
|
||||
it('should set expression to empty when switching to metrics mode', async () => {
|
||||
const onChange = jest.fn();
|
||||
datasource.resources.isMonitoringAccount = jest.fn().mockResolvedValue(false);
|
||||
render(
|
||||
<QueryHeader
|
||||
datasource={datasource}
|
||||
query={{ ...validMetricSearchBuilderQuery, queryMode: 'Logs', expression: 'foo' }}
|
||||
onChange={onChange}
|
||||
onRunQuery={jest.fn()}
|
||||
dataIsStale={false}
|
||||
/>
|
||||
);
|
||||
expect(await screen.findByText('CloudWatch Logs')).toBeInTheDocument();
|
||||
await selectEvent.select(await screen.findByLabelText('Query mode'), 'CloudWatch Metrics', {
|
||||
container: document.body,
|
||||
});
|
||||
expect(onChange).toHaveBeenCalledWith({
|
||||
...validMetricSearchBuilderQuery,
|
||||
logGroupNames: undefined,
|
||||
logGroups: [],
|
||||
sqlExpression: '',
|
||||
expression: '',
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('log expression', () => {
|
||||
const { datasource } = setupMockedDataSource();
|
||||
it('should disable run query button when empty', async () => {
|
||||
const onChange = jest.fn();
|
||||
datasource.resources.isMonitoringAccount = jest.fn().mockResolvedValue(false);
|
||||
render(
|
||||
<QueryHeader
|
||||
datasource={datasource}
|
||||
query={{ ...validMetricSearchBuilderQuery, queryMode: 'Logs', expression: '' }}
|
||||
onChange={onChange}
|
||||
onRunQuery={jest.fn()}
|
||||
dataIsStale={false}
|
||||
/>
|
||||
);
|
||||
expect(await screen.findByText('Run queries')).toBeInTheDocument();
|
||||
expect(screen.getByText('Run queries').closest('button')).toBeDisabled();
|
||||
});
|
||||
it('should enable run query button when set', async () => {
|
||||
const onChange = jest.fn();
|
||||
datasource.resources.isMonitoringAccount = jest.fn().mockResolvedValue(false);
|
||||
render(
|
||||
<QueryHeader
|
||||
datasource={datasource}
|
||||
query={{ ...validMetricSearchBuilderQuery, queryMode: 'Logs', expression: DEFAULT_LOGS_QUERY_STRING }}
|
||||
onChange={onChange}
|
||||
onRunQuery={jest.fn()}
|
||||
dataIsStale={false}
|
||||
/>
|
||||
);
|
||||
expect(await screen.findByText('Run queries')).toBeInTheDocument();
|
||||
expect(screen.getByText('Run queries').closest('button')).not.toBeDisabled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -6,7 +6,8 @@ import { config } from '@grafana/runtime';
|
||||
import { Badge, Button } from '@grafana/ui';
|
||||
|
||||
import { CloudWatchDatasource } from '../datasource';
|
||||
import { isCloudWatchMetricsQuery } from '../guards';
|
||||
import { DEFAULT_LOGS_QUERY_STRING } from '../defaultQueries';
|
||||
import { isCloudWatchLogsQuery, isCloudWatchMetricsQuery } from '../guards';
|
||||
import { useIsMonitoringAccount, useRegions } from '../hooks';
|
||||
import { CloudWatchJsonData, CloudWatchQuery, CloudWatchQueryMode, MetricQueryType } from '../types';
|
||||
|
||||
@ -34,12 +35,19 @@ const QueryHeader: React.FC<Props> = ({
|
||||
const { queryMode, region } = query;
|
||||
const isMonitoringAccount = useIsMonitoringAccount(datasource.resources, query.region);
|
||||
const [regions, regionIsLoading] = useRegions(datasource);
|
||||
const emptyLogsExpression = isCloudWatchLogsQuery(query) ? !query.expression : false;
|
||||
|
||||
const onQueryModeChange = ({ value }: SelectableValue<CloudWatchQueryMode>) => {
|
||||
if (value && value !== queryMode) {
|
||||
// reset expression to a default string when the query mode changes
|
||||
let expression = '';
|
||||
if (value === 'Logs') {
|
||||
expression = DEFAULT_LOGS_QUERY_STRING;
|
||||
}
|
||||
onChange({
|
||||
...datasource.getDefaultQuery(CoreApp.Unknown),
|
||||
...query,
|
||||
expression,
|
||||
queryMode: value,
|
||||
});
|
||||
}
|
||||
@ -100,7 +108,7 @@ const QueryHeader: React.FC<Props> = ({
|
||||
size="sm"
|
||||
onClick={onRunQuery}
|
||||
icon={data?.state === LoadingState.Loading ? 'fa fa-spinner' : undefined}
|
||||
disabled={data?.state === LoadingState.Loading}
|
||||
disabled={data?.state === LoadingState.Loading || emptyLogsExpression}
|
||||
>
|
||||
Run queries
|
||||
</Button>
|
||||
|
@ -16,13 +16,14 @@ export const DEFAULT_METRICS_QUERY: Omit<CloudWatchMetricsQuery, 'refId'> = {
|
||||
matchExact: true,
|
||||
};
|
||||
|
||||
export const DEFAULT_LOGS_QUERY_STRING = 'fields @timestamp, @message |\n sort @timestamp desc |\n limit 20';
|
||||
|
||||
export const getDefaultLogsQuery = (
|
||||
defaultLogGroups?: LogGroup[],
|
||||
legacyDefaultLogGroups?: string[]
|
||||
): Omit<CloudWatchLogsQuery, 'refId' | 'queryMode'> => ({
|
||||
id: '',
|
||||
region: 'default',
|
||||
expression: '',
|
||||
// in case legacy default log groups have been defined in the ConfigEditor, they will be migrated in the LogGroupsField component or the next time the ConfigEditor is opened.
|
||||
// the migration requires async backend calls, so we don't want to do it here as it would block the UI.
|
||||
logGroupNames: legacyDefaultLogGroups,
|
||||
|
Loading…
Reference in New Issue
Block a user