Skip to content
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ require (
github.com/minio/simdjson-go v0.4.5 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/dimfeld/httptreemux.v5/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
github.com/minio/simdjson-go v0.4.5 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contrib/dimfeld/httptreemux.v5/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/google.golang.org/api/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ require (
github.com/minio/simdjson-go v0.4.5 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contrib/google.golang.org/api/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/gorilla/mux/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
github.com/minio/simdjson-go v0.4.5 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contrib/gorilla/mux/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/hashicorp/vault/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ require (
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contrib/hashicorp/vault/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/k8s.io/client-go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ require (
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/onsi/gomega v1.38.3 // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contrib/k8s.io/client-go/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/labstack/echo.v4/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ require (
github.com/minio/simdjson-go v0.4.5 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contrib/labstack/echo.v4/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/labstack/echo.v5/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ require (
github.com/minio/simdjson-go v0.4.5 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df // indirect
github.com/outcaste-io/ristretto v0.2.3 // indirect
github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions contrib/labstack/echo.v5/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions contrib/net/http/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.25.0

require (
github.com/DataDog/dd-trace-go/v2 v2.11.0-dev
github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg v0.0.0-20260624035708-73e5988252df

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't leak into this module.

We should have another dedicated module for the hooks (if we want to go down that path)

github.com/puzpuzpuz/xsync/v3 v3.5.1
github.com/stretchr/testify v1.11.1
)
Expand Down
2 changes: 2 additions & 0 deletions contrib/net/http/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions contrib/net/http/otel.instrumentation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2026 Datadog, Inc.

//go:build tools

//nolint:revive
package http

import (
_ "github.com/DataDog/dd-trace-go/contrib/net/http/v2/otelc"
)
27 changes: 27 additions & 0 deletions contrib/net/http/otelc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache License Version 2.0.
# This product includes software developed at Datadog (https://www.datadoghq.com/).
# Copyright 2026-present Datadog, Inc.
---

net-client:
target: net/http
where:
func: RoundTrip
recv: "*Transport"
do:
- inject_hooks:
before: BeforeRoundTrip
after: AfterRoundTrip
path: github.com/DataDog/dd-trace-go/contrib/net/http/v2/otelc

net-server:
target: net/http
where:
func: ServeHTTP
recv: serverHandler
do:
- inject_hooks:
before: BeforeServeHTTP
after: AfterServeHTTP
path: github.com/DataDog/dd-trace-go/contrib/net/http/v2/otelc
114 changes: 114 additions & 0 deletions contrib/net/http/otelc/roundtrip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Unless explicitly stated otherwise all files in this repository are licensed
// under the Apache License Version 2.0.
// This product includes software developed at Datadog (https://www.datadoghq.com/).
// Copyright 2026 Datadog, Inc.

// Package otelc holds the hook functions that otelc
// (opentelemetry-go-compile-instrumentation) injects into net/http to produce
// Datadog spans. They are referenced by otelc.yaml's inject_hooks rules; the
// tool calls the Before* hook at function entry and the After* hook just before
// the function returns.
//
// This package cannot live under internal/: otelc forces a plain import of it
// into a generated otelc.runtime.go file in the consumer's own package (e.g.
// package main), alongside the //go:linkname trampoline it wires into net/http
// itself. Go's internal-visibility rule would reject that import if this
// package were nested under internal/. These functions are not a supported
// public API — they exist only to satisfy otelc's hook-injection contract.
package otelc

import (
"fmt"
"net/http"
"sync"

"github.com/open-telemetry/opentelemetry-go-compile-instrumentation/pkg/hook"

"github.com/DataDog/dd-trace-go/contrib/net/http/v2/internal/config"
"github.com/DataDog/dd-trace-go/contrib/net/http/v2/internal/wrap"

"github.com/DataDog/dd-trace-go/v2/instrumentation"
"github.com/DataDog/dd-trace-go/v2/instrumentation/env"
"github.com/DataDog/dd-trace-go/v2/instrumentation/httptrace"
"github.com/DataDog/dd-trace-go/v2/instrumentation/options"
)

// tracerVersionHeader is set by the tracer on every request it sends to the
// Datadog agent (see ddtrace/tracer/transport.go). Instrumenting those requests
// would create spans whose submission generates more requests: a span bomb.
// Orchestrion avoids this with a DD__tracer_internal field on http.Transport,
// but otelc has no equivalent join point, so we skip on this header instead.
const tracerVersionHeader = "Datadog-Meta-Tracer-Version"

// BeforeRoundTrip starts a client span for req and stashes the after-hook that
// finishes it. It is injected at the top of (*http.Transport).RoundTrip; the
// receiver is parameter 0 and req is parameter 1.
func BeforeRoundTrip(ictx hook.HookContext, _ *http.Transport, req *http.Request) {
if req.Header.Get(tracerVersionHeader) != "" {
return
}
newReq, after, err := wrap.ObserveRoundTrip(defaultRoundTripperConfig(), req)
if err != nil {
return
}
ictx.SetParam(1, newReq)
ictx.SetData(after)
}

// AfterRoundTrip finishes the client span started by BeforeRoundTrip, applying
// any response/error mutation the after-hook performs.
func AfterRoundTrip(ictx hook.HookContext, resp *http.Response, err error) {
after, ok := ictx.GetData().(wrap.AfterRoundTrip)
if !ok || after == nil {
return
}
resp, err = after(resp, err)
ictx.SetReturnVal(0, resp)
ictx.SetReturnVal(1, err)
}

var (
cfg *config.RoundTripperConfig
cfgOnce sync.Once
)

// defaultRoundTripperConfig mirrors the default client configuration built by
// contrib/net/http/v2/internal/orchestrion so otelc and orchestrion produce
// identical spans.
func defaultRoundTripperConfig() *config.RoundTripperConfig {
cfgOnce.Do(func() {
cfg = &config.RoundTripperConfig{
CommonConfig: config.CommonConfig{
AnalyticsRate: func() float64 {
if options.GetBoolEnv("DD_TRACE_HTTP_ANALYTICS_ENABLED", false) {
return 1.0
}
return config.Instrumentation.AnalyticsRate(true)
}(),
IgnoreRequest: func(*http.Request) bool { return false },
ResourceNamer: func() func(req *http.Request) string {
if options.GetBoolEnv("DD_TRACE_HTTP_CLIENT_RESOURCE_NAME_QUANTIZE", false) {
return func(req *http.Request) string {
return fmt.Sprintf("%s %s", req.Method, httptrace.QuantizeURL(req.URL.Path))
}
}
return func(req *http.Request) string { return fmt.Sprintf("%s %s", req.Method, req.URL.Path) }
}(),
IsStatusError: func() func(int) bool {
envVal := env.Get(config.EnvClientErrorStatuses)
if fn := httptrace.GetErrorCodesFromInput(envVal); fn != nil {
return fn
}
return func(statusCode int) bool { return statusCode >= 400 && statusCode < 500 }
}(),
ServiceName: config.Instrumentation.ServiceName(instrumentation.ComponentClient, nil),
},
Propagation: true,
QueryString: options.GetBoolEnv(config.EnvClientQueryStringEnabled, true),
SpanNamer: func(*http.Request) string {
return config.Instrumentation.OperationName(instrumentation.ComponentClient, nil)
},
}
})
return cfg
}
Loading
Loading