-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This commit implements the trace-context propagation logic, and allows for the creation of trace context headers in the W3C, B3 (openzipkin), and Jaeger formats. Note that a lot of the code and logic present in this commit are inherited and refactored from the xk6-distributed-tracing project.
- Loading branch information
Showing
2 changed files
with
109 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package tracing | ||
|
||
import ( | ||
"math/rand" | ||
) | ||
|
||
// randHexStringRunes returns a random string of n hex characters. | ||
// | ||
// Note that this function uses a non-cryptographic random number generator. | ||
func randHexString(n int) string { | ||
hexRunes := []rune("123456789abcdef") | ||
|
||
b := make([]rune, n) | ||
for i := range b { | ||
b[i] = hexRunes[rand.Intn(len(hexRunes))] //nolint:gosec | ||
} | ||
|
||
return string(b) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package tracing | ||
|
||
import ( | ||
"net/http" | ||
) | ||
|
||
// Propagator is an interface for trace context propagation | ||
type Propagator interface { | ||
Propagate(traceID string) (http.Header, error) | ||
} | ||
|
||
const ( | ||
// W3CPropagatorName is the name of the W3C trace context propagator | ||
W3CPropagatorName = "w3c" | ||
|
||
// W3CHeaderName is the name of the W3C trace context header | ||
W3CHeaderName = "traceparent" | ||
|
||
// W3CVersion is the version of the supported W3C trace context header. | ||
// The current specification assumes the version is set to 00. | ||
W3CVersion = "00" | ||
|
||
// W3CUnsampledTraceFlag is the trace-flag value for an unsampled trace. | ||
W3CUnsampledTraceFlag = "00" | ||
|
||
// W3CSampledTraceFlag is the trace-flag value for a sampled trace. | ||
W3CSampledTraceFlag = "01" | ||
) | ||
|
||
// W3CPropagator is a Propagator for the W3C trace context header | ||
type W3CPropagator struct{} | ||
|
||
// Propagate returns a header with a random trace ID in the W3C format | ||
func (p *W3CPropagator) Propagate(traceID string) (http.Header, error) { | ||
parentID := randHexString(16) | ||
|
||
return http.Header{ | ||
W3CHeaderName: { | ||
W3CVersion + "-" + traceID + "-" + parentID + "-" + W3CSampledTraceFlag, | ||
}, | ||
}, nil | ||
} | ||
|
||
const ( | ||
// B3PropagatorName is the name of the B3 trace context propagator | ||
B3PropagatorName = "b3" | ||
|
||
// B3HeaderName is the name of the B3 trace context header | ||
B3HeaderName = B3PropagatorName | ||
) | ||
|
||
// B3Propagator is a Propagator for the B3 trace context header | ||
type B3Propagator struct{} | ||
|
||
// Propagate returns a header with a random trace ID in the B3 format | ||
func (p *B3Propagator) Propagate(traceID string) (http.Header, error) { | ||
parentID := randHexString(8) | ||
parentSpanID := "1" | ||
|
||
return http.Header{ | ||
B3HeaderName: {traceID + "-" + parentID + "-" + parentSpanID}, | ||
}, nil | ||
} | ||
|
||
const ( | ||
// JaegerPropagatorName is the name of the Jaeger trace context propagator | ||
JaegerPropagatorName = "jaeger" | ||
|
||
// JaegerHeaderName is the name of the Jaeger trace context header | ||
JaegerHeaderName = "uber-trace-id" | ||
|
||
// JaegerRootSpanID is the universal span ID of the root span. | ||
// Its value is zero, which is described in the Jaeger documentation as: | ||
// "0 value is valid and means “root span” (when not ignored)" | ||
JaegerRootSpanID = "0" | ||
) | ||
|
||
// JaegerPropagator is a Propagator for the Jaeger trace context header | ||
type JaegerPropagator struct{} | ||
|
||
// Propagate returns a header with a random trace ID in the Jaeger format | ||
func (p *JaegerPropagator) Propagate(traceID string) (http.Header, error) { | ||
spanID := randHexString(8) | ||
// flags set to 1 means the span is sampled | ||
flags := "1" | ||
|
||
return http.Header{ | ||
JaegerHeaderName: {traceID + ":" + spanID + ":" + JaegerRootSpanID + ":" + flags}, | ||
}, nil | ||
} |