Skip to content

Commit f6d83fe

Browse files
delavetrlakhtakia
authored andcommitted
Parse request x-request-id and expose it in contextual logger (#746)
* parse x-request-id and expose in contextual logger Signed-off-by: Hang Yin <[email protected]> * make ExtractHeaderValue a general func --------- Signed-off-by: Hang Yin <[email protected]>
1 parent e004dad commit f6d83fe

File tree

4 files changed

+95
-0
lines changed

4 files changed

+95
-0
lines changed

pkg/bbr/handlers/server.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"google.golang.org/grpc/status"
2929
"sigs.k8s.io/controller-runtime/pkg/log"
3030
logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
31+
requtil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/request"
3132
)
3233

3334
func NewServer(streaming bool) *Server {
@@ -74,6 +75,11 @@ func (s *Server) Process(srv extProcPb.ExternalProcessor_ProcessServer) error {
7475
// If streaming and the body is not empty, then headers are handled when processing request body.
7576
loggerVerbose.Info("Received headers, passing off header processing until body arrives...")
7677
} else {
78+
if requestId := requtil.ExtractHeaderValue(v, requtil.RequestIdHeaderKey); len(requestId) > 0 {
79+
logger = logger.WithValues(requtil.RequestIdHeaderKey, requestId)
80+
loggerVerbose = logger.V(logutil.VERBOSE)
81+
ctx = log.IntoContext(ctx, logger)
82+
}
7783
responses, err = s.HandleRequestHeaders(req.GetRequestHeaders())
7884
}
7985
case *extProcPb.ProcessingRequest_RequestBody:

pkg/epp/handlers/server.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
schedulingtypes "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types"
4141
errutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/error"
4242
logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging"
43+
requtil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/request"
4344
)
4445

4546
func NewStreamingServer(scheduler Scheduler, destinationEndpointHintMetadataNamespace, destinationEndpointHintKey string, datastore datastore.Datastore) *StreamingServer {
@@ -167,6 +168,11 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer)
167168

168169
switch v := req.Request.(type) {
169170
case *extProcPb.ProcessingRequest_RequestHeaders:
171+
if requestId := requtil.ExtractHeaderValue(v, requtil.RequestIdHeaderKey); len(requestId) > 0 {
172+
logger = logger.WithValues(requtil.RequestIdHeaderKey, requestId)
173+
loggerTrace = logger.V(logutil.TRACE)
174+
ctx = log.IntoContext(ctx, logger)
175+
}
170176
err = s.HandleRequestHeaders(ctx, reqCtx, v)
171177
case *extProcPb.ProcessingRequest_RequestBody:
172178
loggerTrace.Info("Incoming body chunk", "EoS", v.RequestBody.EndOfStream)

pkg/epp/util/request/headers.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package request
2+
3+
import (
4+
"strings"
5+
6+
extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
7+
)
8+
9+
const (
10+
RequestIdHeaderKey = "x-request-id"
11+
)
12+
13+
func ExtractHeaderValue(req *extProcPb.ProcessingRequest_RequestHeaders, headerKey string) string {
14+
// header key should be case insensitive
15+
headerKeyInLower := strings.ToLower(headerKey)
16+
if req != nil && req.RequestHeaders != nil && req.RequestHeaders.Headers != nil {
17+
for _, headerKv := range req.RequestHeaders.Headers.Headers {
18+
if strings.ToLower(headerKv.Key) == headerKeyInLower {
19+
return string(headerKv.RawValue)
20+
}
21+
}
22+
}
23+
return ""
24+
}

pkg/epp/util/request/headers_test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package request
2+
3+
import (
4+
"testing"
5+
6+
corev3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3"
7+
extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3"
8+
)
9+
10+
func TestExtractHeaderValue(t *testing.T) {
11+
tests := []struct {
12+
name string
13+
headers []*corev3.HeaderValue
14+
key string
15+
expected string
16+
}{
17+
{
18+
name: "Exact match",
19+
headers: []*corev3.HeaderValue{
20+
{Key: "x-request-id", RawValue: []byte("123")},
21+
},
22+
key: "x-request-id",
23+
expected: "123",
24+
},
25+
{
26+
name: "Case-insensitive match",
27+
headers: []*corev3.HeaderValue{
28+
{Key: "X-Request-ID", RawValue: []byte("456")},
29+
},
30+
key: "x-request-id",
31+
expected: "456",
32+
},
33+
{
34+
name: "Non-existent key",
35+
headers: []*corev3.HeaderValue{
36+
{Key: "other-header", RawValue: []byte("abc")},
37+
},
38+
key: "x-request-id",
39+
expected: "",
40+
},
41+
}
42+
43+
for _, tt := range tests {
44+
t.Run(tt.name, func(t *testing.T) {
45+
req := &extProcPb.ProcessingRequest_RequestHeaders{
46+
RequestHeaders: &extProcPb.HttpHeaders{
47+
Headers: &corev3.HeaderMap{
48+
Headers: tt.headers,
49+
},
50+
},
51+
}
52+
53+
result := ExtractHeaderValue(req, tt.key)
54+
if result != tt.expected {
55+
t.Errorf("ExtractHeaderValue() = %v, want %v", result, tt.expected)
56+
}
57+
})
58+
}
59+
}

0 commit comments

Comments
 (0)