Skip to content
This repository was archived by the owner on Jul 31, 2023. It is now read-only.

Commit 3456e1d

Browse files
Made public traceparent/tracestate marshal/unmarshal (#1218)
1 parent af30f77 commit 3456e1d

File tree

2 files changed

+58
-17
lines changed

2 files changed

+58
-17
lines changed

plugin/ochttp/propagation/tracecontext/propagation.go

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,17 @@ type HTTPFormat struct{}
4747

4848
// SpanContextFromRequest extracts a span context from incoming requests.
4949
func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanContext, ok bool) {
50-
h, ok := getRequestHeader(req, traceparentHeader, false)
51-
if !ok {
50+
tp, _ := getRequestHeader(req, traceparentHeader, false)
51+
ts, _ := getRequestHeader(req, tracestateHeader, true)
52+
return f.SpanContextFromHeaders(tp, ts)
53+
}
54+
55+
// SpanContextFromHeaders extracts a span context from provided header values.
56+
func (f *HTTPFormat) SpanContextFromHeaders(tp string, ts string) (sc trace.SpanContext, ok bool) {
57+
if tp == "" {
5258
return trace.SpanContext{}, false
5359
}
54-
sections := strings.Split(h, "-")
60+
sections := strings.Split(tp, "-")
5561
if len(sections) < 4 {
5662
return trace.SpanContext{}, false
5763
}
@@ -101,7 +107,7 @@ func (f *HTTPFormat) SpanContextFromRequest(req *http.Request) (sc trace.SpanCon
101107
return trace.SpanContext{}, false
102108
}
103109

104-
sc.Tracestate = tracestateFromRequest(req)
110+
sc.Tracestate = tracestateFromHeader(ts)
105111
return sc, true
106112
}
107113

@@ -128,14 +134,13 @@ func getRequestHeader(req *http.Request, name string, commaSeparated bool) (hdr
128134
// are resolved.
129135
// https://github.com/w3c/distributed-tracing/issues/172
130136
// https://github.com/w3c/distributed-tracing/issues/175
131-
func tracestateFromRequest(req *http.Request) *tracestate.Tracestate {
132-
h, _ := getRequestHeader(req, tracestateHeader, true)
133-
if h == "" {
137+
func tracestateFromHeader(ts string) *tracestate.Tracestate {
138+
if ts == "" {
134139
return nil
135140
}
136141

137142
var entries []tracestate.Entry
138-
pairs := strings.Split(h, ",")
143+
pairs := strings.Split(ts, ",")
139144
hdrLenWithoutOWS := len(pairs) - 1 // Number of commas
140145
for _, pair := range pairs {
141146
matches := trimOWSRegExp.FindStringSubmatch(pair)
@@ -153,15 +158,15 @@ func tracestateFromRequest(req *http.Request) *tracestate.Tracestate {
153158
}
154159
entries = append(entries, tracestate.Entry{Key: kv[0], Value: kv[1]})
155160
}
156-
ts, err := tracestate.New(nil, entries...)
161+
tsParsed, err := tracestate.New(nil, entries...)
157162
if err != nil {
158163
return nil
159164
}
160165

161-
return ts
166+
return tsParsed
162167
}
163168

164-
func tracestateToRequest(sc trace.SpanContext, req *http.Request) {
169+
func tracestateToHeader(sc trace.SpanContext) string {
165170
var pairs = make([]string, 0, len(sc.Tracestate.Entries()))
166171
if sc.Tracestate != nil {
167172
for _, entry := range sc.Tracestate.Entries() {
@@ -170,18 +175,28 @@ func tracestateToRequest(sc trace.SpanContext, req *http.Request) {
170175
h := strings.Join(pairs, ",")
171176

172177
if h != "" && len(h) <= maxTracestateLen {
173-
req.Header.Set(tracestateHeader, h)
178+
return h
174179
}
175180
}
181+
return ""
176182
}
177183

178-
// SpanContextToRequest modifies the given request to include traceparent and tracestate headers.
179-
func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) {
180-
h := fmt.Sprintf("%x-%x-%x-%x",
184+
// SpanContextToHeaders serialize the SpanContext to traceparent and tracestate headers.
185+
func (f *HTTPFormat) SpanContextToHeaders(sc trace.SpanContext) (tp string, ts string) {
186+
tp = fmt.Sprintf("%x-%x-%x-%x",
181187
[]byte{supportedVersion},
182188
sc.TraceID[:],
183189
sc.SpanID[:],
184190
[]byte{byte(sc.TraceOptions)})
185-
req.Header.Set(traceparentHeader, h)
186-
tracestateToRequest(sc, req)
191+
ts = tracestateToHeader(sc)
192+
return
193+
}
194+
195+
// SpanContextToRequest modifies the given request to include traceparent and tracestate headers.
196+
func (f *HTTPFormat) SpanContextToRequest(sc trace.SpanContext, req *http.Request) {
197+
tp, ts := f.SpanContextToHeaders(sc)
198+
req.Header.Set(traceparentHeader, tp)
199+
if ts != "" {
200+
req.Header.Set(tracestateHeader, ts)
201+
}
187202
}

plugin/ochttp/propagation/tracecontext/propagation_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ func TestHTTPFormat_FromRequest(t *testing.T) {
100100
if gotOk != tt.wantOk {
101101
t.Errorf("HTTPFormat.FromRequest() gotOk = %v, want %v", gotOk, tt.wantOk)
102102
}
103+
104+
gotSc, gotOk = f.SpanContextFromHeaders(tt.header, "")
105+
if !reflect.DeepEqual(gotSc, tt.wantSc) {
106+
t.Errorf("HTTPFormat.SpanContextFromHeaders() gotTs = %v, want %v", gotSc.Tracestate, tt.wantSc.Tracestate)
107+
}
108+
if gotOk != tt.wantOk {
109+
t.Errorf("HTTPFormat.SpanContextFromHeaders() gotOk = %v, want %v", gotOk, tt.wantOk)
110+
}
103111
})
104112
}
105113
}
@@ -128,6 +136,11 @@ func TestHTTPFormat_ToRequest(t *testing.T) {
128136
if got, want := h, tt.wantHeader; got != want {
129137
t.Errorf("HTTPFormat.ToRequest() header = %v, want %v", got, want)
130138
}
139+
140+
gotTp, _ := f.SpanContextToHeaders(tt.sc)
141+
if gotTp != tt.wantHeader {
142+
t.Errorf("HTTPFormat.SpanContextToHeaders() tracestate header = %v, want %v", gotTp, tt.wantHeader)
143+
}
131144
})
132145
}
133146
}
@@ -212,6 +225,14 @@ func TestHTTPFormatTracestate_FromRequest(t *testing.T) {
212225
if gotOk != tt.wantOk {
213226
t.Errorf("HTTPFormat.FromRequest() gotOk = %v, want %v", gotOk, tt.wantOk)
214227
}
228+
229+
gotSc, gotOk = f.SpanContextFromHeaders(tt.tpHeader, tt.tsHeader)
230+
if !reflect.DeepEqual(gotSc, tt.wantSc) {
231+
t.Errorf("HTTPFormat.SpanContextFromHeaders() gotTs = %v, want %v", gotSc.Tracestate, tt.wantSc.Tracestate)
232+
}
233+
if gotOk != tt.wantOk {
234+
t.Errorf("HTTPFormat.SpanContextFromHeaders() gotOk = %v, want %v", gotOk, tt.wantOk)
235+
}
215236
})
216237
}
217238
}
@@ -262,6 +283,11 @@ func TestHTTPFormatTracestate_ToRequest(t *testing.T) {
262283
if got, want := h, tt.wantHeader; got != want {
263284
t.Errorf("HTTPFormat.ToRequest() tracestate header = %v, want %v", got, want)
264285
}
286+
287+
_, gotTs := f.SpanContextToHeaders(tt.sc)
288+
if gotTs != tt.wantHeader {
289+
t.Errorf("HTTPFormat.SpanContextToHeaders() tracestate header = %v, want %v", gotTs, tt.wantHeader)
290+
}
265291
})
266292
}
267293
}

0 commit comments

Comments
 (0)