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": [
|
"public/app/features/folders/FolderSettingsPage.test.tsx:1109052730": [
|
||||||
[0, 19, 13, "RegExp match", "2409514259"]
|
[0, 19, 13, "RegExp match", "2409514259"]
|
||||||
],
|
],
|
||||||
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:227258837": [
|
"public/app/plugins/datasource/cloudwatch/components/ConfigEditor.test.tsx:4057721851": [
|
||||||
[0, 19, 13, "RegExp match", "2409514259"]
|
[1, 19, 13, "RegExp match", "2409514259"]
|
||||||
],
|
],
|
||||||
"public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx:3481855642": [
|
"public/app/plugins/datasource/elasticsearch/configuration/ConfigEditor.test.tsx:3481855642": [
|
||||||
[0, 26, 13, "RegExp match", "2409514259"]
|
[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, "Do not use any type assertions.", "1"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
|
[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": [
|
"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": [
|
"public/app/plugins/datasource/cloudwatch/components/LogsQueryEditor.tsx:5381": [
|
||||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
[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": [
|
"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.", "0"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
[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": [
|
"public/app/plugins/datasource/cloudwatch/components/LogsQueryField.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[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.", "13"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "14"],
|
[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.", "15"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "16"],
|
[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"]
|
|
||||||
],
|
],
|
||||||
"public/app/plugins/datasource/influxdb/specs/influx_query_model.test.ts:5381": [
|
"public/app/plugins/datasource/influxdb/specs/influx_query_model.test.ts:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
|
@ -52,6 +52,7 @@ export function setupMockedDataSource({
|
|||||||
|
|
||||||
datasource.getNamespaces = jest.fn().mockResolvedValue([]);
|
datasource.getNamespaces = jest.fn().mockResolvedValue([]);
|
||||||
datasource.getRegions = jest.fn().mockResolvedValue([]);
|
datasource.getRegions = jest.fn().mockResolvedValue([]);
|
||||||
|
datasource.defaultLogGroups = [];
|
||||||
const fetchMock = jest.fn().mockReturnValue(of({ data }));
|
const fetchMock = jest.fn().mockReturnValue(of({ data }));
|
||||||
setBackendSrv({ fetch: fetchMock } as any);
|
setBackendSrv({ fetch: fetchMock } as any);
|
||||||
|
|
||||||
|
@ -1,26 +1,43 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import selectEvent from 'react-select-event';
|
||||||
|
|
||||||
import { AwsAuthType } from '@grafana/aws-sdk';
|
import { AwsAuthType } from '@grafana/aws-sdk';
|
||||||
|
|
||||||
|
import { setupMockedDataSource } from '../__mocks__/CloudWatchDataSource';
|
||||||
|
|
||||||
import { ConfigEditor, Props } from './ConfigEditor';
|
import { ConfigEditor, Props } from './ConfigEditor';
|
||||||
|
|
||||||
|
const ds = setupMockedDataSource();
|
||||||
|
|
||||||
jest.mock('app/features/plugins/datasource_srv', () => ({
|
jest.mock('app/features/plugins/datasource_srv', () => ({
|
||||||
getDatasourceSrv: () => ({
|
getDatasourceSrv: () => ({
|
||||||
loadDatasource: jest.fn().mockImplementation(() =>
|
loadDatasource: jest.fn().mockResolvedValue({
|
||||||
Promise.resolve({
|
getRegions: jest.fn().mockResolvedValue([
|
||||||
getRegions: jest.fn().mockReturnValue([
|
|
||||||
{
|
{
|
||||||
label: 'ap-east-1',
|
label: 'ap-east-1',
|
||||||
value: '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([]),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('./XrayLinkConfig', () => ({
|
||||||
|
XrayLinkConfig: () => <></>,
|
||||||
|
}));
|
||||||
|
|
||||||
|
jest.mock('@grafana/runtime', () => ({
|
||||||
|
...jest.requireActual('@grafana/runtime'),
|
||||||
|
getBackendSrv: () => ({
|
||||||
|
put: jest.fn().mockResolvedValue({ datasource: ds.datasource }),
|
||||||
}),
|
}),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const setup = (propOverrides?: object) => {
|
|
||||||
const props: Props = {
|
const props: Props = {
|
||||||
options: {
|
options: {
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -60,12 +77,16 @@ const setup = (propOverrides?: object) => {
|
|||||||
onOptionsChange: jest.fn(),
|
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', () => {
|
describe('Render', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.resetAllMocks();
|
||||||
|
});
|
||||||
it('should render component', () => {
|
it('should render component', () => {
|
||||||
const wrapper = setup();
|
const wrapper = setup();
|
||||||
|
|
||||||
@ -107,4 +128,15 @@ describe('Render', () => {
|
|||||||
});
|
});
|
||||||
expect(wrapper).toMatchSnapshot();
|
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,
|
DataSourcePluginOptionsEditorProps,
|
||||||
onUpdateDatasourceJsonDataOption,
|
onUpdateDatasourceJsonDataOption,
|
||||||
updateDatasourcePluginJsonDataOption,
|
updateDatasourcePluginJsonDataOption,
|
||||||
|
updateDatasourcePluginOption,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
|
import { getBackendSrv } from '@grafana/runtime';
|
||||||
import { Input, InlineField } from '@grafana/ui';
|
import { Input, InlineField } from '@grafana/ui';
|
||||||
import { notifyApp } from 'app/core/actions';
|
import { notifyApp } from 'app/core/actions';
|
||||||
import { createWarningNotification } from 'app/core/copy/appNotification';
|
import { createWarningNotification } from 'app/core/copy/appNotification';
|
||||||
@ -17,16 +19,43 @@ import { store } from 'app/store/store';
|
|||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../datasource';
|
||||||
import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types';
|
import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types';
|
||||||
|
|
||||||
|
import { LogGroupSelector } from './LogGroupSelector';
|
||||||
import { XrayLinkConfig } from './XrayLinkConfig';
|
import { XrayLinkConfig } from './XrayLinkConfig';
|
||||||
|
|
||||||
export type Props = DataSourcePluginOptionsEditorProps<CloudWatchJsonData, CloudWatchSecureJsonData>;
|
export type Props = DataSourcePluginOptionsEditorProps<CloudWatchJsonData, CloudWatchSecureJsonData>;
|
||||||
|
|
||||||
export const ConfigEditor: FC<Props> = (props: Props) => {
|
export const ConfigEditor: FC<Props> = (props: Props) => {
|
||||||
const { options } = 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);
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
@ -52,7 +81,7 @@ export const ConfigEditor: FC<Props> = (props: Props) => {
|
|||||||
<InlineField
|
<InlineField
|
||||||
label="Timeout"
|
label="Timeout"
|
||||||
labelWidth={28}
|
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)}
|
invalid={Boolean(logsTimeoutError)}
|
||||||
>
|
>
|
||||||
<Input
|
<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.'}
|
title={'The timeout must be a valid duration string, such as "15m" "30s" "2000ms" etc.'}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</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>
|
</div>
|
||||||
|
|
||||||
<XrayLinkConfig
|
<XrayLinkConfig
|
||||||
@ -91,10 +137,14 @@ function useAuthenticationWarning(jsonData: CloudWatchJsonData) {
|
|||||||
}, [jsonData.authType, jsonData.database, jsonData.profile]);
|
}, [jsonData.authType, jsonData.database, jsonData.profile]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function useDatasource(datasourceName: string) {
|
function useDatasource(datasourceName: string, saved: boolean) {
|
||||||
const [datasource, setDatasource] = useState<CloudWatchDatasource>();
|
const [datasource, setDatasource] = useState<CloudWatchDatasource>();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// reload the datasource when it's saved
|
||||||
|
if (!saved) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
getDatasourceSrv()
|
getDatasourceSrv()
|
||||||
.loadDatasource(datasourceName)
|
.loadDatasource(datasourceName)
|
||||||
.then((datasource) => {
|
.then((datasource) => {
|
||||||
@ -102,7 +152,7 @@ function useDatasource(datasourceName: string) {
|
|||||||
// So a "as" type assertion here is a necessary evil.
|
// So a "as" type assertion here is a necessary evil.
|
||||||
setDatasource(datasource as CloudWatchDatasource);
|
setDatasource(datasource as CloudWatchDatasource);
|
||||||
});
|
});
|
||||||
}, [datasourceName]);
|
}, [datasourceName, saved]);
|
||||||
|
|
||||||
return datasource;
|
return datasource;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +85,6 @@ describe('LogGroupSelector', () => {
|
|||||||
'DeliciousGroup',
|
'DeliciousGroup',
|
||||||
'DeliciousGroup2',
|
'DeliciousGroup2',
|
||||||
'DeliciousGroup3',
|
'DeliciousGroup3',
|
||||||
|
|
||||||
'VelvetGroup',
|
'VelvetGroup',
|
||||||
'VelvetGroup2',
|
'VelvetGroup2',
|
||||||
'VelvetGroup3',
|
'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 _, { DebouncedFunc } from 'lodash'; // eslint-disable-line lodash/import-scope
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { act } from 'react-dom/test-utils';
|
import { act } from 'react-dom/test-utils';
|
||||||
@ -34,4 +34,25 @@ describe('CloudWatchLogsQueryField', () => {
|
|||||||
});
|
});
|
||||||
expect(onRunQuery).toHaveBeenCalled();
|
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 = () => {
|
componentDidMount = () => {
|
||||||
const { query, onChange } = this.props;
|
const { query, datasource, onChange } = this.props;
|
||||||
|
|
||||||
if (onChange) {
|
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={
|
inputEl={
|
||||||
<LogGroupSelector
|
<LogGroupSelector
|
||||||
region={region}
|
region={region}
|
||||||
selectedLogGroups={logGroupNames ?? []}
|
selectedLogGroups={logGroupNames ?? datasource.defaultLogGroups}
|
||||||
datasource={datasource}
|
datasource={datasource}
|
||||||
onChange={function (logGroups: string[]): void {
|
onChange={function (logGroups: string[]): void {
|
||||||
onChange({ ...query, logGroupNames: logGroups });
|
onChange({ ...query, logGroupNames: logGroups });
|
||||||
|
@ -72,7 +72,7 @@ exports[`Render should disable access key id field 1`] = `
|
|||||||
invalid={false}
|
invalid={false}
|
||||||
label="Timeout"
|
label="Timeout"
|
||||||
labelWidth={28}
|
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
|
<Input
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -82,6 +82,20 @@ exports[`Render should disable access key id field 1`] = `
|
|||||||
width={60}
|
width={60}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</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>
|
</div>
|
||||||
<XrayLinkConfig
|
<XrayLinkConfig
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -156,7 +170,7 @@ exports[`Render should render component 1`] = `
|
|||||||
invalid={false}
|
invalid={false}
|
||||||
label="Timeout"
|
label="Timeout"
|
||||||
labelWidth={28}
|
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
|
<Input
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -166,6 +180,20 @@ exports[`Render should render component 1`] = `
|
|||||||
width={60}
|
width={60}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</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>
|
</div>
|
||||||
<XrayLinkConfig
|
<XrayLinkConfig
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -245,7 +273,7 @@ exports[`Render should show access key and secret access key fields 1`] = `
|
|||||||
invalid={false}
|
invalid={false}
|
||||||
label="Timeout"
|
label="Timeout"
|
||||||
labelWidth={28}
|
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
|
<Input
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -255,6 +283,20 @@ exports[`Render should show access key and secret access key fields 1`] = `
|
|||||||
width={60}
|
width={60}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</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>
|
</div>
|
||||||
<XrayLinkConfig
|
<XrayLinkConfig
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -334,7 +376,7 @@ exports[`Render should show arn role field 1`] = `
|
|||||||
invalid={false}
|
invalid={false}
|
||||||
label="Timeout"
|
label="Timeout"
|
||||||
labelWidth={28}
|
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
|
<Input
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -344,6 +386,20 @@ exports[`Render should show arn role field 1`] = `
|
|||||||
width={60}
|
width={60}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</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>
|
</div>
|
||||||
<XrayLinkConfig
|
<XrayLinkConfig
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -423,7 +479,7 @@ exports[`Render should show credentials profile name field 1`] = `
|
|||||||
invalid={false}
|
invalid={false}
|
||||||
label="Timeout"
|
label="Timeout"
|
||||||
labelWidth={28}
|
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
|
<Input
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
@ -433,6 +489,20 @@ exports[`Render should show credentials profile name field 1`] = `
|
|||||||
width={60}
|
width={60}
|
||||||
/>
|
/>
|
||||||
</InlineField>
|
</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>
|
</div>
|
||||||
<XrayLinkConfig
|
<XrayLinkConfig
|
||||||
onChange={[Function]}
|
onChange={[Function]}
|
||||||
|
@ -101,6 +101,7 @@ export class CloudWatchDatasource
|
|||||||
|
|
||||||
tracingDataSourceUid?: string;
|
tracingDataSourceUid?: string;
|
||||||
logsTimeout: string;
|
logsTimeout: string;
|
||||||
|
defaultLogGroups: string[];
|
||||||
|
|
||||||
type = 'cloudwatch';
|
type = 'cloudwatch';
|
||||||
standardStatistics = ['Average', 'Maximum', 'Minimum', 'Sum', 'SampleCount'];
|
standardStatistics = ['Average', 'Maximum', 'Minimum', 'Sum', 'SampleCount'];
|
||||||
@ -127,6 +128,7 @@ export class CloudWatchDatasource
|
|||||||
this.languageProvider = new CloudWatchLanguageProvider(this);
|
this.languageProvider = new CloudWatchLanguageProvider(this);
|
||||||
this.tracingDataSourceUid = instanceSettings.jsonData.tracingDatasourceUid;
|
this.tracingDataSourceUid = instanceSettings.jsonData.tracingDatasourceUid;
|
||||||
this.logsTimeout = instanceSettings.jsonData.logsTimeout || '15m';
|
this.logsTimeout = instanceSettings.jsonData.logsTimeout || '15m';
|
||||||
|
this.defaultLogGroups = instanceSettings.jsonData.defaultLogGroups || [];
|
||||||
this.sqlCompletionItemProvider = new SQLCompletionItemProvider(this, this.templateSrv);
|
this.sqlCompletionItemProvider = new SQLCompletionItemProvider(this, this.templateSrv);
|
||||||
this.metricMathCompletionItemProvider = new MetricMathCompletionItemProvider(this, this.templateSrv);
|
this.metricMathCompletionItemProvider = new MetricMathCompletionItemProvider(this, this.templateSrv);
|
||||||
this.variables = new CloudWatchVariableSupport(this);
|
this.variables = new CloudWatchVariableSupport(this);
|
||||||
@ -176,7 +178,14 @@ export class CloudWatchDatasource
|
|||||||
logQueries: CloudWatchLogsQuery[],
|
logQueries: CloudWatchLogsQuery[],
|
||||||
options: DataQueryRequest<CloudWatchQuery>
|
options: DataQueryRequest<CloudWatchQuery>
|
||||||
): Observable<DataQueryResponse> => {
|
): 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) {
|
if (logQueries.length > validLogQueries.length) {
|
||||||
return of({ data: [], error: { message: 'Log group is required' } });
|
return of({ data: [], error: { message: 'Log group is required' } });
|
||||||
}
|
}
|
||||||
@ -186,13 +195,6 @@ export class CloudWatchDatasource
|
|||||||
return of({ data: [], state: LoadingState.Done });
|
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 startTime = new Date();
|
||||||
const timeoutFunc = () => {
|
const timeoutFunc = () => {
|
||||||
return Date.now() >= startTime.valueOf() + rangeUtil.intervalToMs(this.logsTimeout);
|
return Date.now() >= startTime.valueOf() + rangeUtil.intervalToMs(this.logsTimeout);
|
||||||
|
@ -121,6 +121,7 @@ export interface CloudWatchJsonData extends AwsAuthDataSourceJsonData {
|
|||||||
logsTimeout?: string;
|
logsTimeout?: string;
|
||||||
// Used to create links if logs contain traceId.
|
// Used to create links if logs contain traceId.
|
||||||
tracingDatasourceUid?: string;
|
tracingDatasourceUid?: string;
|
||||||
|
defaultLogGroups?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CloudWatchSecureJsonData extends AwsAuthDataSourceSecureJsonData {
|
export interface CloudWatchSecureJsonData extends AwsAuthDataSourceSecureJsonData {
|
||||||
|
Loading…
Reference in New Issue
Block a user