@@ -18,20 +18,23 @@ import (
18
18
"context"
19
19
"encoding/hex"
20
20
"fmt"
21
+ "net/url"
21
22
"regexp"
22
23
"strconv"
23
24
"strings"
24
25
25
- "go.opentelemetry.io/api/trace"
26
-
27
26
"go.opentelemetry.io/api/core"
27
+ dctx "go.opentelemetry.io/api/distributedcontext"
28
+ "go.opentelemetry.io/api/key"
28
29
apipropagation "go.opentelemetry.io/api/propagation"
30
+ "go.opentelemetry.io/api/trace"
29
31
)
30
32
31
33
const (
32
- supportedVersion = 0
33
- maxVersion = 254
34
- TraceparentHeader = "Traceparent"
34
+ supportedVersion = 0
35
+ maxVersion = 254
36
+ TraceparentHeader = "Traceparent"
37
+ CorrelationContextHeader = "Correlation-Context"
35
38
)
36
39
37
40
// HTTPTraceContextPropagator propagates SpanContext in W3C TraceContext format.
@@ -51,9 +54,35 @@ func (hp HTTPTraceContextPropagator) Inject(ctx context.Context, supplier apipro
51
54
sc .TraceFlags & core .TraceFlagsSampled )
52
55
supplier .Set (TraceparentHeader , h )
53
56
}
57
+
58
+ correlationCtx := dctx .FromContext (ctx )
59
+ firstIter := true
60
+ var headerValueBuilder strings.Builder
61
+ correlationCtx .Foreach (func (kv core.KeyValue ) bool {
62
+ if ! firstIter {
63
+ headerValueBuilder .WriteRune (',' )
64
+ }
65
+ firstIter = false
66
+ headerValueBuilder .WriteString (url .QueryEscape (strings .TrimSpace ((string )(kv .Key ))))
67
+ headerValueBuilder .WriteRune ('=' )
68
+ headerValueBuilder .WriteString (url .QueryEscape (strings .TrimSpace (kv .Value .Emit ())))
69
+ return true
70
+ })
71
+ if headerValueBuilder .Len () > 0 {
72
+ headerString := headerValueBuilder .String ()
73
+ supplier .Set (CorrelationContextHeader , headerString )
74
+ }
54
75
}
55
76
56
- func (hp HTTPTraceContextPropagator ) Extract (ctx context.Context , supplier apipropagation.Supplier ) core.SpanContext {
77
+ func (hp HTTPTraceContextPropagator ) Extract (
78
+ ctx context.Context , supplier apipropagation.Supplier ,
79
+ ) (core.SpanContext , dctx.Map ) {
80
+ return hp .extractSpanContext (ctx , supplier ), hp .extractCorrelationCtx (ctx , supplier )
81
+ }
82
+
83
+ func (hp HTTPTraceContextPropagator ) extractSpanContext (
84
+ ctx context.Context , supplier apipropagation.Supplier ,
85
+ ) core.SpanContext {
57
86
h := supplier .Get (TraceparentHeader )
58
87
if h == "" {
59
88
return core .EmptySpanContext ()
@@ -128,6 +157,50 @@ func (hp HTTPTraceContextPropagator) Extract(ctx context.Context, supplier apipr
128
157
return sc
129
158
}
130
159
160
+ func (hp HTTPTraceContextPropagator ) extractCorrelationCtx (ctx context.Context , supplier apipropagation.Supplier ) dctx.Map {
161
+ correlationContext := supplier .Get (CorrelationContextHeader )
162
+ if correlationContext == "" {
163
+ return dctx .NewEmptyMap ()
164
+ }
165
+
166
+ contextValues := strings .Split (correlationContext , "," )
167
+ keyValues := make ([]core.KeyValue , 0 , len (contextValues ))
168
+ for _ , contextValue := range contextValues {
169
+ valueAndProps := strings .Split (contextValue , ";" )
170
+ if len (valueAndProps ) < 1 {
171
+ continue
172
+ }
173
+ nameValue := strings .Split (valueAndProps [0 ], "=" )
174
+ if len (nameValue ) < 2 {
175
+ continue
176
+ }
177
+ name , err := url .QueryUnescape (nameValue [0 ])
178
+ if err != nil {
179
+ continue
180
+ }
181
+ trimmedName := strings .TrimSpace (name )
182
+ value , err := url .QueryUnescape (nameValue [1 ])
183
+ if err != nil {
184
+ continue
185
+ }
186
+ trimmedValue := strings .TrimSpace (value )
187
+
188
+ // TODO (skaris): properties defiend https://w3c.github.io/correlation-context/, are currently
189
+ // just put as part of the value.
190
+ var trimmedValueWithProps strings.Builder
191
+ trimmedValueWithProps .WriteString (trimmedValue )
192
+ for _ , prop := range valueAndProps [1 :] {
193
+ trimmedValueWithProps .WriteRune (';' )
194
+ trimmedValueWithProps .WriteString (prop )
195
+ }
196
+
197
+ keyValues = append (keyValues , key .New (trimmedName ).String (trimmedValueWithProps .String ()))
198
+ }
199
+ return dctx .NewMap (dctx.MapUpdate {
200
+ MultiKV : keyValues ,
201
+ })
202
+ }
203
+
131
204
func (hp HTTPTraceContextPropagator ) GetAllKeys () []string {
132
- return []string {TraceparentHeader }
205
+ return []string {TraceparentHeader , CorrelationContextHeader }
133
206
}
0 commit comments