diff --git a/manifests/golang.yml b/manifests/golang.yml index 8dc6af08cc7..41b9806a673 100644 --- a/manifests/golang.yml +++ b/manifests/golang.yml @@ -1262,7 +1262,7 @@ manifest: tests/auto_inject/test_auto_inject_install.py::TestContainerAutoInjectInstallScriptAppsec: v2.0.0 tests/auto_inject/test_auto_inject_install.py::TestHostAutoInjectInstallScriptAppsec: v2.0.0 tests/auto_inject/test_auto_inject_install.py::TestSimpleInstallerAutoInjectManualAppsec: v2.0.0 - tests/cws/test_thread_context_sharing.py::Test_ThreadContextSharing: missing_feature (missing /security/thread_context_sharing endpoint on weblog) + tests/cws/test_thread_context_sharing.py::Test_ThreadContextSharing: v2.11.0-dev tests/debugger/test_debugger_capture_expressions.py::Test_Debugger_Line_Capture_Expressions: v2.2.3 tests/debugger/test_debugger_capture_expressions.py::Test_Debugger_Method_Capture_Expressions: v2.2.3 tests/debugger/test_debugger_capture_expressions.py::Test_Debugger_Method_Capture_Expressions::test_complex_capture_expressions: missing_feature (index expression not yet supported in Go system-probe) diff --git a/utils/build/docker/golang/app/_shared/common/thread_context_sharing.go b/utils/build/docker/golang/app/_shared/common/thread_context_sharing.go new file mode 100644 index 00000000000..31b22f39105 --- /dev/null +++ b/utils/build/docker/golang/app/_shared/common/thread_context_sharing.go @@ -0,0 +1,50 @@ +package common + +import ( + "encoding/json" + "math/big" + "net/http" + "os" + "strconv" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" +) + +func ThreadContextSharing(w http.ResponseWriter, r *http.Request) { + span, ok := tracer.SpanFromContext(r.Context()) + if !ok { + w.WriteHeader(http.StatusInternalServerError) + return + } + + path := r.URL.Query().Get("path") + if err := os.WriteFile(path, []byte("system-tests thread context sharing"), 0o644); err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + // SpanContext.TraceID() returns the full 128-bit trace id as a hex string; + // convert it to decimal to match the other weblogs' response format. + traceID, ok := new(big.Int).SetString(span.Context().TraceID(), 16) + if !ok { + w.WriteHeader(http.StatusInternalServerError) + return + } + + jsonResponse, err := json.Marshal(struct { + TraceID string `json:"trace_id"` + SpanID string `json:"span_id"` + }{ + TraceID: traceID.String(), + SpanID: strconv.FormatUint(span.Context().SpanID(), 10), + }) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + return + } + + w.Header().Set("Content-Type", "application/json") + if _, err := w.Write(jsonResponse); err != nil { + return + } +} diff --git a/utils/build/docker/golang/app/chi/main.go b/utils/build/docker/golang/app/chi/main.go index 052b190b3a5..b85532021b5 100644 --- a/utils/build/docker/golang/app/chi/main.go +++ b/utils/build/docker/golang/app/chi/main.go @@ -156,6 +156,7 @@ func main() { }) mux.HandleFunc("/trace/manual_keep_drop", common.ManualKeepDrop) + mux.HandleFunc("/security/thread_context_sharing", common.ThreadContextSharing) mux.HandleFunc("/make_distant_call", func(w http.ResponseWriter, r *http.Request) { url := r.URL.Query().Get("url") diff --git a/utils/build/docker/golang/app/echo/main.go b/utils/build/docker/golang/app/echo/main.go index e7db727b2fc..631076f9a44 100644 --- a/utils/build/docker/golang/app/echo/main.go +++ b/utils/build/docker/golang/app/echo/main.go @@ -168,6 +168,7 @@ func main() { }) r.Any("/trace/manual_keep_drop", echoHandleFunc(common.ManualKeepDrop)) + r.Any("/security/thread_context_sharing", echoHandleFunc(common.ThreadContextSharing)) r.Any("/make_distant_call", func(c echo.Context) error { url := c.Request().URL.Query().Get("url") diff --git a/utils/build/docker/golang/app/gin/main.go b/utils/build/docker/golang/app/gin/main.go index 01c669a1aee..1b8b3e4a913 100644 --- a/utils/build/docker/golang/app/gin/main.go +++ b/utils/build/docker/golang/app/gin/main.go @@ -158,6 +158,7 @@ func main() { }) r.Any("/trace/manual_keep_drop", ginHandleFunc(common.ManualKeepDrop)) + r.Any("/security/thread_context_sharing", ginHandleFunc(common.ThreadContextSharing)) r.Any("/make_distant_call", func(ctx *gin.Context) { url := ctx.Request.URL.Query().Get("url") diff --git a/utils/build/docker/golang/app/gqlgen/server.go b/utils/build/docker/golang/app/gqlgen/server.go index 2ceed64f89f..45692694115 100644 --- a/utils/build/docker/golang/app/gqlgen/server.go +++ b/utils/build/docker/golang/app/gqlgen/server.go @@ -49,6 +49,7 @@ func main() { }) mux.HandleFunc("/trace/manual_keep_drop", common.ManualKeepDrop) + mux.HandleFunc("/security/thread_context_sharing", common.ThreadContextSharing) mux.HandleFunc("/healthcheck", func(w http.ResponseWriter, r *http.Request) { diff --git a/utils/build/docker/golang/app/graph-gophers/main.go b/utils/build/docker/golang/app/graph-gophers/main.go index e701167648a..7f50580cde2 100644 --- a/utils/build/docker/golang/app/graph-gophers/main.go +++ b/utils/build/docker/golang/app/graph-gophers/main.go @@ -62,6 +62,7 @@ func main() { }) mux.HandleFunc("/trace/manual_keep_drop", common.ManualKeepDrop) + mux.HandleFunc("/security/thread_context_sharing", common.ThreadContextSharing) mux.HandleFunc("/healthcheck", func(w http.ResponseWriter, r *http.Request) { diff --git a/utils/build/docker/golang/app/graphql-go/main.go b/utils/build/docker/golang/app/graphql-go/main.go index 55a62a7e2fc..7f1ff17fe92 100644 --- a/utils/build/docker/golang/app/graphql-go/main.go +++ b/utils/build/docker/golang/app/graphql-go/main.go @@ -90,6 +90,7 @@ func main() { }) mux.HandleFunc("/trace/manual_keep_drop", common.ManualKeepDrop) + mux.HandleFunc("/security/thread_context_sharing", common.ThreadContextSharing) mux.HandleFunc("/healthcheck", func(w http.ResponseWriter, r *http.Request) { diff --git a/utils/build/docker/golang/app/net-http-orchestrion/main.go b/utils/build/docker/golang/app/net-http-orchestrion/main.go index e433e59a347..b9cda1a1f41 100644 --- a/utils/build/docker/golang/app/net-http-orchestrion/main.go +++ b/utils/build/docker/golang/app/net-http-orchestrion/main.go @@ -146,6 +146,7 @@ func main() { }) mux.HandleFunc("/trace/manual_keep_drop", common.ManualKeepDrop) + mux.HandleFunc("/security/thread_context_sharing", common.ThreadContextSharing) mux.HandleFunc("/make_distant_call", func(w http.ResponseWriter, r *http.Request) { url := r.URL.Query().Get("url") diff --git a/utils/build/docker/golang/app/net-http-span-pool/main.go b/utils/build/docker/golang/app/net-http-span-pool/main.go index f4ec9ff4835..f99de5abc05 100644 --- a/utils/build/docker/golang/app/net-http-span-pool/main.go +++ b/utils/build/docker/golang/app/net-http-span-pool/main.go @@ -189,6 +189,7 @@ func main() { }) mux.HandleFunc("/trace/manual_keep_drop", common.ManualKeepDrop) + mux.HandleFunc("/security/thread_context_sharing", common.ThreadContextSharing) mux.HandleFunc("/make_distant_call", func(w http.ResponseWriter, r *http.Request) { url := r.URL.Query().Get("url") diff --git a/utils/build/docker/golang/app/net-http/main.go b/utils/build/docker/golang/app/net-http/main.go index 343fce50cd9..a802fe3ccfb 100644 --- a/utils/build/docker/golang/app/net-http/main.go +++ b/utils/build/docker/golang/app/net-http/main.go @@ -194,6 +194,7 @@ func main() { mux.HandleFunc("/spawn_child", common.SpawnChild) mux.HandleFunc("/trace/manual_keep_drop", common.ManualKeepDrop) + mux.HandleFunc("/security/thread_context_sharing", common.ThreadContextSharing) mux.HandleFunc("/make_distant_call", func(w http.ResponseWriter, r *http.Request) { url := r.URL.Query().Get("url") diff --git a/utils/build/docker/golang/weblog_metadata.yml b/utils/build/docker/golang/weblog_metadata.yml index 51f16fe6e1d..3538e596a7b 100644 --- a/utils/build/docker/golang/weblog_metadata.yml +++ b/utils/build/docker/golang/weblog_metadata.yml @@ -1,3 +1,4 @@ +--- # docs/understand/weblogs/weblog-metadata.md haproxy: @@ -11,12 +12,15 @@ apim: supported_scenarios: [APPSEC_BLOCKING, DEFAULT] graphql-go: categories: [dd_trace_graphql] + supported_scenarios: [THREAD_CONTEXT_SHARING] excluded_scenarios: [GRAPHQL_ERROR_TRACKING] # why ??? gqlgen: categories: [dd_trace_graphql] + supported_scenarios: [THREAD_CONTEXT_SHARING] excluded_scenarios: [GRAPHQL_ERROR_TRACKING] # why ??? graph-gophers: categories: [dd_trace_graphql] + supported_scenarios: [THREAD_CONTEXT_SHARING] excluded_scenarios: [GRAPHQL_ERROR_TRACKING] # why ??? echo: categories: [dd_trace]