Skip to content

Commit 56a46b5

Browse files
authored
Make info request timeout configurable (#182)
* Customize timeouts and add tests * Propagate config and fix tests * Set e2e test config back to false * Handle write error * Use http.DefaultTransport
1 parent 36ffc58 commit 56a46b5

File tree

5 files changed

+176
-93
lines changed

5 files changed

+176
-93
lines changed

apm-lambda-extension/extension/http_server.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package extension
1919

2020
import (
21+
"context"
2122
"net"
2223
"net/http"
2324
"time"
@@ -26,9 +27,9 @@ import (
2627
var agentDataServer *http.Server
2728

2829
// StartHttpServer starts the server listening for APM agent data.
29-
func StartHttpServer(agentDataChan chan AgentData, config *extensionConfig) (err error) {
30+
func StartHttpServer(ctx context.Context, agentDataChan chan AgentData, config *extensionConfig) (err error) {
3031
mux := http.NewServeMux()
31-
mux.HandleFunc("/", handleInfoRequest(config.apmServerUrl))
32+
mux.HandleFunc("/", handleInfoRequest(ctx, config.apmServerUrl, config))
3233
mux.HandleFunc("/intake/v2/events", handleIntakeV2Events(agentDataChan))
3334
timeout := time.Duration(config.dataReceiverTimeoutSeconds) * time.Second
3435
agentDataServer = &http.Server{
@@ -47,8 +48,11 @@ func StartHttpServer(agentDataChan chan AgentData, config *extensionConfig) (err
4748
go func() {
4849
Log.Infof("Extension listening for apm data on %s", agentDataServer.Addr)
4950
if err = agentDataServer.Serve(ln); err != nil {
50-
Log.Errorf("Error upon APM data server start : %v", err)
51-
return
51+
if err.Error() == "http: Server closed" {
52+
Log.Debug(err)
53+
} else {
54+
Log.Errorf("Error upon APM data server start : %v", err)
55+
}
5256
}
5357
}()
5458
return nil

apm-lambda-extension/extension/http_server_test.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package extension
1919

2020
import (
2121
"bytes"
22+
"context"
2223
"errors"
2324
"io/ioutil"
2425
"net"
@@ -59,7 +60,7 @@ func TestInfoProxy(t *testing.T) {
5960
dataReceiverTimeoutSeconds: 15,
6061
}
6162

62-
if err := StartHttpServer(dataChannel, &config); err != nil {
63+
if err := StartHttpServer(context.Background(), dataChannel, &config); err != nil {
6364
t.Fail()
6465
return
6566
}
@@ -108,7 +109,7 @@ func TestInfoProxyErrorStatusCode(t *testing.T) {
108109
dataReceiverTimeoutSeconds: 15,
109110
}
110111

111-
if err := StartHttpServer(dataChannel, &config); err != nil {
112+
if err := StartHttpServer(context.Background(), dataChannel, &config); err != nil {
112113
t.Fail()
113114
return
114115
}
@@ -152,7 +153,7 @@ func Test_handleInfoRequest(t *testing.T) {
152153
}
153154

154155
// Start extension server
155-
if err := StartHttpServer(dataChannel, &config); err != nil {
156+
if err := StartHttpServer(context.Background(), dataChannel, &config); err != nil {
156157
t.Fail()
157158
return
158159
}
@@ -217,7 +218,7 @@ func Test_handleIntakeV2EventsQueryParam(t *testing.T) {
217218
dataReceiverTimeoutSeconds: 15,
218219
}
219220

220-
if err := StartHttpServer(dataChannel, &config); err != nil {
221+
if err := StartHttpServer(context.Background(), dataChannel, &config); err != nil {
221222
t.Fail()
222223
return
223224
}
@@ -269,7 +270,7 @@ func Test_handleIntakeV2EventsNoQueryParam(t *testing.T) {
269270
dataReceiverTimeoutSeconds: 15,
270271
}
271272

272-
if err := StartHttpServer(dataChannel, &config); err != nil {
273+
if err := StartHttpServer(context.Background(), dataChannel, &config); err != nil {
273274
t.Fail()
274275
return
275276
}
@@ -313,7 +314,7 @@ func Test_handleIntakeV2EventsQueryParamEmptyData(t *testing.T) {
313314
dataReceiverTimeoutSeconds: 15,
314315
}
315316

316-
if err := StartHttpServer(dataChannel, &config); err != nil {
317+
if err := StartHttpServer(context.Background(), dataChannel, &config); err != nil {
317318
t.Fail()
318319
return
319320
}

apm-lambda-extension/extension/route_handlers.go

+21-2
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
package extension
1919

2020
import (
21+
"context"
2122
"io/ioutil"
2223
"net/http"
2324
"net/http/httputil"
2425
"net/url"
26+
"time"
2527
)
2628

2729
type AgentData struct {
@@ -30,19 +32,30 @@ type AgentData struct {
3032
}
3133

3234
var AgentDoneSignal chan struct{}
35+
var mainExtensionContext context.Context
3336

3437
// URL: http://server/
35-
func handleInfoRequest(apmServerUrl string) func(w http.ResponseWriter, r *http.Request) {
38+
func handleInfoRequest(ctx context.Context, apmServerUrl string, config *extensionConfig) func(w http.ResponseWriter, r *http.Request) {
3639
return func(w http.ResponseWriter, r *http.Request) {
3740

41+
Log.Debug("Handling APM Server Info Request")
42+
mainExtensionContext = ctx
43+
3844
// Init reverse proxy
3945
parsedApmServerUrl, err := url.Parse(apmServerUrl)
4046
if err != nil {
4147
Log.Errorf("could not parse APM server URL: %v", err)
4248
return
4349
}
50+
4451
reverseProxy := httputil.NewSingleHostReverseProxy(parsedApmServerUrl)
4552

53+
reverseProxyTimeout := time.Duration(config.DataForwarderTimeoutSeconds) * time.Second
54+
reverseProxy.Transport = http.DefaultTransport
55+
reverseProxy.Transport.(*http.Transport).ResponseHeaderTimeout = reverseProxyTimeout
56+
57+
reverseProxy.ErrorHandler = reverseProxyErrorHandler
58+
4659
// Process request (the Golang doc suggests removing any pre-existing X-Forwarded-For header coming
4760
// from the client or an untrusted proxy to prevent IP spoofing : https://pkg.go.dev/net/http/httputil#ReverseProxy
4861
r.Header.Del("X-Forwarded-For")
@@ -58,10 +71,16 @@ func handleInfoRequest(apmServerUrl string) func(w http.ResponseWriter, r *http.
5871
}
5972
}
6073

74+
func reverseProxyErrorHandler(res http.ResponseWriter, req *http.Request, err error) {
75+
SetApmServerTransportState(Failing, mainExtensionContext)
76+
Log.Errorf("Error querying version from the APM Server: %v", err)
77+
}
78+
6179
// URL: http://server/intake/v2/events
6280
func handleIntakeV2Events(agentDataChan chan AgentData) func(w http.ResponseWriter, r *http.Request) {
63-
6481
return func(w http.ResponseWriter, r *http.Request) {
82+
83+
Log.Debug("Handling APM Data Intake")
6584
rawBytes, err := ioutil.ReadAll(r.Body)
6685
defer r.Body.Close()
6786
if err != nil {

apm-lambda-extension/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func main() {
7575
agentDataChannel := make(chan extension.AgentData, 100)
7676

7777
// Start http server to receive data from agent
78-
if err = extension.StartHttpServer(agentDataChannel, config); err != nil {
78+
if err = extension.StartHttpServer(ctx, agentDataChannel, config); err != nil {
7979
extension.Log.Errorf("Could not start APM data receiver : %v", err)
8080
}
8181

0 commit comments

Comments
 (0)