Skip to content

Commit dbd8b52

Browse files
zroubalikJorTurFer
andauthored
Azure Log Analytics, Prometheus scaler: custom HTTP client timeout (kedacore#6607)
Signed-off-by: Zbynek Roubalik <[email protected]> Co-authored-by: Jorge Turrado Ferrero <[email protected]>
1 parent 18a639d commit dbd8b52

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,13 @@ Here is an overview of all new **experimental** features:
7878
### Improvements
7979

8080
- **General**: Add SecretKey to AWS SecretsManager TriggerAuthentication to allow parsing JSON / Key/Value Pairs in secrets ([#5940](https://github.com/kedacore/keda/issues/5940))
81+
- **Azure Log Analytics Scaler**: Add custom HTTP client timeout ([#6607](https://github.com/kedacore/keda/pull/6607))
8182
- **Elasticsearch Scaler**: Support IgnoreNullValues at Elasticsearch scaler ([#6599](https://github.com/kedacore/keda/pull/6599))
8283
- **GitHub Scaler**: Add support to use ETag for conditional requests against the Github API ([#6503](https://github.com/kedacore/keda/issues/6503))
8384
- **GitHub Scaler**: Filter workflows via query parameter for improved queue count accuracy ([#6519](https://github.com/kedacore/keda/pull/6519))
8485
- **IBMMQ Scaler**: Handling StatusNotFound in IBMMQ scaler ([#6472](https://github.com/kedacore/keda/pull/6472))
8586
- **MongoDB Scaler**: Support float queryValue for MongoDB scaler ([#6574](https://github.com/kedacore/keda/issues/6574))
87+
- **Prometheus Scaler**: Add custom HTTP client timeout ([#6607](https://github.com/kedacore/keda/pull/6607))
8688
- **RabbitMQ Scaler**: Support use of the ‘vhostName’ parameter in the ‘TriggerAuthentication’ resource ([#6369](https://github.com/kedacore/keda/issues/6369))
8789
- **Selenium Grid**: Add trigger param for Node enables managed downloads capability ([#6570](https://github.com/kedacore/keda/pull/6570))
8890
- **Selenium Grid**: Add trigger param to set custom capabilities for matching specific Nodes ([#6536](https://github.com/kedacore/keda/issues/6536))

pkg/scalers/azure_log_analytics_scaler.go

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"strconv"
2323
"strings"
24+
"time"
2425

2526
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
2627
azcloud "github.com/Azure/azure-sdk-for-go/sdk/azcore/cloud"
@@ -58,6 +59,7 @@ type azureLogAnalyticsMetadata struct {
5859
triggerIndex int
5960
cloud azcloud.Configuration
6061
unsafeSsl bool
62+
timeout time.Duration // custom HTTP client timeout
6163
}
6264

6365
// NewAzureLogAnalyticsScaler creates a new Azure Log Analytics Scaler
@@ -105,7 +107,7 @@ func CreateAzureLogsClient(config *scalersconfig.ScalerConfig, meta *azureLogAna
105107
}
106108
client, err := azquery.NewLogsClient(creds, &azquery.LogsClientOptions{
107109
ClientOptions: policy.ClientOptions{
108-
Transport: kedautil.CreateHTTPClient(config.GlobalHTTPTimeout, meta.unsafeSsl),
110+
Transport: kedautil.CreateHTTPClient(meta.timeout, meta.unsafeSsl),
109111
Cloud: meta.cloud,
110112
},
111113
})
@@ -217,6 +219,22 @@ func parseAzureLogAnalyticsMetadata(config *scalersconfig.ScalerConfig) (*azureL
217219
meta.unsafeSsl = unsafeSsl
218220
}
219221

222+
// Resolve HTTP client timeout
223+
meta.timeout = config.GlobalHTTPTimeout
224+
timeoutVal, err := getParameterFromConfig(config, "timeout", false)
225+
if err == nil {
226+
timeout, err := strconv.Atoi(timeoutVal)
227+
if err != nil {
228+
return nil, fmt.Errorf("unable to parse timeout: %w", err)
229+
}
230+
231+
if timeout <= 0 {
232+
return nil, fmt.Errorf("timeout must be greater than 0: %w", err)
233+
}
234+
235+
meta.timeout = time.Duration(timeout) * time.Millisecond
236+
}
237+
220238
return &meta, nil
221239
}
222240

pkg/scalers/azure_log_analytics_scaler_test.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,14 @@ var testLogAnalyticsMetadata = []parseLogAnalyticsMetadataTestData{
9898
{map[string]string{"tenantIdFromEnv": "d248da64-0e1e-4f79-b8c6-72ab7aa055eb", "clientIdFromEnv": "41826dd4-9e0a-4357-a5bd-a88ad771ea7d", "clientSecretFromEnv": "U6DtAX5r6RPZxd~l12Ri3X8J9urt5Q-xs", "workspaceIdFromEnv": "074dd9f8-c368-4220-9400-acb6e80fc325", "query": query, "threshold": "1900000000", "cloud": "private", "logAnalyticsResourceURL": testLogAnalyticsResourceURL}, false},
9999
// Unsupported cloud
100100
{map[string]string{"tenantIdFromEnv": "d248da64-0e1e-4f79-b8c6-72ab7aa055eb", "clientIdFromEnv": "41826dd4-9e0a-4357-a5bd-a88ad771ea7d", "clientSecretFromEnv": "U6DtAX5r6RPZxd~l12Ri3X8J9urt5Q-xs", "workspaceIdFromEnv": "074dd9f8-c368-4220-9400-acb6e80fc325", "query": query, "threshold": "1900000000", "cloud": "azureGermanCloud"}, true},
101+
// Valid HTTP timeout
102+
{map[string]string{"tenantId": "d248da64-0e1e-4f79-b8c6-72ab7aa055eb", "clientId": "41826dd4-9e0a-4357-a5bd-a88ad771ea7d", "clientSecret": "U6DtAX5r6RPZxd~l12Ri3X8J9urt5Q-xs", "workspaceId": "074dd9f8-c368-4220-9400-acb6e80fc325", "query": query, "threshold": "1900000000", "timeout": "1000"}, false},
103+
// Invalid - 0 - HTTP timeout
104+
{map[string]string{"tenantId": "d248da64-0e1e-4f79-b8c6-72ab7aa055eb", "clientId": "41826dd4-9e0a-4357-a5bd-a88ad771ea7d", "clientSecret": "U6DtAX5r6RPZxd~l12Ri3X8J9urt5Q-xs", "workspaceId": "074dd9f8-c368-4220-9400-acb6e80fc325", "query": query, "threshold": "1900000000", "timeout": "0"}, true},
105+
// Invalid - negative - HTTP timeout
106+
{map[string]string{"tenantId": "d248da64-0e1e-4f79-b8c6-72ab7aa055eb", "clientId": "41826dd4-9e0a-4357-a5bd-a88ad771ea7d", "clientSecret": "U6DtAX5r6RPZxd~l12Ri3X8J9urt5Q-xs", "workspaceId": "074dd9f8-c368-4220-9400-acb6e80fc325", "query": query, "threshold": "1900000000", "timeout": "-1"}, true},
107+
// Invalid - not a number - HTTP timeout
108+
{map[string]string{"tenantId": "d248da64-0e1e-4f79-b8c6-72ab7aa055eb", "clientId": "41826dd4-9e0a-4357-a5bd-a88ad771ea7d", "clientSecret": "U6DtAX5r6RPZxd~l12Ri3X8J9urt5Q-xs", "workspaceId": "074dd9f8-c368-4220-9400-acb6e80fc325", "query": query, "threshold": "1900000000", "timeout": "a"}, true},
101109
}
102110

103111
var LogAnalyticsMetricIdentifiers = []LogAnalyticsMetricIdentifier{

pkg/scalers/prometheus_scaler.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ type prometheusMetadata struct {
4949
CustomHeaders map[string]string `keda:"name=customHeaders, order=triggerMetadata, optional"`
5050
IgnoreNullValues bool `keda:"name=ignoreNullValues, order=triggerMetadata, default=true"`
5151
UnsafeSSL bool `keda:"name=unsafeSsl, order=triggerMetadata, optional"`
52-
AwsRegion string `keda:"name=awsRegion, order=triggerMetadata;authParams, optional"`
52+
AwsRegion string `keda:"name=awsRegion, order=triggerMetadata;authParams, optional"`
53+
Timeout int `keda:"name=timeout, order=triggerMetadata, optional"` // custom HTTP client timeout
5354
}
5455

5556
type promQueryResult struct {
@@ -78,7 +79,13 @@ func NewPrometheusScaler(config *scalersconfig.ScalerConfig) (Scaler, error) {
7879
return nil, fmt.Errorf("error parsing prometheus metadata: %w", err)
7980
}
8081

81-
httpClient := kedautil.CreateHTTPClient(config.GlobalHTTPTimeout, meta.UnsafeSSL)
82+
// handle HTTP client timeout
83+
httpClientTimeout := config.GlobalHTTPTimeout
84+
if meta.Timeout > 0 {
85+
httpClientTimeout = time.Duration(meta.Timeout) * time.Millisecond
86+
}
87+
88+
httpClient := kedautil.CreateHTTPClient(httpClientTimeout, meta.UnsafeSSL)
8289

8390
if !meta.PrometheusAuth.Disabled() {
8491
if meta.PrometheusAuth.CA != "" || meta.PrometheusAuth.EnabledTLS() {
@@ -148,6 +155,11 @@ func parsePrometheusMetadata(config *scalersconfig.ScalerConfig) (meta *promethe
148155
return nil, err
149156
}
150157

158+
// validate the timeout
159+
if meta.Timeout < 0 {
160+
return nil, fmt.Errorf("timeout must be greater than 0: %d", meta.Timeout)
161+
}
162+
151163
return meta, nil
152164
}
153165

pkg/scalers/prometheus_scaler_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ var testPromMetadata = []parsePrometheusMetadataTestData{
6464
{map[string]string{"serverAddress": "http://localhost:9090", "metricName": "http_requests_total", "threshold": "100", "query": "up", "queryParameters": "key1=value1,key2=value2"}, false},
6565
// queryParameters with wrong format
6666
{map[string]string{"serverAddress": "http://localhost:9090", "metricName": "http_requests_total", "threshold": "100", "query": "up", "queryParameters": "key1=value1,key2"}, true},
67+
// valid custom http client timeout
68+
{map[string]string{"serverAddress": "http://localhost:9090", "metricName": "http_requests_total", "threshold": "100", "query": "up", "timeout": "1000"}, false},
69+
// invalid - negative - custom http client timeout
70+
{map[string]string{"serverAddress": "http://localhost:9090", "metricName": "http_requests_total", "threshold": "100", "query": "up", "timeout": "-1"}, true},
71+
// invalid - not a number - custom http client timeout with milliseconds
72+
{map[string]string{"serverAddress": "http://localhost:9090", "metricName": "http_requests_total", "threshold": "100", "query": "up", "timeout": "a"}, true},
6773
}
6874

6975
var prometheusMetricIdentifiers = []prometheusMetricIdentifier{

0 commit comments

Comments
 (0)