mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudWatch: Add default log groups to config page (#49286)
Co-authored-by: Shirley Leu <4163034+fridgepoet@users.noreply.github.com>
This commit is contained in:
parent
3d68023606
commit
8dd8c50dc4
@ -86,8 +86,8 @@ exports[`no enzyme tests`] = {
|
||||
"public/app/features/folders/FolderSettingsPage.test.tsx:1109052730": [
|
||||
[0, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:227258837": [
|
||||
[0, 19, 13, "RegExp match", "2409514259"]
|
||||
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:4057721851": [
|
||||
[1, 19, 13, "RegExp match", "2409514259"]
|
||||
],
|
||||
"public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx:3481855642": [
|
||||
[0, 26, 13, "RegExp match", "2409514259"]
|
||||
@ -6659,8 +6659,12 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/LogsQueryEditor.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
@ -6668,7 +6672,8 @@ exports[`better eslint`] = {
|
||||
"public/app/plugins/datasource/cloudwatch/components/LogsQueryField.test.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"]
|
||||
],
|
||||
"public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
@ -7568,10 +7573,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "13"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "15"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "17"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "19"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "16"]
|
||||
],
|
||||
"public/app/plugins/datasource/influxdb/specs/influx_query_model.test.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
|
@ -52,6 +52,7 @@ export function setupMockedDataSource({
|
||||
|
||||
datasource.getNamespaces = jest.fn().mockResolvedValue([]);
|
||||
datasource.getRegions = jest.fn().mockResolvedValue([]);
|
||||
datasource.defaultLogGroups = [];
|
||||
const fetchMock = jest.fn().mockReturnValue(of({ data }));
|
||||
setBackendSrv({ fetch: fetchMock } as any);
|
||||
|
||||
|
@ -1,71 +1,92 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { shallow } from 'enzyme';
|
||||
import React from 'react';
|
||||
import selectEvent from 'react-select-event';
|
||||
|
||||
import { AwsAuthType } from '@grafana/aws-sdk';
|
||||
|
||||
import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource';
|
||||
|
||||
import { ConfigEditor, Props } from './ConfigEditor';
|
||||
|
||||
const ds = setupMockedDataSource();
|
||||
|
||||
jest.mock('app/features/plugins/datasource_srv', () => ({
|
||||
getDatasourceSrv: () => ({
|
||||
loadDatasource: jest.fn().mockImplementation(() =>
|
||||
Promise.resolve({
|
||||
getRegions: jest.fn().mockReturnValue([
|
||||
{
|
||||
label: 'ap-east-1',
|
||||
value: 'ap-east-1',
|
||||
},
|
||||
]),
|
||||
})
|
||||
),
|
||||
loadDatasource: jest.fn().mockResolvedValue({
|
||||
getRegions: jest.fn().mockResolvedValue([
|
||||
{
|
||||
label: 'ap-east-1',
|
||||
value: 'ap-east-1',
|
||||
},
|
||||
]),
|
||||
describeLogGroups: jest.fn().mockResolvedValue(['logGroup-foo', 'logGroup-bar']),
|
||||
getActualRegion: jest.fn().mockReturnValue('ap-east-1'),
|
||||
getVariables: jest.fn().mockReturnValue([]),
|
||||
}),
|
||||
}),
|
||||
}));
|
||||
|
||||
const setup = (propOverrides?: object) => {
|
||||
const props: Props = {
|
||||
options: {
|
||||
id: 1,
|
||||
uid: 'z',
|
||||
orgId: 1,
|
||||
typeLogoUrl: '',
|
||||
name: 'CloudWatch',
|
||||
access: 'proxy',
|
||||
url: '',
|
||||
database: '',
|
||||
type: 'cloudwatch',
|
||||
typeName: 'Cloudwatch',
|
||||
user: '',
|
||||
basicAuth: false,
|
||||
basicAuthUser: '',
|
||||
isDefault: true,
|
||||
readOnly: false,
|
||||
withCredentials: false,
|
||||
secureJsonFields: {
|
||||
accessKey: false,
|
||||
secretKey: false,
|
||||
},
|
||||
jsonData: {
|
||||
assumeRoleArn: '',
|
||||
externalId: '',
|
||||
database: '',
|
||||
customMetricsNamespaces: '',
|
||||
authType: AwsAuthType.Keys,
|
||||
defaultRegion: 'us-east-2',
|
||||
timeField: '@timestamp',
|
||||
},
|
||||
secureJsonData: {
|
||||
secretKey: '',
|
||||
accessKey: '',
|
||||
},
|
||||
jest.mock('./XrayLinkConfig', () => ({
|
||||
XrayLinkConfig: () => <></>,
|
||||
}));
|
||||
|
||||
jest.mock('@grafana/runtime', () => ({
|
||||
...jest.requireActual('@grafana/runtime'),
|
||||
getBackendSrv: () => ({
|
||||
put: jest.fn().mockResolvedValue({ datasource: ds.datasource }),
|
||||
}),
|
||||
}));
|
||||
|
||||
const props: Props = {
|
||||
options: {
|
||||
id: 1,
|
||||
uid: 'z',
|
||||
orgId: 1,
|
||||
typeLogoUrl: '',
|
||||
name: 'CloudWatch',
|
||||
access: 'proxy',
|
||||
url: '',
|
||||
database: '',
|
||||
type: 'cloudwatch',
|
||||
typeName: 'Cloudwatch',
|
||||
user: '',
|
||||
basicAuth: false,
|
||||
basicAuthUser: '',
|
||||
isDefault: true,
|
||||
readOnly: false,
|
||||
withCredentials: false,
|
||||
secureJsonFields: {
|
||||
accessKey: false,
|
||||
secretKey: false,
|
||||
},
|
||||
onOptionsChange: jest.fn(),
|
||||
};
|
||||
jsonData: {
|
||||
assumeRoleArn: '',
|
||||
externalId: '',
|
||||
database: '',
|
||||
customMetricsNamespaces: '',
|
||||
authType: AwsAuthType.Keys,
|
||||
defaultRegion: 'us-east-2',
|
||||
timeField: '@timestamp',
|
||||
},
|
||||
secureJsonData: {
|
||||
secretKey: '',
|
||||
accessKey: '',
|
||||
},
|
||||
},
|
||||
onOptionsChange: jest.fn(),
|
||||
};
|
||||
|
||||
Object.assign(props, propOverrides);
|
||||
const setup = (propOverrides?: object) => {
|
||||
const newProps = { ...props, ...propOverrides };
|
||||
|
||||
return shallow(<ConfigEditor {...props} />);
|
||||
return shallow(<ConfigEditor {...newProps} />);
|
||||
};
|
||||
|
||||
describe('Render', () => {
|
||||
beforeEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
it('should render component', () => {
|
||||
const wrapper = setup();
|
||||
|
||||
@ -107,4 +128,15 @@ describe('Render', () => {
|
||||
});
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should load log groups when multiselect is opened', async () => {
|
||||
(window as any).grafanaBootData = {
|
||||
settings: {},
|
||||
};
|
||||
|
||||
render(<ConfigEditor {...props} />);
|
||||
const multiselect = await screen.findByLabelText('Log Groups');
|
||||
selectEvent.openMenu(multiselect);
|
||||
expect(await screen.findByText('logGroup-foo')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
@ -7,7 +7,9 @@ import {
|
||||
DataSourcePluginOptionsEditorProps,
|
||||
onUpdateDatasourceJsonDataOption,
|
||||
updateDatasourcePluginJsonDataOption,
|
||||
updateDatasourcePluginOption,
|
||||
} from '@grafana/data';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { Input, InlineField } from '@grafana/ui';
|
||||
import { notifyApp } from 'app/core/actions';
|
||||
import { createWarningNotification } from 'app/core/copy/appNotification';
|
||||
@ -17,16 +19,43 @@ import { store } from 'app/store/store';
|
||||
import { CloudWatchDatasource } from '../datasource';
|
||||
import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types';
|
||||
|
||||
import { LogGroupSelector } from './LogGroupSelector';
|
||||
import { XrayLinkConfig } from './XrayLinkConfig';
|
||||
|
||||
export type Props = DataSourcePluginOptionsEditorProps<CloudWatchJsonData, CloudWatchSecureJsonData>;
|
||||
|
||||
export const ConfigEditor: FC<Props> = (props: Props) => {
|
||||
const { options } = props;
|
||||
const { defaultLogGroups, logsTimeout, defaultRegion } = options.jsonData;
|
||||
const [saved, setSaved] = useState(!!options.version && options.version > 1);
|
||||
|
||||
const datasource = useDatasource(options.name);
|
||||
const datasource = useDatasource(options.name, saved);
|
||||
useAuthenticationWarning(options.jsonData);
|
||||
const logsTimeoutError = useTimoutValidation(props.options.jsonData.logsTimeout);
|
||||
const logsTimeoutError = useTimoutValidation(logsTimeout);
|
||||
useEffect(() => {
|
||||
setSaved(false);
|
||||
}, [
|
||||
props.options.jsonData.assumeRoleArn,
|
||||
props.options.jsonData.authType,
|
||||
props.options.jsonData.defaultRegion,
|
||||
props.options.jsonData.endpoint,
|
||||
props.options.jsonData.externalId,
|
||||
props.options.jsonData.profile,
|
||||
props.options.secureJsonData?.accessKey,
|
||||
props.options.secureJsonData?.secretKey,
|
||||
]);
|
||||
|
||||
const saveOptions = async (): Promise<void> => {
|
||||
if (saved) {
|
||||
return;
|
||||
}
|
||||
await getBackendSrv()
|
||||
.put(`/api/datasources/${options.id}`, options)
|
||||
.then((result: { datasource: any }) => {
|
||||
updateDatasourcePluginOption(props, 'version', result.datasource.version);
|
||||
});
|
||||
setSaved(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -52,7 +81,7 @@ export const ConfigEditor: FC<Props> = (props: Props) => {
|
||||
<InlineField
|
||||
label="Timeout"
|
||||
labelWidth={28}
|
||||
tooltip='Custom timout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as "15m" "30s" "2000ms" etc.'
|
||||
tooltip='Custom timeout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as "15m" "30s" "2000ms" etc.'
|
||||
invalid={Boolean(logsTimeoutError)}
|
||||
>
|
||||
<Input
|
||||
@ -63,6 +92,23 @@ export const ConfigEditor: FC<Props> = (props: Props) => {
|
||||
title={'The timeout must be a valid duration string, such as "15m" "30s" "2000ms" etc.'}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default Log Groups"
|
||||
labelWidth={28}
|
||||
tooltip="Optionally, specify default log groups for CloudWatch Logs queries."
|
||||
>
|
||||
<LogGroupSelector
|
||||
region={defaultRegion ?? ''}
|
||||
selectedLogGroups={defaultLogGroups ?? []}
|
||||
datasource={datasource}
|
||||
onChange={(logGroups) => {
|
||||
updateDatasourcePluginJsonDataOption(props, 'defaultLogGroups', logGroups);
|
||||
}}
|
||||
onOpenMenu={saveOptions}
|
||||
width={60}
|
||||
saved={saved}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
|
||||
<XrayLinkConfig
|
||||
@ -91,10 +137,14 @@ function useAuthenticationWarning(jsonData: CloudWatchJsonData) {
|
||||
}, [jsonData.authType, jsonData.database, jsonData.profile]);
|
||||
}
|
||||
|
||||
function useDatasource(datasourceName: string) {
|
||||
function useDatasource(datasourceName: string, saved: boolean) {
|
||||
const [datasource, setDatasource] = useState<CloudWatchDatasource>();
|
||||
|
||||
useEffect(() => {
|
||||
// reload the datasource when it's saved
|
||||
if (!saved) {
|
||||
return;
|
||||
}
|
||||
getDatasourceSrv()
|
||||
.loadDatasource(datasourceName)
|
||||
.then((datasource) => {
|
||||
@ -102,7 +152,7 @@ function useDatasource(datasourceName: string) {
|
||||
// So a "as" type assertion here is a necessary evil.
|
||||
setDatasource(datasource as CloudWatchDatasource);
|
||||
});
|
||||
}, [datasourceName]);
|
||||
}, [datasourceName, saved]);
|
||||
|
||||
return datasource;
|
||||
}
|
||||
|
@ -85,7 +85,6 @@ describe('LogGroupSelector', () => {
|
||||
'DeliciousGroup',
|
||||
'DeliciousGroup2',
|
||||
'DeliciousGroup3',
|
||||
|
||||
'VelvetGroup',
|
||||
'VelvetGroup2',
|
||||
'VelvetGroup3',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
||||
import _, { DebouncedFunc } from 'lodash'; // eslint-disable-line lodash/import-scope
|
||||
import React from 'react';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
@ -34,4 +34,25 @@ describe('CloudWatchLogsQueryField', () => {
|
||||
});
|
||||
expect(onRunQuery).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('loads defaultLogGroups', async () => {
|
||||
const onRunQuery = jest.fn();
|
||||
const ds = setupMockedDataSource();
|
||||
ds.datasource.defaultLogGroups = ['foo'];
|
||||
|
||||
render(
|
||||
<CloudWatchLogsQueryField
|
||||
absoluteRange={{ from: 1, to: 10 }}
|
||||
exploreId={ExploreId.left}
|
||||
datasource={ds.datasource}
|
||||
query={{} as any}
|
||||
onRunQuery={onRunQuery}
|
||||
onChange={() => {}}
|
||||
/>
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('foo')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -66,10 +66,10 @@ export class CloudWatchLogsQueryField extends React.PureComponent<CloudWatchLogs
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
const { query, onChange } = this.props;
|
||||
const { query, datasource, onChange } = this.props;
|
||||
|
||||
if (onChange) {
|
||||
onChange({ ...query, logGroupNames: query.logGroupNames ?? [] });
|
||||
onChange({ ...query, logGroupNames: query.logGroupNames ?? datasource.defaultLogGroups });
|
||||
}
|
||||
};
|
||||
|
||||
@ -135,7 +135,7 @@ export class CloudWatchLogsQueryField extends React.PureComponent<CloudWatchLogs
|
||||
inputEl={
|
||||
<LogGroupSelector
|
||||
region={region}
|
||||
selectedLogGroups={logGroupNames ?? []}
|
||||
selectedLogGroups={logGroupNames ?? datasource.defaultLogGroups}
|
||||
datasource={datasource}
|
||||
onChange={function (logGroups: string[]): void {
|
||||
onChange({ ...query, logGroupNames: logGroups });
|
||||
|
@ -72,7 +72,7 @@ exports[`Render should disable access key id field 1`] = `
|
||||
invalid={false}
|
||||
label="Timeout"
|
||||
labelWidth={28}
|
||||
tooltip="Custom timout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
tooltip="Custom timeout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
>
|
||||
<Input
|
||||
onChange={[Function]}
|
||||
@ -82,6 +82,20 @@ exports[`Render should disable access key id field 1`] = `
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default Log Groups"
|
||||
labelWidth={28}
|
||||
tooltip="Optionally, specify default log groups for CloudWatch Logs queries."
|
||||
>
|
||||
<LogGroupSelector
|
||||
onChange={[Function]}
|
||||
onOpenMenu={[Function]}
|
||||
region="us-east-2"
|
||||
saved={false}
|
||||
selectedLogGroups={Array []}
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
<XrayLinkConfig
|
||||
onChange={[Function]}
|
||||
@ -156,7 +170,7 @@ exports[`Render should render component 1`] = `
|
||||
invalid={false}
|
||||
label="Timeout"
|
||||
labelWidth={28}
|
||||
tooltip="Custom timout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
tooltip="Custom timeout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
>
|
||||
<Input
|
||||
onChange={[Function]}
|
||||
@ -166,6 +180,20 @@ exports[`Render should render component 1`] = `
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default Log Groups"
|
||||
labelWidth={28}
|
||||
tooltip="Optionally, specify default log groups for CloudWatch Logs queries."
|
||||
>
|
||||
<LogGroupSelector
|
||||
onChange={[Function]}
|
||||
onOpenMenu={[Function]}
|
||||
region="us-east-2"
|
||||
saved={false}
|
||||
selectedLogGroups={Array []}
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
<XrayLinkConfig
|
||||
onChange={[Function]}
|
||||
@ -245,7 +273,7 @@ exports[`Render should show access key and secret access key fields 1`] = `
|
||||
invalid={false}
|
||||
label="Timeout"
|
||||
labelWidth={28}
|
||||
tooltip="Custom timout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
tooltip="Custom timeout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
>
|
||||
<Input
|
||||
onChange={[Function]}
|
||||
@ -255,6 +283,20 @@ exports[`Render should show access key and secret access key fields 1`] = `
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default Log Groups"
|
||||
labelWidth={28}
|
||||
tooltip="Optionally, specify default log groups for CloudWatch Logs queries."
|
||||
>
|
||||
<LogGroupSelector
|
||||
onChange={[Function]}
|
||||
onOpenMenu={[Function]}
|
||||
region="us-east-2"
|
||||
saved={false}
|
||||
selectedLogGroups={Array []}
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
<XrayLinkConfig
|
||||
onChange={[Function]}
|
||||
@ -334,7 +376,7 @@ exports[`Render should show arn role field 1`] = `
|
||||
invalid={false}
|
||||
label="Timeout"
|
||||
labelWidth={28}
|
||||
tooltip="Custom timout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
tooltip="Custom timeout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
>
|
||||
<Input
|
||||
onChange={[Function]}
|
||||
@ -344,6 +386,20 @@ exports[`Render should show arn role field 1`] = `
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default Log Groups"
|
||||
labelWidth={28}
|
||||
tooltip="Optionally, specify default log groups for CloudWatch Logs queries."
|
||||
>
|
||||
<LogGroupSelector
|
||||
onChange={[Function]}
|
||||
onOpenMenu={[Function]}
|
||||
region="us-east-2"
|
||||
saved={false}
|
||||
selectedLogGroups={Array []}
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
<XrayLinkConfig
|
||||
onChange={[Function]}
|
||||
@ -423,7 +479,7 @@ exports[`Render should show credentials profile name field 1`] = `
|
||||
invalid={false}
|
||||
label="Timeout"
|
||||
labelWidth={28}
|
||||
tooltip="Custom timout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
tooltip="Custom timeout for CloudWatch Logs insights queries which have max concurrency limits. Default is 15 minutes. Must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
|
||||
>
|
||||
<Input
|
||||
onChange={[Function]}
|
||||
@ -433,6 +489,20 @@ exports[`Render should show credentials profile name field 1`] = `
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
<InlineField
|
||||
label="Default Log Groups"
|
||||
labelWidth={28}
|
||||
tooltip="Optionally, specify default log groups for CloudWatch Logs queries."
|
||||
>
|
||||
<LogGroupSelector
|
||||
onChange={[Function]}
|
||||
onOpenMenu={[Function]}
|
||||
region="us-east-2"
|
||||
saved={false}
|
||||
selectedLogGroups={Array []}
|
||||
width={60}
|
||||
/>
|
||||
</InlineField>
|
||||
</div>
|
||||
<XrayLinkConfig
|
||||
onChange={[Function]}
|
||||
|
@ -101,6 +101,7 @@ export class CloudWatchDatasource
|
||||
|
||||
tracingDataSourceUid?: string;
|
||||
logsTimeout: string;
|
||||
defaultLogGroups: string[];
|
||||
|
||||
type = 'cloudwatch';
|
||||
standardStatistics = ['Average', 'Maximum', 'Minimum', 'Sum', 'SampleCount'];
|
||||
@ -127,6 +128,7 @@ export class CloudWatchDatasource
|
||||
this.languageProvider = new CloudWatchLanguageProvider(this);
|
||||
this.tracingDataSourceUid = instanceSettings.jsonData.tracingDatasourceUid;
|
||||
this.logsTimeout = instanceSettings.jsonData.logsTimeout || '15m';
|
||||
this.defaultLogGroups = instanceSettings.jsonData.defaultLogGroups || [];
|
||||
this.sqlCompletionItemProvider = new SQLCompletionItemProvider(this, this.templateSrv);
|
||||
this.metricMathCompletionItemProvider = new MetricMathCompletionItemProvider(this, this.templateSrv);
|
||||
this.variables = new CloudWatchVariableSupport(this);
|
||||
@ -176,7 +178,14 @@ export class CloudWatchDatasource
|
||||
logQueries: CloudWatchLogsQuery[],
|
||||
options: DataQueryRequest<CloudWatchQuery>
|
||||
): Observable<DataQueryResponse> => {
|
||||
const validLogQueries = logQueries.filter((item) => item.logGroupNames?.length);
|
||||
const queryParams = logQueries.map((target: CloudWatchLogsQuery) => ({
|
||||
queryString: target.expression || '',
|
||||
refId: target.refId,
|
||||
logGroupNames: target.logGroupNames || this.defaultLogGroups,
|
||||
region: this.replace(this.getActualRegion(target.region), options.scopedVars, true, 'region'),
|
||||
}));
|
||||
|
||||
const validLogQueries = queryParams.filter((item) => item.logGroupNames?.length);
|
||||
if (logQueries.length > validLogQueries.length) {
|
||||
return of({ data: [], error: { message: 'Log group is required' } });
|
||||
}
|
||||
@ -186,13 +195,6 @@ export class CloudWatchDatasource
|
||||
return of({ data: [], state: LoadingState.Done });
|
||||
}
|
||||
|
||||
const queryParams = logQueries.map((target: CloudWatchLogsQuery) => ({
|
||||
queryString: target.expression || '',
|
||||
refId: target.refId,
|
||||
logGroupNames: target.logGroupNames,
|
||||
region: this.replace(this.getActualRegion(target.region), options.scopedVars, true, 'region'),
|
||||
}));
|
||||
|
||||
const startTime = new Date();
|
||||
const timeoutFunc = () => {
|
||||
return Date.now() >= startTime.valueOf() + rangeUtil.intervalToMs(this.logsTimeout);
|
||||
|
@ -121,6 +121,7 @@ export interface CloudWatchJsonData extends AwsAuthDataSourceJsonData {
|
||||
logsTimeout?: string;
|
||||
// Used to create links if logs contain traceId.
|
||||
tracingDatasourceUid?: string;
|
||||
defaultLogGroups?: string[];
|
||||
}
|
||||
|
||||
export interface CloudWatchSecureJsonData extends AwsAuthDataSourceSecureJsonData {
|
||||
|
Loading…
Reference in New Issue
Block a user