Skip to content

Commit 38c7ef9

Browse files
committed
Add option to configure HTTP request timeout in milliseconds
Keep (but also deprecate) old option `request_timeout_in_seconds` to preserve backward compatibility.
1 parent 6d51561 commit 38c7ef9

File tree

5 files changed

+95
-29
lines changed

5 files changed

+95
-29
lines changed

assets/docs/configuration/targets/http-full-example.hcl

+3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ target {
1717
# Request timeout in seconds (default: 5)
1818
request_timeout_in_seconds = 2
1919

20+
# Request timeout in milliseconds (default: 5000)
21+
request_timeout_in_millis = 2000
22+
2023
# Content type for POST request (default: "application/json")
2124
content_type = "text/html"
2225

config/component_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ func TestCreateTargetComponentHCL(t *testing.T) {
7878
RequestMaxMessages: 20,
7979
RequestByteLimit: 1048576,
8080
MessageByteLimit: 1048576,
81-
RequestTimeoutInSeconds: 5,
81+
RequestTimeoutInSeconds: 0,
82+
RequestTimeoutInMillis: 0,
8283
ContentType: "application/json",
8384
Headers: "",
8485
BasicAuthUsername: "",
@@ -104,6 +105,7 @@ func TestCreateTargetComponentHCL(t *testing.T) {
104105
RequestByteLimit: 1000000,
105106
MessageByteLimit: 1000000,
106107
RequestTimeoutInSeconds: 2,
108+
RequestTimeoutInMillis: 2000,
107109
ContentType: "text/html",
108110
Headers: "{\"Accept-Language\":\"en-US\"}",
109111
BasicAuthUsername: "myUsername",

pkg/target/http.go

+26-5
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
type HTTPTargetConfig struct {
4040
HTTPURL string `hcl:"url"`
4141
RequestTimeoutInSeconds int `hcl:"request_timeout_in_seconds,optional"`
42+
RequestTimeoutInMillis int `hcl:"request_timeout_in_millis,optional"`
4243
ContentType string `hcl:"content_type,optional"`
4344
Headers string `hcl:"headers,optional"`
4445
BasicAuthUsername string `hcl:"basic_auth_username,optional"`
@@ -145,7 +146,7 @@ func addHeadersToRequest(request *http.Request, headers map[string]string, dynam
145146
// newHTTPTarget creates a client for writing events to HTTP
146147
func newHTTPTarget(
147148
httpURL string,
148-
requestTimeout int,
149+
requestTimeoutMillis int,
149150
requestMaxMessages int,
150151
requestByteLimit int,
151152
messageByteLimit int,
@@ -187,7 +188,7 @@ func newHTTPTarget(
187188
}
188189

189190
client := createHTTPClient(oAuth2ClientID, oAuth2ClientSecret, oAuth2TokenURL, oAuth2RefreshToken, transport)
190-
client.Timeout = time.Duration(requestTimeout) * time.Second
191+
client.Timeout = time.Duration(requestTimeoutMillis) * time.Millisecond
191192

192193
approxTmplSize, requestTemplate, err := loadRequestTemplate(templateFile)
193194
if err != nil {
@@ -276,9 +277,30 @@ func createHTTPClient(oAuth2ClientID string, oAuth2ClientSecret string, oAuth2To
276277

277278
// HTTPTargetConfigFunction creates HTTPTarget from HTTPTargetConfig
278279
func HTTPTargetConfigFunction(c *HTTPTargetConfig) (*HTTPTarget, error) {
280+
var requestTimeoutInMillis int
281+
282+
if c.RequestTimeoutInMillis != 0 && c.RequestTimeoutInSeconds == 0 {
283+
requestTimeoutInMillis = c.RequestTimeoutInMillis
284+
}
285+
286+
if c.RequestTimeoutInMillis != 0 && c.RequestTimeoutInSeconds != 0 {
287+
requestTimeoutInMillis = c.RequestTimeoutInMillis
288+
log.Warn("Both 'request_timeout' and 'request_timeout_in_seconds' options are set. In this case 'request_timeout' takes precendence and 'request_timeout_in_seconds' is ignored. Using 'request_timeout_in_seconds' is deprecated, and will be removed in the next major version. Use 'request_timeout' only")
289+
}
290+
291+
if c.RequestTimeoutInMillis == 0 && c.RequestTimeoutInSeconds != 0 {
292+
requestTimeoutInMillis = c.RequestTimeoutInSeconds * 1000
293+
log.Warn("For the HTTP target, 'request_timeout_in_seconds' is deprecated, and will be removed in the next major version. Use 'request_timeout' instead")
294+
}
295+
296+
if c.RequestTimeoutInMillis == 0 && c.RequestTimeoutInSeconds == 0 {
297+
requestTimeoutInMillis = 5000
298+
log.Warn("Neither 'request_timeout' nor 'request_timeout_in_seconds' are set. The previous default is preserved, but strongly advise manual configuration of 'request_timeout'")
299+
}
300+
279301
return newHTTPTarget(
280302
c.HTTPURL,
281-
c.RequestTimeoutInSeconds,
303+
requestTimeoutInMillis,
282304
c.RequestMaxMessages,
283305
c.RequestByteLimit,
284306
c.MessageByteLimit,
@@ -321,8 +343,7 @@ func (f HTTPTargetAdapter) ProvideDefault() (interface{}, error) {
321343
MessageByteLimit: 1048576,
322344
EnableTLS: false,
323345

324-
RequestTimeoutInSeconds: 5,
325-
ContentType: "application/json",
346+
ContentType: "application/json",
326347
ResponseRules: &ResponseRules{
327348
Invalid: []Rule{},
328349
SetupError: []Rule{},

pkg/target/http_oauth2_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func runTest(t *testing.T, inputClientID string, inputClientSecret string, input
120120
}
121121

122122
func oauth2Target(t *testing.T, targetURL string, inputClientID string, inputClientSecret string, inputRefreshToken string, tokenServerURL string) *HTTPTarget {
123-
target, err := newHTTPTarget(targetURL, 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, inputClientID, inputClientSecret, inputRefreshToken, tokenServerURL, "", defaultResponseRules(), false)
123+
target, err := newHTTPTarget(targetURL, 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, inputClientID, inputClientSecret, inputRefreshToken, tokenServerURL, "", defaultResponseRules(), false)
124124
if err != nil {
125125
t.Fatal(err)
126126
}

pkg/target/http_test.go

+62-22
Original file line numberDiff line numberDiff line change
@@ -162,12 +162,12 @@ func TestHTTP_RetrieveHeaders(t *testing.T) {
162162
for _, tt := range testCases {
163163
t.Run(tt.Name, func(t *testing.T) {
164164
testTargetConfig := &HTTPTargetConfig{
165-
HTTPURL: "http://test",
166-
MessageByteLimit: 1048576,
167-
RequestByteLimit: 1048576,
168-
RequestTimeoutInSeconds: 5,
169-
ContentType: "application/json",
170-
DynamicHeaders: tt.Dynamic,
165+
HTTPURL: "http://test",
166+
MessageByteLimit: 1048576,
167+
RequestByteLimit: 1048576,
168+
RequestTimeoutInMillis: 5000,
169+
ContentType: "application/json",
170+
DynamicHeaders: tt.Dynamic,
171171
}
172172
testTarget, err := HTTPTargetConfigFunction(testTargetConfig)
173173
if err != nil {
@@ -184,6 +184,46 @@ func TestHTTP_RetrieveHeaders(t *testing.T) {
184184
}
185185
}
186186

187+
func TestHTTP_RequestTimeoutsConfig(t *testing.T) {
188+
testCases := []struct {
189+
Name string
190+
Config *HTTPTargetConfig
191+
ExpectedCientTimeout time.Duration
192+
}{
193+
{
194+
Name: "Nothing set",
195+
Config: &HTTPTargetConfig{},
196+
ExpectedCientTimeout: time.Duration(5) * time.Second,
197+
},
198+
{
199+
Name: "In seconds only",
200+
Config: &HTTPTargetConfig{RequestTimeoutInSeconds: 10},
201+
ExpectedCientTimeout: time.Duration(10) * time.Second,
202+
},
203+
{
204+
Name: "In milliseconds only",
205+
Config: &HTTPTargetConfig{RequestTimeoutInMillis: 2500},
206+
ExpectedCientTimeout: time.Duration(2500) * time.Millisecond,
207+
},
208+
{
209+
Name: "Seconds and millis are set",
210+
Config: &HTTPTargetConfig{RequestTimeoutInSeconds: 10, RequestTimeoutInMillis: 2500},
211+
ExpectedCientTimeout: time.Duration(2500) * time.Millisecond,
212+
},
213+
}
214+
for _, tt := range testCases {
215+
t.Run(tt.Name, func(t *testing.T) {
216+
assert := assert.New(t)
217+
tt.Config.HTTPURL = "http://test"
218+
tt.Config.RequestByteLimit = 1048576
219+
tt.Config.MessageByteLimit = 1048576
220+
target, _ := HTTPTargetConfigFunction(tt.Config)
221+
222+
assert.Equal(tt.ExpectedCientTimeout, target.client.Timeout)
223+
})
224+
}
225+
}
226+
187227
func TestHTTP_AddHeadersToRequest(t *testing.T) {
188228
assert := assert.New(t)
189229

@@ -311,20 +351,20 @@ func TestHTTP_AddHeadersToRequest_WithDynamicHeaders(t *testing.T) {
311351
func TestHTTP_NewHTTPTarget(t *testing.T) {
312352
assert := assert.New(t)
313353

314-
httpTarget, err := newHTTPTarget("http://something", 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
354+
httpTarget, err := newHTTPTarget("http://something", 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
315355

316356
assert.Nil(err)
317357
assert.NotNil(httpTarget)
318358

319-
failedHTTPTarget, err1 := newHTTPTarget("something", 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
359+
failedHTTPTarget, err1 := newHTTPTarget("something", 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
320360

321361
assert.NotNil(err1)
322362
if err1 != nil {
323363
assert.Equal("Invalid url for HTTP target: 'something'", err1.Error())
324364
}
325365
assert.Nil(failedHTTPTarget)
326366

327-
failedHTTPTarget2, err2 := newHTTPTarget("", 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
367+
failedHTTPTarget2, err2 := newHTTPTarget("", 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
328368
assert.NotNil(err2)
329369
if err2 != nil {
330370
assert.Equal("Invalid url for HTTP target: ''", err2.Error())
@@ -353,7 +393,7 @@ func TestHTTP_Write_Simple(t *testing.T) {
353393
server := createTestServerWithResponseCode(&results, &headers, tt.ResponseCode, "")
354394
defer server.Close()
355395

356-
target, err := newHTTPTarget(server.URL, 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
396+
target, err := newHTTPTarget(server.URL, 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
357397
if err != nil {
358398
t.Fatal(err)
359399
}
@@ -421,7 +461,7 @@ func TestHTTP_Write_Batched(t *testing.T) {
421461
server := createTestServerWithResponseCode(&results, &headers, 200, "")
422462
defer server.Close()
423463

424-
target, err := newHTTPTarget(server.URL, 5, tt.BatchSize, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
464+
target, err := newHTTPTarget(server.URL, 5000, tt.BatchSize, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
425465
if err != nil {
426466
t.Fatal(err)
427467
}
@@ -480,7 +520,7 @@ func TestHTTP_Write_Concurrent(t *testing.T) {
480520
server := createTestServer(&results)
481521
defer server.Close()
482522

483-
target, err := newHTTPTarget(server.URL, 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
523+
target, err := newHTTPTarget(server.URL, 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
484524
if err != nil {
485525
t.Fatal(err)
486526
}
@@ -524,7 +564,7 @@ func TestHTTP_Write_Failure(t *testing.T) {
524564
server := createTestServer(&results)
525565
defer server.Close()
526566

527-
target, err := newHTTPTarget("http://NonexistentEndpoint", 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
567+
target, err := newHTTPTarget("http://NonexistentEndpoint", 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
528568
if err != nil {
529569
t.Fatal(err)
530570
}
@@ -567,7 +607,7 @@ func TestHTTP_Write_InvalidResponseCode(t *testing.T) {
567607
var headers http.Header
568608
server := createTestServerWithResponseCode(&results, &headers, tt.ResponseCode, "")
569609
defer server.Close()
570-
target, err := newHTTPTarget(server.URL, 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
610+
target, err := newHTTPTarget(server.URL, 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
571611
if err != nil {
572612
t.Fatal(err)
573613
}
@@ -602,7 +642,7 @@ func TestHTTP_Write_Oversized(t *testing.T) {
602642
server := createTestServer(&results)
603643
defer server.Close()
604644

605-
target, err := newHTTPTarget(server.URL, 5, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
645+
target, err := newHTTPTarget(server.URL, 5000, 1, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), false)
606646
if err != nil {
607647
t.Fatal(err)
608648
}
@@ -645,7 +685,7 @@ func TestHTTP_Write_EnabledTemplating(t *testing.T) {
645685
server := createTestServer(&results)
646686
defer server.Close()
647687

648-
target, err := newHTTPTarget(server.URL, 5, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", string(`../../integration/http/template`), defaultResponseRules(), false)
688+
target, err := newHTTPTarget(server.URL, 5000, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", string(`../../integration/http/template`), defaultResponseRules(), false)
649689
if err != nil {
650690
t.Fatal(err)
651691
}
@@ -705,7 +745,7 @@ func TestHTTP_Write_Invalid(t *testing.T) {
705745
},
706746
}
707747

708-
target, err := newHTTPTarget(server.URL, 5, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", string(`../../integration/http/template`), &responseRules, false)
748+
target, err := newHTTPTarget(server.URL, 5000, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", string(`../../integration/http/template`), &responseRules, false)
709749
if err != nil {
710750
t.Fatal(err)
711751
}
@@ -735,7 +775,7 @@ func TestHTTP_Write_Setup(t *testing.T) {
735775
},
736776
}
737777

738-
target, err := newHTTPTarget(server.URL, 5, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", string(`../../integration/http/template`), &responseRules, false)
778+
target, err := newHTTPTarget(server.URL, 5000, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", string(`../../integration/http/template`), &responseRules, false)
739779
if err != nil {
740780
t.Fatal(err)
741781
}
@@ -762,7 +802,7 @@ func TestHTTP_TimeOrientedHeadersEnabled(t *testing.T) {
762802
server := createTestServerWithResponseCode(&results, &headers, 200, "ok")
763803
defer server.Close()
764804

765-
target, err := newHTTPTarget(server.URL, 5, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), true)
805+
target, err := newHTTPTarget(server.URL, 5000, 5, 1048576, 1048576, "application/json", "", "", "", false, "", "", "", true, false, "", "", "", "", "", defaultResponseRules(), true)
766806
if err != nil {
767807
t.Fatal(err)
768808
}
@@ -789,7 +829,7 @@ func TestHTTP_Write_TLS(t *testing.T) {
789829

790830
// Test that https requests work with manually provided certs
791831
target, err := newHTTPTarget("https://localhost:8999/hello",
792-
5,
832+
5000,
793833
1,
794834
1048576,
795835
1048576,
@@ -831,7 +871,7 @@ func TestHTTP_Write_TLS(t *testing.T) {
831871

832872
// Test that https requests work for different endpoints when different certs are provided manually
833873
target2, err2 := newHTTPTarget(ngrokAddress,
834-
5,
874+
5000,
835875
1,
836876
1048576,
837877
1048576,
@@ -866,7 +906,7 @@ func TestHTTP_Write_TLS(t *testing.T) {
866906

867907
// Test that https requests work for different endpoints when different certs are provided manually
868908
target3, err4 := newHTTPTarget(ngrokAddress,
869-
5,
909+
5000,
870910
1,
871911
1048576,
872912
1048576,

0 commit comments

Comments
 (0)