CloudWatch Logs: Add retry strategy for hitting max concurrent queries (#39290)

* Add error passing and retry strategy

* Change generic error to specific one

* Make the error more generic

* Refactor retry strategy

* Add retry that handles multiple queries

* Rollback some backend changes

* Remove simple retry strategy

* Add comments

* Add tests

* Small test fixes

* Add log timeout config

* Fix tests

* Fix tests

* Add validation

* Remove commented code and add comment

* Fix snapshots

* Remove unnecessary cast
This commit is contained in:
Andrej Ocenas
2021-11-17 21:46:13 +01:00
committed by GitHub
parent 3dd73387fa
commit e237ff20a9
10 changed files with 659 additions and 58 deletions

View File

@@ -1,6 +1,8 @@
import React, { FC, useEffect, useState } from 'react';
import { useDebounce } from 'react-use';
import { Input, InlineField } from '@grafana/ui';
import {
rangeUtil,
DataSourcePluginOptionsEditorProps,
onUpdateDatasourceJsonDataOption,
updateDatasourcePluginJsonDataOption,
@@ -23,6 +25,7 @@ export const ConfigEditor: FC<Props> = (props: Props) => {
const datasource = useDatasource(options.name);
useAuthenticationWarning(options.jsonData);
const logsTimeoutError = useTimoutValidation(props.options.jsonData.logsTimeout);
return (
<>
@@ -43,6 +46,24 @@ export const ConfigEditor: FC<Props> = (props: Props) => {
</InlineField>
</ConnectionConfig>
<h3 className="page-heading">CloudWatch Logs</h3>
<div className="gf-form-group">
<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.'
invalid={Boolean(logsTimeoutError)}
>
<Input
width={60}
placeholder="15m"
value={options.jsonData.logsTimeout || ''}
onChange={onUpdateDatasourceJsonDataOption(props, 'logsTimeout')}
title={'The timeout must be a valid duration string, such as "15m" "30s" "2000ms" etc.'}
/>
</InlineField>
</div>
<XrayLinkConfig
onChange={(uid) => updateDatasourcePluginJsonDataOption(props, 'tracingDatasourceUid', uid)}
datasourceUid={options.jsonData.tracingDatasourceUid}
@@ -84,3 +105,24 @@ function useDatasource(datasourceName: string) {
return datasource;
}
function useTimoutValidation(value: string | undefined) {
const [err, setErr] = useState<undefined | string>(undefined);
useDebounce(
() => {
if (value) {
try {
rangeUtil.describeInterval(value);
setErr(undefined);
} catch (e) {
setErr(e.toString());
}
} else {
setErr(undefined);
}
},
350,
[value]
);
return err;
}

View File

@@ -62,6 +62,29 @@ exports[`Render should disable access key id field 1`] = `
/>
</InlineField>
</ConnectionConfig>
<h3
className="page-heading"
>
CloudWatch Logs
</h3>
<div
className="gf-form-group"
>
<InlineField
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."
>
<Input
onChange={[Function]}
placeholder="15m"
title="The timeout must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
value=""
width={60}
/>
</InlineField>
</div>
<XrayLinkConfig
onChange={[Function]}
/>
@@ -125,6 +148,29 @@ exports[`Render should render component 1`] = `
/>
</InlineField>
</ConnectionConfig>
<h3
className="page-heading"
>
CloudWatch Logs
</h3>
<div
className="gf-form-group"
>
<InlineField
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."
>
<Input
onChange={[Function]}
placeholder="15m"
title="The timeout must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
value=""
width={60}
/>
</InlineField>
</div>
<XrayLinkConfig
onChange={[Function]}
/>
@@ -193,6 +239,29 @@ exports[`Render should show access key and secret access key fields 1`] = `
/>
</InlineField>
</ConnectionConfig>
<h3
className="page-heading"
>
CloudWatch Logs
</h3>
<div
className="gf-form-group"
>
<InlineField
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."
>
<Input
onChange={[Function]}
placeholder="15m"
title="The timeout must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
value=""
width={60}
/>
</InlineField>
</div>
<XrayLinkConfig
onChange={[Function]}
/>
@@ -261,6 +330,29 @@ exports[`Render should show arn role field 1`] = `
/>
</InlineField>
</ConnectionConfig>
<h3
className="page-heading"
>
CloudWatch Logs
</h3>
<div
className="gf-form-group"
>
<InlineField
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."
>
<Input
onChange={[Function]}
placeholder="15m"
title="The timeout must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
value=""
width={60}
/>
</InlineField>
</div>
<XrayLinkConfig
onChange={[Function]}
/>
@@ -329,6 +421,29 @@ exports[`Render should show credentials profile name field 1`] = `
/>
</InlineField>
</ConnectionConfig>
<h3
className="page-heading"
>
CloudWatch Logs
</h3>
<div
className="gf-form-group"
>
<InlineField
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."
>
<Input
onChange={[Function]}
placeholder="15m"
title="The timeout must be a valid duration string, such as \\"15m\\" \\"30s\\" \\"2000ms\\" etc."
value=""
width={60}
/>
</InlineField>
</div>
<XrayLinkConfig
onChange={[Function]}
/>