11package observability
22
33import (
4+ "net/http"
45 "net/url"
56 "os"
67 "strconv"
@@ -12,6 +13,7 @@ const (
1213 BrowserTraceIngressPath = "/api/telemetry/v1/traces"
1314 defaultBrowserTraceSampleRatio = 0.1
1415 browserTraceProxyTargetEnvVar = "WL_BROWSER_OTLP_TRACES_TARGET"
16+ browserTraceHeadersEnvVar = "WL_BROWSER_OTLP_HEADERS"
1517 browserTraceSampleRatioEnvVar = "WL_BROWSER_OTEL_TRACES_SAMPLE_RATIO"
1618)
1719
@@ -60,6 +62,22 @@ func BrowserTraceProxyTarget() string {
6062 return ""
6163}
6264
65+ // BrowserTraceProxyHeaders resolves static headers that should be forwarded to
66+ // the upstream collector for browser OTLP traces.
67+ func BrowserTraceProxyHeaders () http.Header {
68+ for _ , raw := range []string {
69+ strings .TrimSpace (os .Getenv (browserTraceHeadersEnvVar )),
70+ strings .TrimSpace (os .Getenv ("OTEL_EXPORTER_OTLP_TRACES_HEADERS" )),
71+ strings .TrimSpace (os .Getenv ("OTEL_EXPORTER_OTLP_HEADERS" )),
72+ } {
73+ if raw == "" {
74+ continue
75+ }
76+ return parseOTLPHeaders (raw )
77+ }
78+ return nil
79+ }
80+
6381func appendTracePath (raw string ) string {
6482 u , err := url .Parse (raw )
6583 if err != nil {
@@ -75,3 +93,30 @@ func appendTracePath(raw string) string {
7593 u .Path = strings .TrimRight (u .Path , "/" ) + "/v1/traces"
7694 return u .String ()
7795}
96+
97+ func parseOTLPHeaders (raw string ) http.Header {
98+ headers := http.Header {}
99+ for _ , pair := range strings .Split (raw , "," ) {
100+ pair = strings .TrimSpace (pair )
101+ if pair == "" {
102+ continue
103+ }
104+ name , value , ok := strings .Cut (pair , "=" )
105+ if ! ok {
106+ continue
107+ }
108+ name = strings .TrimSpace (name )
109+ value = strings .TrimSpace (value )
110+ if name == "" || value == "" {
111+ continue
112+ }
113+ if decoded , err := url .QueryUnescape (value ); err == nil {
114+ value = decoded
115+ }
116+ headers .Add (name , value )
117+ }
118+ if len (headers ) == 0 {
119+ return nil
120+ }
121+ return headers
122+ }
0 commit comments