Skip to content

Commit 1f60fbe

Browse files
authored
Patch listener in collector ext to use random port (#1099)
* Patch listener.go to use random port * Use serve and pass listener to start
1 parent f6d6301 commit 1f60fbe

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

listener.patch

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
diff --git a/collector/internal/telemetryapi/listener.go b/collector/internal/telemetryapi/listener.go
2+
index 8499d4e..62a6461 100644
3+
--- a/collector/internal/telemetryapi/listener.go
4+
+++ b/collector/internal/telemetryapi/listener.go
5+
@@ -17,18 +17,32 @@ package telemetryapi
6+
import (
7+
"context"
8+
"encoding/json"
9+
+ "errors"
10+
"fmt"
11+
"io"
12+
+ "math/rand"
13+
+ "net"
14+
"net/http"
15+
"os"
16+
+ "syscall"
17+
"time"
18+
19+
"github.com/golang-collections/go-datastructures/queue"
20+
"go.uber.org/zap"
21+
)
22+
23+
-const defaultListenerPort = "53612"
24+
-const initialQueueSize = 5
25+
+const (
26+
+ initialQueueSize = 5
27+
+ maxRetries = 5
28+
+ // Define ephemeral port range (typical range is 49152-65535)
29+
+ minPort = 49152
30+
+ maxPort = 65535
31+
+)
32+
+
33+
+// getRandomPort returns a random port number within the ephemeral range
34+
+func getRandomPort() string {
35+
+ return fmt.Sprintf("%d", rand.Intn(maxPort-minPort)+minPort)
36+
+}
37+
38+
// Listener is used to listen to the Telemetry API
39+
type Listener struct {
40+
@@ -46,26 +60,48 @@ func NewListener(logger *zap.Logger) *Listener {
41+
}
42+
}
43+
44+
-func listenOnAddress() string {
45+
+func (s *Listener) tryBindPort() (net.Listener, string, error) {
46+
+ for i := 0; i < maxRetries; i++ {
47+
+ port := getRandomPort()
48+
+ address := listenOnAddress(port)
49+
+
50+
+ l, err := net.Listen("tcp", address)
51+
+ if err != nil {
52+
+ if errors.Is(err, syscall.EADDRINUSE) {
53+
+ s.logger.Debug("Port in use, trying another",
54+
+ zap.String("address", address))
55+
+ continue
56+
+ }
57+
+ return nil, "", err
58+
+ }
59+
+ return l, address, nil
60+
+ }
61+
+
62+
+ return nil, "", fmt.Errorf("failed to find available port after %d attempts", maxRetries)
63+
+}
64+
+
65+
+func listenOnAddress(port string) string {
66+
envAwsLocal, ok := os.LookupEnv("AWS_SAM_LOCAL")
67+
var addr string
68+
if ok && envAwsLocal == "true" {
69+
- addr = ":" + defaultListenerPort
70+
+ addr = ":" + port
71+
} else {
72+
- addr = "sandbox.localdomain:" + defaultListenerPort
73+
+ addr = "sandbox.localdomain:" + port
74+
}
75+
-
76+
return addr
77+
}
78+
79+
// Start the server in a goroutine where the log events will be sent
80+
func (s *Listener) Start() (string, error) {
81+
- address := listenOnAddress()
82+
+ listener, address, err := s.tryBindPort()
83+
+ if err != nil {
84+
+ return "", fmt.Errorf("failed to find available port: %w", err)
85+
+ }
86+
s.logger.Info("Listening for requests", zap.String("address", address))
87+
s.httpServer = &http.Server{Addr: address}
88+
http.HandleFunc("/", s.httpHandler)
89+
go func() {
90+
- err := s.httpServer.ListenAndServe()
91+
+ err := s.httpServer.Serve(listener)
92+
if err != http.ErrServerClosed {
93+
s.logger.Error("Unexpected stop on HTTP Server", zap.Error(err))
94+
s.Shutdown()

patch-upstream.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ patch -p2 < ../../collector.patch
4242
# patch manager.go to remove lambdacomponents attribute
4343
patch -p2 < ../../manager.patch
4444

45+
46+
# patch listener.go to patch port usage
47+
patch -p2 < ../../listener.patch
48+
4549
# Replace OTel Collector with ADOT Collector
4650
go mod edit -replace github.com/open-telemetry/opentelemetry-lambda/collector/lambdacomponents=${CURRENT_DIR}/adot/collector/lambdacomponents
4751

0 commit comments

Comments
 (0)