Add timeout option to datasource config (#31871)

This commit is contained in:
Arseny Smalyuk
2021-04-07 17:46:19 +03:00
committed by GitHub
parent 7a68852aa7
commit 8e70d5d181
4 changed files with 61 additions and 15 deletions

View File

@ -147,6 +147,7 @@ Since not all datasources have the same configuration settings we only have the
| tlsAuthWithCACert | boolean | _All_ | Enable TLS authentication using CA cert | | tlsAuthWithCACert | boolean | _All_ | Enable TLS authentication using CA cert |
| tlsSkipVerify | boolean | _All_ | Controls whether a client verifies the server's certificate chain and host name. | | tlsSkipVerify | boolean | _All_ | Controls whether a client verifies the server's certificate chain and host name. |
| serverName | string | _All_ | Optional. Controls the server name used for certificate common name/subject alternative name verification. Defaults to using the data source URL. | | serverName | string | _All_ | Optional. Controls the server name used for certificate common name/subject alternative name verification. Defaults to using the data source URL. |
| timeout | string | _All_ | Request timeout in seconds. Overrides dataproxy.timeout option |
| graphiteVersion | string | Graphite | Graphite version | | graphiteVersion | string | Graphite | Graphite version |
| timeInterval | string | Prometheus, Elasticsearch, InfluxDB, MySQL, PostgreSQL and MSSQL | Lowest interval/step value that should be used for this data source. | | timeInterval | string | Prometheus, Elasticsearch, InfluxDB, MySQL, PostgreSQL and MSSQL | Lowest interval/step value that should be used for this data source. |
| httpMode | string | Influxdb | HTTP Method. 'GET', 'POST', defaults to GET | | httpMode | string | Influxdb | HTTP Method. 'GET', 'POST', defaults to GET |

View File

@ -148,10 +148,11 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
</> </>
)} )}
{dataSourceConfig.access === 'proxy' && ( {dataSourceConfig.access === 'proxy' && (
<div className="gf-form-group">
<div className="gf-form"> <div className="gf-form">
<InlineFormLabel <InlineFormLabel
width={11} width={11}
tooltip="Grafana Proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source." tooltip="Grafana proxy deletes forwarded cookies by default. Specify cookies by name that should be forwarded to the data source."
> >
Whitelisted Cookies Whitelisted Cookies
</InlineFormLabel> </InlineFormLabel>
@ -162,6 +163,20 @@ export const DataSourceHttpSettings: React.FC<HttpSettingsProps> = (props) => {
} }
/> />
</div> </div>
<div className="gf-form">
<FormField
label="Timeout"
labelWidth={11}
tooltip="HTTP request timeout in seconds"
value={dataSourceConfig.jsonData.timeout}
onChange={(event) => {
onSettingsChange({
jsonData: { ...dataSourceConfig.jsonData, timeout: event.currentTarget.value },
});
}}
/>
</div>
</div>
)} )}
</div> </div>
</> </>

View File

@ -124,6 +124,17 @@ var ptc = proxyTransportCache{
cache: make(map[int64]cachedTransport), cache: make(map[int64]cachedTransport),
} }
func (ds *DataSource) getTimeout() time.Duration {
timeout := 0
if ds.JsonData != nil {
timeout = ds.JsonData.Get("timeout").MustInt()
}
if timeout == 0 {
timeout = setting.DataProxyTimeout
}
return time.Duration(timeout) * time.Second
}
func (ds *DataSource) GetHttpClient() (*http.Client, error) { func (ds *DataSource) GetHttpClient() (*http.Client, error) {
transport, err := ds.GetHttpTransport() transport, err := ds.GetHttpTransport()
if err != nil { if err != nil {
@ -131,7 +142,7 @@ func (ds *DataSource) GetHttpClient() (*http.Client, error) {
} }
return &http.Client{ return &http.Client{
Timeout: time.Duration(setting.DataProxyTimeout) * time.Second, Timeout: ds.getTimeout(),
Transport: transport, Transport: transport,
}, nil }, nil
} }
@ -158,7 +169,7 @@ func (ds *DataSource) GetHttpTransport() (*dataSourceTransport, error) {
TLSClientConfig: tlsConfig, TLSClientConfig: tlsConfig,
Proxy: http.ProxyFromEnvironment, Proxy: http.ProxyFromEnvironment,
Dial: (&net.Dialer{ Dial: (&net.Dialer{
Timeout: time.Duration(setting.DataProxyTimeout) * time.Second, Timeout: ds.getTimeout(),
KeepAlive: time.Duration(setting.DataProxyKeepAlive) * time.Second, KeepAlive: time.Duration(setting.DataProxyKeepAlive) * time.Second,
}).Dial, }).Dial,
TLSHandshakeTimeout: time.Duration(setting.DataProxyTLSHandshakeTimeout) * time.Second, TLSHandshakeTimeout: time.Duration(setting.DataProxyTLSHandshakeTimeout) * time.Second,

View File

@ -214,6 +214,25 @@ func TestDataSource_GetHttpTransport(t *testing.T) {
assert.Equal(t, "Ok", bodyStr) assert.Equal(t, "Ok", bodyStr)
}) })
t.Run("Should use request timeout if configured in JsonData", func(t *testing.T) {
clearDSProxyCache(t)
json := simplejson.NewFromAny(map[string]interface{}{
"timeout": 19,
})
ds := DataSource{
Id: 1,
Url: "http://k8s:8001",
Type: "Kubernetes",
JsonData: json,
}
client, err := ds.GetHttpClient()
require.NoError(t, err)
assert.Equal(t, 19*time.Second, client.Timeout)
})
t.Run("Should not include SigV4 middleware if not configured in JsonData", func(t *testing.T) { t.Run("Should not include SigV4 middleware if not configured in JsonData", func(t *testing.T) {
clearDSProxyCache(t) clearDSProxyCache(t)