Skip to content

Commit

Permalink
Implement trace context propagators
Browse files Browse the repository at this point in the history
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
oleiade committed Jan 16, 2023
1 parent 77143dc commit 9a80844
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 0 deletions.
19 changes: 19 additions & 0 deletions js/modules/k6/experimental/tracing/encoding.go
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)
}
90 changes: 90 additions & 0 deletions js/modules/k6/experimental/tracing/propagator.go
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
}

0 comments on commit 9a80844

Please sign in to comment.