Skip to content

Commit

Permalink
Run tests against Go. This one differs specifically because we don't …
Browse files Browse the repository at this point in the history
…run automatic instrumentation in the typical dd-trace-go setup, so the user is expected to set the default propagator. This test simply tests that using the API `otel.GetTextMapPropagator()` works as expected
  • Loading branch information
zacharycmontoya committed Jan 18, 2025
1 parent 6ad0a30 commit 247982b
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 0 deletions.
3 changes: 3 additions & 0 deletions manifests/golang.yml
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ tests/:
Test_AWS_API_Gateway_Inferred_Span_Creation: missing_feature
test_otel_drop_in.py:
Test_Otel_Drop_In: missing_feature
Test_Otel_Drop_In_Default_Propagator:
'*': irrelevant
net-http: v1.70.1
parametric/:
test_config_consistency.py:
Test_Config_Dogstatsd: missing_feature
Expand Down
112 changes: 112 additions & 0 deletions utils/build/docker/golang/app/net-http/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"go.opentelemetry.io/otel/propagation"
"go.opentelemetry.io/otel/trace"
oteltrace "go.opentelemetry.io/otel/trace"
otelbaggage "go.opentelemetry.io/otel/baggage"

"gopkg.in/DataDog/dd-trace-go.v1/appsec"
httptrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/net/http"
Expand Down Expand Up @@ -537,6 +538,79 @@ func main() {
w.Write([]byte("ok"))
})

mux.HandleFunc("/otel_drop_in_default_propagator_extract", func(w http.ResponseWriter, r *http.Request) {
// Differing from other languages, the user must set the text map propagator because dd-trace-go
// doesn't automatically instrument at runtime (not including Orchestrion)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

httpCarrier := HttpCarrier{header: r.Header}

propagator := otel.GetTextMapPropagator()
ctx := propagator.Extract(r.Context(), httpCarrier)

spanContext := oteltrace.SpanContextFromContext(ctx)
baggage := otelbaggage.FromContext(ctx)

base := 16
bitSize := 64
result := make(map[string]any, 4)

num, err := strconv.ParseInt(spanContext.TraceID().String()[16:], base, bitSize)
if err == nil {
result["trace_id"] = num
}

num, err = strconv.ParseInt(spanContext.SpanID().String(), base, bitSize)
if err == nil {
result["span_id"] = num
}

result["tracestate"] = spanContext.TraceState().String()
result["baggage"] = baggage.String()

jsonData, err := json.Marshal(result)
if err != nil {
w.WriteHeader(422)
w.Write([]byte("failed to convert carrier to JSON"))
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
w.Write(jsonData)
})

mux.HandleFunc("/otel_drop_in_default_propagator_inject", func(w http.ResponseWriter, r *http.Request) {
// Differing from other languages, the user must set the text map propagator because dd-trace-go
// doesn't automatically instrument at runtime (not including Orchestrion)
otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}))

ctx := context.Background()
p := ddotel.NewTracerProvider()
tracer := p.Tracer("")
otel.SetTracerProvider(p)

_, span := tracer.Start(ddotel.ContextWithStartOptions(ctx), "main")
newCtx := oteltrace.ContextWithSpan(ctx, span)

propagator := otel.GetTextMapPropagator()
mapCarrier := make(MapCarrier)
propagator.Inject(newCtx, mapCarrier)

jsonData, err := json.Marshal(mapCarrier)
span.End()

if err != nil {
w.WriteHeader(422)
w.Write([]byte("failed to convert carrier to JSON"))
return
}

w.Header().Set("Content-Type", "application/json")
w.WriteHeader(200)
w.Write(jsonData)
})

mux.HandleFunc("/session/new", func(w http.ResponseWriter, r *http.Request) {
sessionID := strconv.Itoa(rand.Int())
w.Header().Add("Set-Cookie", "session="+sessionID+"; Path=/; Max-Age=3600; Secure; HttpOnly")
Expand Down Expand Up @@ -598,6 +672,44 @@ func (c carrier) ForeachKey(handler func(key, val string) error) error {
return nil
}

type MapCarrier map[string]string

func (c MapCarrier) Get(key string) string {
return c[key]
}

func (c MapCarrier) Set(key, val string) {
c[key] = val
}

func (c MapCarrier) Keys() []string {
keys := make([]string, 0, len(c))
for k := range c {
keys = append(keys, k)
}
return keys
}

type HttpCarrier struct {
header http.Header
}

func (c HttpCarrier) Get(key string) string {
return c.header.Get(key)
}

func (c HttpCarrier) Set(key, val string) {
c.header.Set(key, val)
}

func (c HttpCarrier) Keys() []string {
keys := make([]string, 0, len(c.header))
for k := range c.header {
keys = append(keys, k)
}
return keys
}

func write(w http.ResponseWriter, r *http.Request, d []byte) {
span, _ := ddtracer.StartSpanFromContext(r.Context(), "child.span")
defer span.Finish()
Expand Down

0 comments on commit 247982b

Please sign in to comment.