diff --git a/contrib/go.uber.org/zap/go.mod b/contrib/go.uber.org/zap/go.mod new file mode 100644 index 0000000000..0b43883561 --- /dev/null +++ b/contrib/go.uber.org/zap/go.mod @@ -0,0 +1,82 @@ +module github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 + +go 1.25.0 + +require ( + github.com/DataDog/dd-trace-go/v2 v2.11.0-dev + github.com/stretchr/testify v1.11.1 + go.uber.org/zap v1.28.0 +) + +require ( + github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/obfuscate v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/proto v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/trace v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/trace/log v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/trace/stats v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-agent/pkg/trace/traceutil v0.82.0-rc.2 // indirect + github.com/DataDog/datadog-go/v5 v5.9.0 // indirect + github.com/DataDog/go-libddwaf/v5 v5.0.0 // indirect + github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20260217080614-b0f4edc38a6d // indirect + github.com/DataDog/go-sqllexer v0.2.3 // indirect + github.com/DataDog/go-tuf v1.1.1-0.5.2 // indirect + github.com/DataDog/sketches-go v1.4.8 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/dustin/go-humanize v1.0.1 // indirect + github.com/ebitengine/purego v0.10.0 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/go-version v1.9.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.18.6 // indirect + github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/linkdata/deadlock v0.5.5 // indirect + github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e // indirect + 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/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 + github.com/pkg/errors v0.9.1 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect + github.com/puzpuzpuz/xsync/v4 v4.5.0 // indirect + github.com/secure-systems-lab/go-securesystemslib v0.11.0 // indirect + github.com/shirou/gopsutil/v4 v4.26.6 // indirect + github.com/tinylib/msgp v1.6.4 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect + github.com/trailofbits/go-mutexasserts v0.0.0-20250514102930-c1f3d2e37561 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + go.opentelemetry.io/collector/component v1.61.0 // indirect + go.opentelemetry.io/collector/featuregate v1.61.0 // indirect + go.opentelemetry.io/collector/pdata v1.61.0 // indirect + go.opentelemetry.io/collector/pdata/pprofile v0.155.0 // indirect + go.opentelemetry.io/otel v1.44.0 // indirect + go.opentelemetry.io/otel/metric v1.44.0 // indirect + go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect + go.uber.org/atomic v1.11.0 // indirect + go.uber.org/mock v0.6.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/exp v0.0.0-20260529124908-c761662dc8c9 // indirect + golang.org/x/mod v0.36.0 // indirect + golang.org/x/sys v0.46.0 // indirect + golang.org/x/time v0.15.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260618152121-87f3d3e198d3 // indirect + google.golang.org/protobuf v1.36.12-0.20260116114154-8c4c4ae446ca // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace github.com/DataDog/dd-trace-go/v2 => ../../.. diff --git a/contrib/go.uber.org/zap/go.sum b/contrib/go.uber.org/zap/go.sum new file mode 100644 index 0000000000..4c229698cb --- /dev/null +++ b/contrib/go.uber.org/zap/go.sum @@ -0,0 +1,247 @@ +github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.82.0-rc.2 h1:D78y0XOvACwT7QsOCx0QDDRe3yMGFdyrIgbZKRtoD6E= +github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.82.0-rc.2/go.mod h1:6LC1ryDn2VNqF0iNapwcLLdsfoFUMnT4p+JPu6sEkHg= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.82.0-rc.2 h1:3uIMYQvZNimspb7EFD66vEz0GteKjeT371QT+gVP/JQ= +github.com/DataDog/datadog-agent/pkg/obfuscate v0.82.0-rc.2/go.mod h1:TTmzWCh9Ose8xBFiZPc02niaUnbIJvMKkuc1swIA/+E= +github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.82.0-rc.2 h1:gL9G7vSG5Rq4KpVj65YXNavX5jXBq0vmbLJFPCjUOc8= +github.com/DataDog/datadog-agent/pkg/opentelemetry-mapping-go/otlp/attributes v0.82.0-rc.2/go.mod h1:lwkwdimN3B1vyoq09ufYJbPjkD3F31gsZFkV8Fz+McE= +github.com/DataDog/datadog-agent/pkg/proto v0.82.0-rc.2 h1:sYeDfkIVMRRks6oARQ0eZ4AR/oISv9DzGDx4aI8nWso= +github.com/DataDog/datadog-agent/pkg/proto v0.82.0-rc.2/go.mod h1:CN9cnkdi6L+uU2hsce+ENaJk1ixQVfzloqZkPOoCZe8= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.82.0-rc.2 h1:sqpklDgaeQ1dUcSQWIrrVXq+1XO9T//GXjKQnvIVTCk= +github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.82.0-rc.2/go.mod h1:jOEgJKvdRsCc36mDsAjFIWdyC9zCypX5SMKZ0vEBtFw= +github.com/DataDog/datadog-agent/pkg/trace v0.82.0-rc.2 h1:DjkRHhS3f/suzPYhOqjcEAklOMq8es7W0jGwg8pk7jI= +github.com/DataDog/datadog-agent/pkg/trace v0.82.0-rc.2/go.mod h1:3Nh5m4yEqScf+5ottviDHeBH9ITqXZxW+Gg21eCfNUM= +github.com/DataDog/datadog-agent/pkg/trace/log v0.82.0-rc.2 h1:YRPnojC5TeJdDKOODDekNyanTqe+YOrbvkvRPtjeTro= +github.com/DataDog/datadog-agent/pkg/trace/log v0.82.0-rc.2/go.mod h1:Vj76uL63Yu1mh+ZlcxInL6YiG7xP2i1NcrIGSP6mXzI= +github.com/DataDog/datadog-agent/pkg/trace/stats v0.82.0-rc.2 h1:z7CC/gVWFC1i71mdLJvrYLiCOJMG4LlWHpt5FmexViQ= +github.com/DataDog/datadog-agent/pkg/trace/stats v0.82.0-rc.2/go.mod h1:Lf9NYWsTcB96p16QfN3jEAoOZIJY9vJj01laoezDvDE= +github.com/DataDog/datadog-agent/pkg/trace/traceutil v0.82.0-rc.2 h1:0BiabGJwkJrIlVjTEsKHQtH3g20G3bNs3AU5CPkJrlc= +github.com/DataDog/datadog-agent/pkg/trace/traceutil v0.82.0-rc.2/go.mod h1:Km7Jyy+hr/gmCsSLcX6eJXgdrzh/2IwOLzXHecnGLcw= +github.com/DataDog/datadog-go/v5 v5.9.0 h1:0rhs5wBov9Iz+xLXLk4maaReHvOANM1ijSm2IKWtKFs= +github.com/DataDog/datadog-go/v5 v5.9.0/go.mod h1:2SBt8zJu6r7sRQHZFMQ8oCukWTKj0ymwulmNgQzJ1JM= +github.com/DataDog/go-libddwaf/v5 v5.0.0 h1:uPQfIVPH9T8jLSplAdfETAHwL3iRLabP6JxRTH8NL7Y= +github.com/DataDog/go-libddwaf/v5 v5.0.0/go.mod h1:/UzdsIsO8qk8fmbqNnk6Na7MsaNvU2R7SlBRHEgSIOQ= +github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20260217080614-b0f4edc38a6d h1:cH9Bm0tJ8FEQbA4FRi0iRm7Zr/5Lata/Or31c+Dth0E= +github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20260217080614-b0f4edc38a6d/go.mod h1:yDuvU+Ak1TKwgd4K8DNcpJmUrrK8ONLkBMGNAppmBRk= +github.com/DataDog/go-sqllexer v0.2.3 h1:VNUUVv4nCHbyHKKYwuj3HuRD2/hll8aYEkR5b4BW6nw= +github.com/DataDog/go-sqllexer v0.2.3/go.mod h1:3xTFXBU69vUikYpESggScvC0RKYA7ZIdVrIkLwUOWdE= +github.com/DataDog/go-tuf v1.1.1-0.5.2 h1:YWvghV4ZvrQsPcUw8IOUMSDpqc3W5ruOIC+KJxPknv0= +github.com/DataDog/go-tuf v1.1.1-0.5.2/go.mod h1:zBcq6f654iVqmkk8n2Cx81E1JnNTMOAx1UEO/wZR+P0= +github.com/DataDog/sketches-go v1.4.8 h1:pFk9BNn+Rzv8IMIoPUttoOpOr3bJOqU3P6EP5wK+Lv8= +github.com/DataDog/sketches-go v1.4.8/go.mod h1:a/wjRUqzqtGS8qRHRPDCs4EAQfmvPDZGDlMIF5mxXOE= +github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 h1:kHaBemcxl8o/pQ5VM1c8PVE1PubbNx3mjUr09OqWGCs= +github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575/go.mod h1:9d6lWj8KzO/fd/NrVaLscBKmPigpZpn5YawRPw+e3Yo= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38= +github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/hashicorp/go-version v1.9.0 h1:CeOIz6k+LoN3qX9Z0tyQrPtiB1DFYRPfCIBtaXPSCnA= +github.com/hashicorp/go-version v1.9.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= +github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= +github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/linkdata/deadlock v0.5.5 h1:d6O+rzEqasSfamGDA8u7bjtaq7hOX8Ha4Zn36Wxrkvo= +github.com/linkdata/deadlock v0.5.5/go.mod h1:tXb28stzAD3trzEEK0UJWC+rZKuobCoPktPYzebb1u0= +github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e h1:Q6MvJtQK/iRcRtzAscm/zF23XxJlbECiGPyRicsX+Ak= +github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/minio/simdjson-go v0.4.5 h1:r4IQwjRGmWCQ2VeMc7fGiilu1z5du0gJ/I/FsKwgo5A= +github.com/minio/simdjson-go v0.4.5/go.mod h1:eoNz0DcLQRyEDeaPr4Ru6JpjlZPzbA0IodxVJk8lO8E= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= +github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac= +github.com/petermattis/goid v0.0.0-20250813065127-a731cc31b4fe/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6 h1:rh2lKw/P/EqHa724vYH2+VVQ1YnW4u6EOXl0PMAovZE= +github.com/petermattis/goid v0.0.0-20260226131333-17d1149c6ac6/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= +github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/puzpuzpuz/xsync/v4 v4.5.0 h1:vOSWu6b57/emh+L/Cw0BeQfvxa/cogFywXHeGUxQxAg= +github.com/puzpuzpuz/xsync/v4 v4.5.0/go.mod h1:VJDmTCJMBt8igNxnkQd86r+8KUeN1quSfNKu5bLYFQo= +github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3 h1:4+LEVOB87y175cLJC/mbsgKmoDOjrBldtXvioEy96WY= +github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3/go.mod h1:vl5+MqJ1nBINuSsUI2mGgH79UweUT/B5Fy8857PqyyI= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/secure-systems-lab/go-securesystemslib v0.11.0 h1:iuCR9kcMFD4QurdKrGvPLoKZLv9YvwPYVr0473BdtFs= +github.com/secure-systems-lab/go-securesystemslib v0.11.0/go.mod h1:+PMOTjUGwHj2vcZ+TFKlb1tXRbrdWE1LYDT5i9JC80Q= +github.com/shirou/gopsutil/v4 v4.26.6 h1:Mzr/npDtQC/xpeEuQKHZt8Zo9CmPvhTj8nkR8w5TLDs= +github.com/shirou/gopsutil/v4 v4.26.6/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tinylib/msgp v1.6.4 h1:mOwYbyYDLPj35mkA2BjjYejgJk9BuHxDdvRnb6v2ZcQ= +github.com/tinylib/msgp v1.6.4/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= +github.com/trailofbits/go-mutexasserts v0.0.0-20250514102930-c1f3d2e37561 h1:qqa3P9AtNn6RMe90l/lxd3eJWnIRxjI4eb5Rx8xqCLA= +github.com/trailofbits/go-mutexasserts v0.0.0-20250514102930-c1f3d2e37561/go.mod h1:GA3+Mq3kt3tYAfM0WZCu7ofy+GW9PuGysHfhr+6JX7s= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= +github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/collector/component v1.61.0 h1:f2dUAPK1xu3FSY3QG2whG9PEEs+QgfdraoKQFyIwlSI= +go.opentelemetry.io/collector/component v1.61.0/go.mod h1:TFmz1NXfMDG4aKTAYcdi5gFntdAW/+Vq/iHYDoou/0E= +go.opentelemetry.io/collector/component/componenttest v0.155.0 h1:FfQQpYJnkNhNW5EPSD+vBiUL7Mwgkudrkr0LRYpi7HA= +go.opentelemetry.io/collector/component/componenttest v0.155.0/go.mod h1:MkXnGN4QH6El1GGTTOrDUqY8/p8Vkbfi0Non2Pmi0m4= +go.opentelemetry.io/collector/featuregate v1.61.0 h1:XtnQ/XPHLmw9zgg4Cjq/f0rgdqn7z1M10wnmGhgNbYk= +go.opentelemetry.io/collector/featuregate v1.61.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= +go.opentelemetry.io/collector/internal/testutil v0.155.0 h1:ExZ3lqM1e1Y83AAXKr6Xsw20v4LHW6GZ8VeLLQHiOrA= +go.opentelemetry.io/collector/internal/testutil v0.155.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= +go.opentelemetry.io/collector/pdata v1.61.0 h1:EVfGB/9dcyMXhMsZ5kzKeGFJj8QWqvmZjgg4RMjnRhE= +go.opentelemetry.io/collector/pdata v1.61.0/go.mod h1:qYEsyeIJ9tWHb2jSR5HQ9/VmbCGVca+G+ZDAB8dFCMc= +go.opentelemetry.io/collector/pdata/pprofile v0.155.0 h1:13LsyUy9SN88xcqbz89kvDqyn6qQSF5RpvXJ/c84nrw= +go.opentelemetry.io/collector/pdata/pprofile v0.155.0/go.mod h1:wlPe4OkzIYSmd1bCgAzmbKMlPDwlXCOLjbG68Fn7SG0= +go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU= +go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc= +go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc= +go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo= +go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58= +go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0= +go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI= +go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA= +go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk= +go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= +go.opentelemetry.io/proto/slim/otlp v1.10.0 h1:iR97Vs/ZDR+y9TfuP9b1XBtdPWeC+OMslIBmhcLU7jM= +go.opentelemetry.io/proto/slim/otlp v1.10.0/go.mod h1:lV9250stpjYLPNA5viFabIgP2QlUGRT1GdTgAf8SIUk= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0 h1:RUF5rO0hAlgiJt1fzQVzcVs3vZVNHIcMLgOgG4rWNcQ= +go.opentelemetry.io/proto/slim/otlp/collector/profiles/v1development v0.3.0/go.mod h1:I89cynRj8y+383o7tEQVg2SVA6SRgDVIouWPUVXjx0U= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0 h1:CQvJSldHRUN6Z8jsUeYv8J0lXRvygALXIzsmAeCcZE0= +go.opentelemetry.io/proto/slim/otlp/profiles/v1development v0.3.0/go.mod h1:xSQ+mEfJe/GjK1LXEyVOoSI1N9JV9ZI923X5kup43W4= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= +go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= +go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto= +golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio= +golang.org/x/exp v0.0.0-20260529124908-c761662dc8c9 h1:4d4PbuBNwaxMXkXI8yiIYjydtMU+04RHeuSxJdgKftM= +golang.org/x/exp v0.0.0-20260529124908-c761662dc8c9/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= +golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= +golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw= +golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260618152121-87f3d3e198d3 h1:phvBWCAQMGN1945mp5fjCXP6jEF0+a0+4TjokS4sxNY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260618152121-87f3d3e198d3/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/protobuf v1.36.12-0.20260116114154-8c4c4ae446ca h1:/ro7D0tSP+jEnQPzy9e1r5L6mAcEShGlE5kFsShX5O8= +google.golang.org/protobuf v1.36.12-0.20260116114154-8c4c4ae446ca/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/contrib/go.uber.org/zap/orchestrion.yml b/contrib/go.uber.org/zap/orchestrion.yml new file mode 100644 index 0000000000..15f2de25d6 --- /dev/null +++ b/contrib/go.uber.org/zap/orchestrion.yml @@ -0,0 +1,220 @@ +# 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 2023-present Datadog, Inc. +--- +# yaml-language-server: $schema=https://datadoghq.dev/orchestrion/schema.json +meta: + name: github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 + description: Structured, leveled logging for Go. + +aspects: + - id: Logger.Debug|Info|Warn|Error|DPanic|Panic|Fatal|Log + join-point: + all-of: + - not: + import-path: github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 + - one-of: + - method-call: + receiver: "go.uber.org/zap.Logger" + name: Debug + + - method-call: + receiver: "go.uber.org/zap.Logger" + name: Info + + - method-call: + receiver: "go.uber.org/zap.Logger" + name: Warn + + - method-call: + receiver: "go.uber.org/zap.Logger" + name: Error + + - method-call: + receiver: "go.uber.org/zap.Logger" + name: DPanic + + - method-call: + receiver: "go.uber.org/zap.Logger" + name: Panic + + - method-call: + receiver: "go.uber.org/zap.Logger" + name: Fatal + + - method-call: + receiver: "go.uber.org/zap.Logger" + name: Log + + advice: + - wrap-expression: + imports: + __ddzap: github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 + template: |- + {{- $ctx := .Function.ArgumentOfType "context.Context" -}} + {{- if eq $ctx "" -}} + {{- $ctx = .Function.ArgumentThatImplements "context.Context" -}} + {{- end -}} + {{- $req := .Function.ArgumentOfType "*net/http.Request" -}} + {{- $ellipsis := .AST.Ellipsis -}} + {{- if $ctx -}} + {{ .AST.Fun.X }}.With(__ddzap.TraceFields({{ $ctx }})...).{{ .AST.Fun.Name }}({{ range $i, $a := .AST.Args }}{{ if $i }}, {{ end }}{{ $a }}{{ end }}{{ if $ellipsis }}...{{ end }}) + {{- else if $req -}} + {{ .AST.Fun.X }}.With(__ddzap.TraceFieldsFromRequest({{ $req }})...).{{ .AST.Fun.Name }}({{ range $i, $a := .AST.Args }}{{ if $i }}, {{ end }}{{ $a }}{{ end }}{{ if $ellipsis }}...{{ end }}) + {{- else -}} + {{ . }} + {{- end -}} + + - id: SugaredLogger.Debug|Info|Warn|Error|DPanic|Panic|Fatal|Log|Logf|Logw|Logln + join-point: + all-of: + - not: + import-path: github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 + - one-of: + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Debug + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Info + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Warn + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Error + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: DPanic + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Panic + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Fatal + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Debugf + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Infof + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Warnf + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Errorf + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: DPanicf + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Panicf + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Fatalf + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Debugw + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Infow + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Warnw + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Errorw + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: DPanicw + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Panicw + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Fatalw + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Debugln + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Infoln + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Warnln + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Errorln + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: DPanicln + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Panicln + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Fatalln + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Log + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Logf + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Logw + + - method-call: + receiver: "go.uber.org/zap.SugaredLogger" + name: Logln + + advice: + - wrap-expression: + imports: + __ddzap: github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 + template: |- + {{- $ctx := .Function.ArgumentOfType "context.Context" -}} + {{- if eq $ctx "" -}} + {{- $ctx = .Function.ArgumentThatImplements "context.Context" -}} + {{- end -}} + {{- $req := .Function.ArgumentOfType "*net/http.Request" -}} + {{- $ellipsis := .AST.Ellipsis -}} + {{- if $ctx -}} + {{ .AST.Fun.X }}.Desugar().With(__ddzap.TraceFields({{ $ctx }})...).Sugar().{{ .AST.Fun.Name }}({{ range $i, $a := .AST.Args }}{{ if $i }}, {{ end }}{{ $a }}{{ end }}{{ if $ellipsis }}...{{ end }}) + {{- else if $req -}} + {{ .AST.Fun.X }}.Desugar().With(__ddzap.TraceFieldsFromRequest({{ $req }})...).Sugar().{{ .AST.Fun.Name }}({{ range $i, $a := .AST.Args }}{{ if $i }}, {{ end }}{{ $a }}{{ end }}{{ if $ellipsis }}...{{ end }}) + {{- else -}} + {{ . }} + {{- end -}} diff --git a/contrib/go.uber.org/zap/zap.go b/contrib/go.uber.org/zap/zap.go new file mode 100644 index 0000000000..39124ce06e --- /dev/null +++ b/contrib/go.uber.org/zap/zap.go @@ -0,0 +1,85 @@ +// 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 2023-present Datadog, Inc. + +// Package zap provides Datadog trace/log correlation helpers for go.uber.org/zap. +// +// # Manual use +// +// Call TraceFields with the current context to obtain zap.Field values for the +// active span, then pass them to any Logger method: +// +// logger.Info("handling request", +// zap.String("url", req.URL.Path), +// ddzap.TraceFields(ctx)..., +// ) +// +// # Automatic use via Orchestrion +// +// When built with Orchestrion, call sites of (*zap.Logger) and (*zap.SugaredLogger) +// log methods are automatically rewritten to inject trace fields whenever a +// context.Context (or a value implementing it) or a *http.Request is in scope. +package zap + +import ( + "context" + "net/http" + "strconv" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/ext" + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" + "github.com/DataDog/dd-trace-go/v2/instrumentation" + "github.com/DataDog/dd-trace-go/v2/instrumentation/options" +) + +var instr *instrumentation.Instrumentation + +func init() { + instr = instrumentation.Load(instrumentation.PackageGoUberOrgZap) +} + +type config struct { + log128bits bool +} + +var cfg = newConfig() + +func newConfig() *config { + return &config{ + log128bits: options.GetBoolEnv("DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED", true), + } +} + +// TraceFields returns zap.Field values carrying the Datadog trace and span IDs +// from the active span in ctx. Returns nil when no span is active. +func TraceFields(ctx context.Context) []zap.Field { + span, ok := tracer.SpanFromContext(ctx) + if !ok { + return nil + } + var traceID string + if cfg.log128bits && span.Context().TraceID() != tracer.TraceIDZero { + traceID = span.Context().TraceID() + } else { + traceID = strconv.FormatUint(span.Context().TraceIDLower(), 10) + } + return []zap.Field{ + zap.String(ext.LogKeyTraceID, traceID), + zap.String(ext.LogKeySpanID, strconv.FormatUint(span.Context().SpanID(), 10)), + } +} + +// TraceFieldsFromRequest returns TraceFields for req's context, or nil when req +// is nil. Orchestrion uses this as a fallback trace source when a *http.Request +// is in scope but no context.Context is: a nil req would otherwise panic on +// req.Context() in an instrumented build where the original, uninstrumented log +// call would have logged normally. +func TraceFieldsFromRequest(req *http.Request) []zap.Field { + if req == nil { + return nil + } + return TraceFields(req.Context()) +} diff --git a/contrib/go.uber.org/zap/zap_test.go b/contrib/go.uber.org/zap/zap_test.go new file mode 100644 index 0000000000..f478659f93 --- /dev/null +++ b/contrib/go.uber.org/zap/zap_test.go @@ -0,0 +1,145 @@ +// 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 2023-present Datadog, Inc. + +package zap + +import ( + "context" + "io" + "strconv" + "testing" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/ext" + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" +) + +func fieldsToMap(fields []zap.Field) map[string]string { + m := make(map[string]string, len(fields)) + for _, f := range fields { + m[f.Key] = f.String + } + return m +} + +func TestTraceFields(t *testing.T) { + tracer.Start() + defer tracer.Stop() + sp, sctx := tracer.StartSpanFromContext(context.Background(), "testSpan", tracer.WithSpanID(1234)) + defer sp.Finish() + + fields := TraceFields(sctx) + require.Len(t, fields, 2) + + data := fieldsToMap(fields) + // By default, trace IDs are logged in 128-bit format. + assert.Equal(t, sp.Context().TraceID(), data[ext.LogKeyTraceID]) + assert.Equal(t, strconv.FormatUint(sp.Context().SpanID(), 10), data[ext.LogKeySpanID]) +} + +func TestTraceFields128BitDisabled(t *testing.T) { + t.Setenv("DD_TRACE_128_BIT_TRACEID_LOGGING_ENABLED", "false") + + // Re-initialize to account for the race between setting the env var in the + // test and reading it in the contrib. Restore the original config afterwards + // so this override doesn't leak into other tests or benchmarks. + orig := cfg + t.Cleanup(func() { cfg = orig }) + cfg = newConfig() + + tracer.Start() + defer tracer.Stop() + sp, sctx := tracer.StartSpanFromContext(context.Background(), "testSpan", tracer.WithSpanID(1234)) + defer sp.Finish() + + fields := TraceFields(sctx) + require.Len(t, fields, 2) + + data := fieldsToMap(fields) + assert.Equal(t, strconv.FormatUint(sp.Context().TraceIDLower(), 10), data[ext.LogKeyTraceID]) + assert.Equal(t, strconv.FormatUint(sp.Context().SpanID(), 10), data[ext.LogKeySpanID]) +} + +func TestTraceFieldsNoSpan(t *testing.T) { + assert.Nil(t, TraceFields(context.Background())) +} + +// newBenchLogger returns a zap.Logger that discards its output, so benchmarks +// measure only the trace-field injection overhead, not encoding or I/O. +func newBenchLogger() *zap.Logger { + return zap.New(zapcore.NewCore( + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + zapcore.AddSync(io.Discard), + zapcore.DebugLevel, + )) +} + +// BenchmarkTraceFields measures the cost of extracting the trace and span IDs +// from a context into zap.Field values. +func BenchmarkTraceFields(b *testing.B) { + tracer.Start() + defer tracer.Stop() + sp, ctx := tracer.StartSpanFromContext(context.Background(), "bench") + defer sp.Finish() + + b.ReportAllocs() + for b.Loop() { + _ = TraceFields(ctx) + } +} + +// BenchmarkLogger compares a plain log call against the form Orchestrion +// injects, logger.With(TraceFields(ctx)...).Info(...), so the delta between the +// two sub-benchmarks is the per-call instrumentation overhead. +func BenchmarkLogger(b *testing.B) { + tracer.Start() + defer tracer.Stop() + sp, ctx := tracer.StartSpanFromContext(context.Background(), "bench") + defer sp.Finish() + + logger := newBenchLogger() + + b.Run("baseline", func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + logger.Info("bench message") + } + }) + b.Run("instrumented", func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + logger.With(TraceFields(ctx)...).Info("bench message") + } + }) +} + +// BenchmarkSugaredLogger mirrors BenchmarkLogger for the SugaredLogger path, +// which Orchestrion instruments via Desugar().With(...).Sugar(). +func BenchmarkSugaredLogger(b *testing.B) { + tracer.Start() + defer tracer.Stop() + sp, ctx := tracer.StartSpanFromContext(context.Background(), "bench") + defer sp.Finish() + + sugar := newBenchLogger().Sugar() + + b.Run("baseline", func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + sugar.Infow("bench message") + } + }) + b.Run("instrumented", func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + sugar.Desugar().With(TraceFields(ctx)...).Sugar().Infow("bench message") + } + }) +} diff --git a/contrib/supported_integrations.md b/contrib/supported_integrations.md index c4025f6ed2..e24f68b728 100644 --- a/contrib/supported_integrations.md +++ b/contrib/supported_integrations.md @@ -1,67 +1,71 @@ | Package | Datadog Integration | Minimum Tested Version | Maximum Tested Version | Orchestrion support | |-------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------|----------------------------------------|---------------------| -| [github.com/99designs/gqlgen](https://pkg.go.dev/github.com/99designs/gqlgen) | [contrib/99designs/gqlgen](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/99designs/gqlgen/v2) | `v0.17.83` | `v0.17.85` | :white_check_mark: | -| [github.com/IBM/sarama](https://pkg.go.dev/github.com/IBM/sarama) | [contrib/IBM/sarama](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/IBM/sarama/v2) | `v1.40.0` | `v1.46.3` | :white_check_mark: | -| [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) | [contrib/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/aws/aws-sdk-go-v2/v2) | `v1.26.1` | `v1.41.0` | :white_check_mark: | -| [github.com/bradfitz/gomemcache](https://pkg.go.dev/github.com/bradfitz/gomemcache) | [contrib/bradfitz/gomemcache](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/bradfitz/gomemcache/v2) | `v0.0.0-20230611145640-acc696258285` | `v0.0.0-20250403215159-8d39553ac7cf` | | -| [cloud.google.com/go/pubsub](https://pkg.go.dev/cloud.google.com/go/pubsub) | [contrib/cloud.google.com/go/pubsub.v1](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/cloud.google.com/go/pubsub.v1/v2) | `v1.37.0` | `v1.50.1` | :white_check_mark: | -| [cloud.google.com/go/pubsub/v2](https://pkg.go.dev/cloud.google.com/go/pubsub/v2) | [contrib/cloud.google.com/go/pubsub.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/cloud.google.com/go/pubsub.v2/v2) | `v2.0.0` | `v2.3.0` | :white_check_mark: | +| [github.com/99designs/gqlgen](https://pkg.go.dev/github.com/99designs/gqlgen) | [contrib/99designs/gqlgen](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/99designs/gqlgen/v2) | `v0.17.92` | `v0.17.94` | :white_check_mark: | +| [github.com/IBM/sarama](https://pkg.go.dev/github.com/IBM/sarama) | [contrib/IBM/sarama](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/IBM/sarama/v2) | `v1.44.0` | `v1.50.3` | :white_check_mark: | +| [github.com/aerospike/aerospike-client-go/v7](https://pkg.go.dev/github.com/aerospike/aerospike-client-go/v7) | [contrib/aerospike/aerospike-client-go.v7](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/aerospike/aerospike-client-go.v7/v2) | `v7.10.2` | `v7.10.2` | :white_check_mark: | +| [github.com/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2) | [contrib/aws/aws-sdk-go-v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/aws/aws-sdk-go-v2/v2) | `v1.41.5` | `v1.42.1` | :white_check_mark: | +| [github.com/bradfitz/gomemcache](https://pkg.go.dev/github.com/bradfitz/gomemcache) | [contrib/bradfitz/gomemcache](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/bradfitz/gomemcache/v2) | `v0.0.0-20230611145640-acc696258285` | `v0.0.0-20260422231931-4d751bb6e37c` | | +| [cloud.google.com/go/pubsub](https://pkg.go.dev/cloud.google.com/go/pubsub) | [contrib/cloud.google.com/go/pubsub.v1](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/cloud.google.com/go/pubsub.v1/v2) | `v1.50.1` | `v1.50.4` | :white_check_mark: | +| [cloud.google.com/go/pubsub/v2](https://pkg.go.dev/cloud.google.com/go/pubsub/v2) | [contrib/cloud.google.com/go/pubsub.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/cloud.google.com/go/pubsub.v2/v2) | `v2.0.0` | `v2.6.1` | :white_check_mark: | | [github.com/confluentinc/confluent-kafka-go](https://pkg.go.dev/github.com/confluentinc/confluent-kafka-go) | [contrib/confluentinc/confluent-kafka-go/kafka](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/confluentinc/confluent-kafka-go/kafka/v2) | `v1.9.2` | `v1.9.2` | :white_check_mark: | -| [github.com/confluentinc/confluent-kafka-go/v2](https://pkg.go.dev/github.com/confluentinc/confluent-kafka-go/v2) | [contrib/confluentinc/confluent-kafka-go/kafka.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/confluentinc/confluent-kafka-go/kafka.v2/v2) | `v2.4.0` | `v2.13.0` | :white_check_mark: | +| [github.com/confluentinc/confluent-kafka-go/v2](https://pkg.go.dev/github.com/confluentinc/confluent-kafka-go/v2) | [contrib/confluentinc/confluent-kafka-go/kafka.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/confluentinc/confluent-kafka-go/kafka.v2/v2) | `v2.4.0` | `v2.15.0` | :white_check_mark: | | [database/sql](https://pkg.go.dev/database/sql) | [contrib/database/sql](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/database/sql/v2) | `N/A` | `N/A` | :white_check_mark: | | [github.com/dimfeld/httptreemux/v5](https://pkg.go.dev/github.com/dimfeld/httptreemux/v5) | [contrib/dimfeld/httptreemux.v5](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/dimfeld/httptreemux.v5/v2) | `v5.5.0` | `v5.5.0` | | | [github.com/elastic/go-elasticsearch/v6](https://pkg.go.dev/github.com/elastic/go-elasticsearch/v6) | [contrib/elastic/go-elasticsearch.v6](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/elastic/go-elasticsearch.v6/v2) | `v6.8.5` | `v6.8.10` | :white_check_mark: | -| [github.com/emicklei/go-restful/v3](https://pkg.go.dev/github.com/emicklei/go-restful/v3) | [contrib/emicklei/go-restful.v3](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/emicklei/go-restful.v3/v2) | `v3.11.0` | `v3.13.0` | | -| [github.com/envoyproxy/go-control-plane/envoy](https://pkg.go.dev/github.com/envoyproxy/go-control-plane/envoy) | [contrib/envoyproxy/go-control-plane](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/envoyproxy/go-control-plane/v2) | `v1.32.4` | `v1.36.0` | | -| [github.com/gin-gonic/gin](https://pkg.go.dev/github.com/gin-gonic/gin) | [contrib/gin-gonic/gin](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gin-gonic/gin/v2) | `v1.10.1` | `v1.11.0` | :white_check_mark: | +| [github.com/emicklei/go-restful/v3](https://pkg.go.dev/github.com/emicklei/go-restful/v3) | [contrib/emicklei/go-restful.v3](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/emicklei/go-restful.v3/v2) | `v3.12.2` | `v3.13.0` | | +| [github.com/envoyproxy/go-control-plane/envoy](https://pkg.go.dev/github.com/envoyproxy/go-control-plane/envoy) | [contrib/envoyproxy/go-control-plane](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/envoyproxy/go-control-plane/v2) | `v1.36.0` | `v1.37.0` | | +| [github.com/gin-gonic/gin](https://pkg.go.dev/github.com/gin-gonic/gin) | [contrib/gin-gonic/gin](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gin-gonic/gin/v2) | `v1.10.1` | `v1.12.0` | :white_check_mark: | | [github.com/go-chi/chi](https://pkg.go.dev/github.com/go-chi/chi) | [contrib/go-chi/chi](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-chi/chi/v2) | `v1.5.4` | `v1.5.5` | :white_check_mark: | -| [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) | [contrib/go-chi/chi.v5](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-chi/chi.v5/v2) | `v5.2.2` | `v5.2.3` | :white_check_mark: | -| [github.com/go-pg/pg/v10](https://pkg.go.dev/github.com/go-pg/pg/v10) | [contrib/go-pg/pg.v10](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-pg/pg.v10/v2) | `v10.15.0` | `v10.15.0` | | +| [github.com/go-chi/chi/v5](https://pkg.go.dev/github.com/go-chi/chi/v5) | [contrib/go-chi/chi.v5](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-chi/chi.v5/v2) | `v5.2.4` | `v5.3.1` | :white_check_mark: | +| [github.com/go-pg/pg/v10](https://pkg.go.dev/github.com/go-pg/pg/v10) | [contrib/go-pg/pg.v10](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-pg/pg.v10/v2) | `v10.15.0` | `v10.15.1` | | | [github.com/go-redis/redis](https://pkg.go.dev/github.com/go-redis/redis) | [contrib/go-redis/redis](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-redis/redis/v2) | `v6.15.9+incompatible` | `v6.15.9+incompatible` | :white_check_mark: | | [github.com/go-redis/redis/v7](https://pkg.go.dev/github.com/go-redis/redis/v7) | [contrib/go-redis/redis.v7](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-redis/redis.v7/v2) | `v7.4.1` | `v7.4.1` | :white_check_mark: | | [github.com/go-redis/redis/v8](https://pkg.go.dev/github.com/go-redis/redis/v8) | [contrib/go-redis/redis.v8](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go-redis/redis.v8/v2) | `v8.11.5` | `v8.11.5` | :white_check_mark: | -| [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) | [contrib/go.mongodb.org/mongo-driver](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver/v2) | `v1.12.1` | `v1.17.6` | :white_check_mark: | -| [go.mongodb.org/mongo-driver/v2](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2) | [contrib/go.mongodb.org/mongo-driver.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver.v2/v2) | `v2.2.2` | `v2.4.1` | :white_check_mark: | -| [github.com/gocql/gocql](https://pkg.go.dev/github.com/gocql/gocql) | [contrib/gocql/gocql](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gocql/gocql/v2) | `v1.6.0` | `v1.7.0` | :white_check_mark: | -| [github.com/gofiber/fiber/v2](https://pkg.go.dev/github.com/gofiber/fiber/v2) | [contrib/gofiber/fiber.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gofiber/fiber.v2/v2) | `v2.52.9` | `v2.52.10` | :white_check_mark: | -| [github.com/gomodule/redigo](https://pkg.go.dev/github.com/gomodule/redigo) | [contrib/gomodule/redigo](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gomodule/redigo/v2) | `v1.8.9` | `v1.9.3` | :white_check_mark: | -| [google.golang.org/api](https://pkg.go.dev/google.golang.org/api) | [contrib/google.golang.org/api](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/google.golang.org/api/v2) | `v0.169.0` | `v0.259.0` | | -| [google.golang.org/grpc](https://pkg.go.dev/google.golang.org/grpc) | [contrib/google.golang.org/grpc](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/google.golang.org/grpc/v2) | `v1.76.0` | `v1.78.0` | :white_check_mark: | +| [go.mongodb.org/mongo-driver](https://pkg.go.dev/go.mongodb.org/mongo-driver) | [contrib/go.mongodb.org/mongo-driver](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver/v2) | `v1.17.1` | `v1.17.9` | :white_check_mark: | +| [go.mongodb.org/mongo-driver/v2](https://pkg.go.dev/go.mongodb.org/mongo-driver/v2) | [contrib/go.mongodb.org/mongo-driver.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver.v2/v2) | `v2.2.2` | `v2.8.0` | :white_check_mark: | +| [go.uber.org/zap](https://pkg.go.dev/go.uber.org/zap) | [contrib/go.uber.org/zap](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2) | `v1.28.0` | `v1.28.0` | :white_check_mark: | +| [github.com/gocql/gocql](https://pkg.go.dev/github.com/gocql/gocql) | [contrib/gocql/gocql](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gocql/gocql/v2) | `v1.7.0` | `v1.7.0` | :white_check_mark: | +| [github.com/gofiber/fiber/v2](https://pkg.go.dev/github.com/gofiber/fiber/v2) | [contrib/gofiber/fiber.v2](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gofiber/fiber.v2/v2) | `v2.52.12` | `v2.52.14` | :white_check_mark: | +| [github.com/gomodule/redigo](https://pkg.go.dev/github.com/gomodule/redigo) | [contrib/gomodule/redigo](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gomodule/redigo/v2) | `v1.9.2` | `v1.9.3` | :white_check_mark: | +| [google.golang.org/api](https://pkg.go.dev/google.golang.org/api) | [contrib/google.golang.org/api](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/google.golang.org/api/v2) | `v0.273.1` | `v0.288.0` | | +| [google.golang.org/grpc](https://pkg.go.dev/google.golang.org/grpc) | [contrib/google.golang.org/grpc](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/google.golang.org/grpc/v2) | `v1.80.0` | `v1.82.0` | :white_check_mark: | | [github.com/gorilla/mux](https://pkg.go.dev/github.com/gorilla/mux) | [contrib/gorilla/mux](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gorilla/mux/v2) | `v1.8.1` | `v1.8.1` | :white_check_mark: | -| [gorm.io/gorm](https://pkg.go.dev/gorm.io/gorm) | [contrib/gorm.io/gorm.v1](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gorm.io/gorm.v1/v2) | `v1.25.5` | `v1.31.1` | :white_check_mark: | -| [github.com/graph-gophers/graphql-go](https://pkg.go.dev/github.com/graph-gophers/graphql-go) | [contrib/graph-gophers/graphql-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/graph-gophers/graphql-go/v2) | `v1.5.0` | `v1.8.0` | :white_check_mark: | +| [gorm.io/gorm](https://pkg.go.dev/gorm.io/gorm) | [contrib/gorm.io/gorm.v1](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/gorm.io/gorm.v1/v2) | `v1.25.12` | `v1.31.2` | :white_check_mark: | +| [github.com/graph-gophers/graphql-go](https://pkg.go.dev/github.com/graph-gophers/graphql-go) | [contrib/graph-gophers/graphql-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/graph-gophers/graphql-go/v2) | `v1.5.0` | `v1.10.2` | :white_check_mark: | | [github.com/graphql-go/graphql](https://pkg.go.dev/github.com/graphql-go/graphql) | [contrib/graphql-go/graphql](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/graphql-go/graphql/v2) | `v0.8.1` | `v0.8.1` | :white_check_mark: | -| [github.com/hashicorp/consul/api](https://pkg.go.dev/github.com/hashicorp/consul/api) | [contrib/hashicorp/consul](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/hashicorp/consul/v2) | `v1.24.0` | `v1.33.0` | | -| [github.com/hashicorp/vault/api](https://pkg.go.dev/github.com/hashicorp/vault/api) | [contrib/hashicorp/vault](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/hashicorp/vault/v2) | `v1.15.0` | `v1.22.0` | :white_check_mark: | -| [github.com/jackc/pgx/v5](https://pkg.go.dev/github.com/jackc/pgx/v5) | [contrib/jackc/pgx.v5](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/jackc/pgx.v5/v2) | `v5.6.0` | `v5.8.0` | :white_check_mark: | +| [github.com/hashicorp/consul/api](https://pkg.go.dev/github.com/hashicorp/consul/api) | [contrib/hashicorp/consul](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/hashicorp/consul/v2) | `v1.24.0` | `v1.34.4` | | +| [github.com/hashicorp/vault/api](https://pkg.go.dev/github.com/hashicorp/vault/api) | [contrib/hashicorp/vault](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/hashicorp/vault/v2) | `v1.15.0` | `v1.23.0` | :white_check_mark: | +| [github.com/jackc/pgx/v5](https://pkg.go.dev/github.com/jackc/pgx/v5) | [contrib/jackc/pgx.v5](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/jackc/pgx.v5/v2) | `v5.9.0` | `v5.10.0` | :white_check_mark: | | [github.com/jmoiron/sqlx](https://pkg.go.dev/github.com/jmoiron/sqlx) | [contrib/jmoiron/sqlx](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/jmoiron/sqlx/v2) | `v1.3.5` | `v1.4.0` | | | [github.com/julienschmidt/httprouter](https://pkg.go.dev/github.com/julienschmidt/httprouter) | [contrib/julienschmidt/httprouter](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/julienschmidt/httprouter/v2) | `v1.3.0` | `v1.3.0` | :white_check_mark: | -| [k8s.io/client-go](https://pkg.go.dev/k8s.io/client-go) | [contrib/k8s.io/client-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/k8s.io/client-go/v2) | `v0.31.4` | `v0.35.0` | :white_check_mark: | -| [sigs.k8s.io/gateway-api](https://pkg.go.dev/sigs.k8s.io/gateway-api) | [contrib/k8s.io/gateway-api](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/k8s.io/gateway-api/v2) | `v1.2.1` | `v1.4.1` | | -| [github.com/labstack/echo/v4](https://pkg.go.dev/github.com/labstack/echo/v4) | [contrib/labstack/echo.v4](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/labstack/echo.v4/v2) | `v4.11.1` | `v4.15.0` | :white_check_mark: | +| [k8s.io/client-go](https://pkg.go.dev/k8s.io/client-go) | [contrib/k8s.io/client-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/k8s.io/client-go/v2) | `v0.35.1` | `v0.36.2` | :white_check_mark: | +| [sigs.k8s.io/gateway-api](https://pkg.go.dev/sigs.k8s.io/gateway-api) | [contrib/k8s.io/gateway-api](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/k8s.io/gateway-api/v2) | `v1.2.1` | `v1.6.0` | | +| [github.com/labstack/echo/v4](https://pkg.go.dev/github.com/labstack/echo/v4) | [contrib/labstack/echo.v4](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/labstack/echo.v4/v2) | `v4.13.3` | `v4.15.4` | :white_check_mark: | +| [github.com/labstack/echo/v5](https://pkg.go.dev/github.com/labstack/echo/v5) | [contrib/labstack/echo.v5](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/labstack/echo.v5/v2) | `v5.1.0` | `v5.3.0` | :white_check_mark: | | [log/slog](https://pkg.go.dev/log/slog) | [contrib/log/slog](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/log/slog/v2) | `N/A` | `N/A` | :white_check_mark: | -| [github.com/mark3labs/mcp-go](https://pkg.go.dev/github.com/mark3labs/mcp-go) | [contrib/mark3labs/mcp-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/mark3labs/mcp-go/v2) | `v0.42.0` | `v0.43.2` | | -| [github.com/miekg/dns](https://pkg.go.dev/github.com/miekg/dns) | [contrib/miekg/dns](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/miekg/dns/v2) | `v1.1.55` | `v1.1.69` | | -| [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) | [contrib/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/modelcontextprotocol/go-sdk/v2) | `v1.1.0` | `v1.2.0` | | +| [github.com/mark3labs/mcp-go](https://pkg.go.dev/github.com/mark3labs/mcp-go) | [contrib/mark3labs/mcp-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/mark3labs/mcp-go/v2) | `v0.42.0` | `v0.56.0` | | +| [github.com/miekg/dns](https://pkg.go.dev/github.com/miekg/dns) | [contrib/miekg/dns](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/miekg/dns/v2) | `v1.1.62` | `v1.1.72` | | +| [github.com/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/modelcontextprotocol/go-sdk) | [contrib/modelcontextprotocol/go-sdk](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/modelcontextprotocol/go-sdk/v2) | `v1.4.1` | `v1.6.1` | | | [net/http](https://pkg.go.dev/net/http) | [contrib/net/http](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/net/http/v2) | `N/A` | `N/A` | :white_check_mark: | -| [github.com/redis/go-redis/v9](https://pkg.go.dev/github.com/redis/go-redis/v9) | [contrib/redis/go-redis.v9](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/redis/go-redis.v9/v2) | `v9.7.3` | `v9.17.2` | :white_check_mark: | -| [github.com/redis/rueidis](https://pkg.go.dev/github.com/redis/rueidis) | [contrib/redis/rueidis](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/redis/rueidis/v2) | `v1.0.55` | `v1.0.70` | :white_check_mark: | -| [github.com/rs/zerolog](https://pkg.go.dev/github.com/rs/zerolog) | [contrib/rs/zerolog](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/rs/zerolog/v2) | `v1.34.0` | `v1.34.0` | :white_check_mark: | -| [github.com/segmentio/kafka-go](https://pkg.go.dev/github.com/segmentio/kafka-go) | [contrib/segmentio/kafka-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/segmentio/kafka-go/v2) | `v0.4.42` | `v0.4.49` | :white_check_mark: | -| [github.com/sirupsen/logrus](https://pkg.go.dev/github.com/sirupsen/logrus) | [contrib/sirupsen/logrus](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/sirupsen/logrus/v2) | `v1.9.3` | `v1.9.3` | :white_check_mark: | +| [github.com/redis/go-redis/v9](https://pkg.go.dev/github.com/redis/go-redis/v9) | [contrib/redis/go-redis.v9](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/redis/go-redis.v9/v2) | `v9.7.3` | `v9.21.0` | :white_check_mark: | +| [github.com/redis/rueidis](https://pkg.go.dev/github.com/redis/rueidis) | [contrib/redis/rueidis](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/redis/rueidis/v2) | `v1.0.74` | `v1.0.76` | :white_check_mark: | +| [github.com/rs/zerolog](https://pkg.go.dev/github.com/rs/zerolog) | [contrib/rs/zerolog](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/rs/zerolog/v2) | `v1.34.0` | `v1.35.1` | :white_check_mark: | +| [github.com/segmentio/kafka-go](https://pkg.go.dev/github.com/segmentio/kafka-go) | [contrib/segmentio/kafka-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/segmentio/kafka-go/v2) | `v0.4.42` | `v0.4.51` | :white_check_mark: | +| [github.com/sirupsen/logrus](https://pkg.go.dev/github.com/sirupsen/logrus) | [contrib/sirupsen/logrus](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/sirupsen/logrus/v2) | `v1.9.3` | `v1.9.4` | :white_check_mark: | | [github.com/syndtr/goleveldb](https://pkg.go.dev/github.com/syndtr/goleveldb) | [contrib/syndtr/goleveldb](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/syndtr/goleveldb/v2) | `v1.0.1-0.20220721030215-126854af5e6d` | `v1.0.1-0.20220721030215-126854af5e6d` | | | [github.com/tidwall/buntdb](https://pkg.go.dev/github.com/tidwall/buntdb) | [contrib/tidwall/buntdb](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/tidwall/buntdb/v2) | `v1.3.0` | `v1.3.2` | | | [github.com/twitchtv/twirp](https://pkg.go.dev/github.com/twitchtv/twirp) | [contrib/twitchtv/twirp](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/twitchtv/twirp/v2) | `v8.1.3+incompatible` | `v8.1.3+incompatible` | :white_check_mark: | -| [github.com/uptrace/bun](https://pkg.go.dev/github.com/uptrace/bun) | [contrib/uptrace/bun](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/uptrace/bun/v2) | `v1.1.17` | `v1.2.16` | | +| [github.com/twmb/franz-go](https://pkg.go.dev/github.com/twmb/franz-go) | [contrib/twmb/franz-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/twmb/franz-go/v2) | `v1.21.0` | `v1.21.5` | :white_check_mark: | +| [github.com/uptrace/bun](https://pkg.go.dev/github.com/uptrace/bun) | [contrib/uptrace/bun](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/uptrace/bun/v2) | `v1.1.17` | `v1.2.18` | | | [github.com/urfave/negroni](https://pkg.go.dev/github.com/urfave/negroni) | [contrib/urfave/negroni](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/urfave/negroni/v2) | `v1.0.0` | `v1.0.0` | | -| [github.com/valkey-io/valkey-go](https://pkg.go.dev/github.com/valkey-io/valkey-go) | [contrib/valkey-io/valkey-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/valkey-io/valkey-go/v2) | `v1.0.55` | `v1.0.70` | :white_check_mark: | -| [github.com/valyala/fasthttp](https://pkg.go.dev/github.com/valyala/fasthttp) | [contrib/valyala/fasthttp](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/valyala/fasthttp/v2) | `v1.51.0` | `v1.69.0` | :white_check_mark: | +| [github.com/valkey-io/valkey-go](https://pkg.go.dev/github.com/valkey-io/valkey-go) | [contrib/valkey-io/valkey-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/valkey-io/valkey-go/v2) | `v1.0.74` | `v1.0.76` | :white_check_mark: | +| [github.com/valyala/fasthttp](https://pkg.go.dev/github.com/valyala/fasthttp) | [contrib/valyala/fasthttp](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/valyala/fasthttp/v2) | `v1.58.0` | `v1.72.0` | :white_check_mark: | ⚠️ The following integrations are marked as deprecated and will be removed in future releases. ⚠️ | Package | Datadog Integration | Minimum Tested Version | Maximum Tested Version | Orchestrion support | Deprecation comment | |---------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|------------------------------------------|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| [github.com/Shopify/sarama](https://pkg.go.dev/github.com/Shopify/sarama) | [contrib/Shopify/sarama](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/Shopify/sarama/v2) | `v1.38.1` | `v1.46.3` | :white_check_mark: | - `contrib/Shopify/sarama`: github.com/Shopify/sarama is no longer maintained. Please migrate to github.com/IBM/sarama and use the corresponding integration. This integration will be removed in a future release. | -| [github.com/aws/aws-sdk-go](https://pkg.go.dev/github.com/aws/aws-sdk-go) | [contrib/aws/aws-sdk-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/aws/aws-sdk-go/v2) | `v1.44.327` | `v1.55.8` | :white_check_mark: | - `contrib/aws/aws-sdk-go/aws`: The AWS SDK for Go v1 is deprecated. Please migrate to github.com/aws/aws-sdk-go-v2 and use the corresponding integration. This integration will be removed in a future release. | +| [github.com/Shopify/sarama](https://pkg.go.dev/github.com/Shopify/sarama) | [contrib/Shopify/sarama](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/Shopify/sarama/v2) | `v1.38.1` | `v1.38.1` | :white_check_mark: | - `contrib/Shopify/sarama`: github.com/Shopify/sarama is no longer maintained. Please migrate to github.com/IBM/sarama and use the corresponding integration. This integration will be removed in a future release. | +| [github.com/aws/aws-sdk-go](https://pkg.go.dev/github.com/aws/aws-sdk-go) | [contrib/aws/aws-sdk-go](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/aws/aws-sdk-go/v2) | `v1.55.5` | `v1.55.8` | :white_check_mark: | - `contrib/aws/aws-sdk-go/aws`: The AWS SDK for Go v1 is deprecated. Please migrate to github.com/aws/aws-sdk-go-v2 and use the corresponding integration. This integration will be removed in a future release. | | [github.com/globalsign/mgo](https://pkg.go.dev/github.com/globalsign/mgo) | [contrib/globalsign/mgo](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/globalsign/mgo/v2) | `v0.0.0-20181015135952-eeefdecb41b8` | `v0.0.0-20181015135952-eeefdecb41b8` | | - `contrib/globalsign/mgo`: github.com/globalsign/mgo is unmaintained, please migrate to the official MongoDB driver https://github.com/mongodb/mongo-go-driver. This integration will be removed in a future release. | | [gopkg.in/olivere/elastic.v5](https://pkg.go.dev/gopkg.in/olivere/elastic.v5) | [contrib/olivere/elastic.v5](https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/olivere/elastic.v5/v2) | `v5.0.84` | `v5.0.86` | | - `contrib/olivere/elastic.v5`: https://github.com/olivere/elastic is deprecated. Please use the official Elasticsearch client for Go at https://github.com/elastic/go-elasticsearch and use the corresponding integration. This integration will be removed in a future release. | diff --git a/ddtrace/tracer/option.go b/ddtrace/tracer/option.go index 4dd70fdcdf..4ce161d261 100644 --- a/ddtrace/tracer/option.go +++ b/ddtrace/tracer/option.go @@ -118,6 +118,7 @@ var contribIntegrations = map[string]struct { "github.com/urfave/negroni": {"Negroni", false}, "github.com/valyala/fasthttp": {"FastHTTP", false}, "github.com/valkey-io/valkey-go": {"Valkey", false}, + "go.uber.org/zap": {"Zap", false}, } // Supported trace protocols. diff --git a/ddtrace/tracer/option_test.go b/ddtrace/tracer/option_test.go index 0095594c3b..610661328c 100644 --- a/ddtrace/tracer/option_test.go +++ b/ddtrace/tracer/option_test.go @@ -388,7 +388,7 @@ func TestAgentIntegration(t *testing.T) { defer clearIntegrationsForTests() cfg.loadContribIntegrations(nil) - assert.Equal(t, 58, len(cfg.integrations)) + assert.Equal(t, 59, len(cfg.integrations)) for integrationName, v := range cfg.integrations { assert.False(t, v.Instrumented, "integrationName=%s", integrationName) } diff --git a/go.work b/go.work index 97a6d2485f..801ba107f8 100644 --- a/go.work +++ b/go.work @@ -31,6 +31,7 @@ use ( ./contrib/go-redis/redis.v8 ./contrib/go.mongodb.org/mongo-driver ./contrib/go.mongodb.org/mongo-driver.v2 + ./contrib/go.uber.org/zap ./contrib/gocql/gocql ./contrib/gofiber/fiber.v2 ./contrib/gomodule/redigo diff --git a/instrumentation/packages.go b/instrumentation/packages.go index 3b0fb4b51a..74eb9067cf 100644 --- a/instrumentation/packages.go +++ b/instrumentation/packages.go @@ -35,6 +35,7 @@ const ( PackageGlobalsignMgo Package = "globalsign/mgo" PackageMongoDriver Package = "go.mongodb.org/mongo-driver" PackageMongoDriverV2 Package = "go.mongodb.org/mongo-driver.v2" + PackageGoUberOrgZap Package = "go.uber.org/zap" PackageChi Package = "go-chi/chi" PackageChiV5 Package = "go-chi/chi.v5" PackageGoPGV10 Package = "go-pg/pg.v10" @@ -630,6 +631,10 @@ var packages = map[Package]PackageInfo{ TracedPackage: "github.com/rs/zerolog", EnvVarPrefix: "ZEROLOG", }, + PackageGoUberOrgZap: { + TracedPackage: "go.uber.org/zap", + EnvVarPrefix: "ZAP", + }, PackageShopifySarama: { TracedPackage: "github.com/Shopify/sarama", EnvVarPrefix: "SARAMA", diff --git a/internal/env/supported_configurations.gen.go b/internal/env/supported_configurations.gen.go index 2d64b840e7..e3a489a9fe 100644 --- a/internal/env/supported_configurations.gen.go +++ b/internal/env/supported_configurations.gen.go @@ -264,6 +264,7 @@ var SupportedConfigurations = map[string]struct{}{ "DD_TRACE_VALKEY_RAW_COMMAND": {}, "DD_TRACE_VAULT_ANALYTICS_ENABLED": {}, "DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH": {}, + "DD_TRACE_ZAP_ANALYTICS_ENABLED": {}, "DD_TRACE_ZEROLOG_ANALYTICS_ENABLED": {}, "DD_TRACE__ANALYTICS_ENABLED": {}, "DD_VERSION": {}, diff --git a/internal/env/supported_configurations.json b/internal/env/supported_configurations.json index 0bf8c46f91..910b43af76 100644 --- a/internal/env/supported_configurations.json +++ b/internal/env/supported_configurations.json @@ -1794,6 +1794,13 @@ "default": "512" } ], + "DD_TRACE_ZAP_ANALYTICS_ENABLED": [ + { + "implementation": "A", + "type": "boolean", + "default": "false" + } + ], "DD_TRACE_ZEROLOG_ANALYTICS_ENABLED": [ { "implementation": "A", diff --git a/internal/orchestrion/_integration/go.mod b/internal/orchestrion/_integration/go.mod index 330629cede..037f4c3ba5 100644 --- a/internal/orchestrion/_integration/go.mod +++ b/internal/orchestrion/_integration/go.mod @@ -67,6 +67,7 @@ require ( github.com/xlab/treeprint v1.2.0 go.mongodb.org/mongo-driver v1.17.1 go.mongodb.org/mongo-driver/v2 v2.3.0 + go.uber.org/zap v1.28.0 google.golang.org/api v0.273.1 google.golang.org/grpc v1.82.0 google.golang.org/grpc/examples v0.0.0-20240521165117-aea78bdf9d13 @@ -115,6 +116,7 @@ require ( github.com/DataDog/dd-trace-go/contrib/go-redis/redis/v2 v2.11.0-dev // indirect github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver.v2/v2 v2.11.0-dev // indirect github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver/v2 v2.11.0-dev // indirect + github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 v2.11.0-dev // indirect github.com/DataDog/dd-trace-go/contrib/gocql/gocql/v2 v2.11.0-dev // indirect github.com/DataDog/dd-trace-go/contrib/gofiber/fiber.v2/v2 v2.11.0-dev // indirect github.com/DataDog/dd-trace-go/contrib/gomodule/redigo/v2 v2.11.0-dev // indirect @@ -361,7 +363,6 @@ require ( go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.8.0 // indirect @@ -434,6 +435,8 @@ replace github.com/DataDog/dd-trace-go/contrib/go-redis/redis/v2 => ../../../con replace github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver/v2 => ../../../contrib/go.mongodb.org/mongo-driver +replace github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 => ../../../contrib/go.uber.org/zap + replace github.com/DataDog/dd-trace-go/contrib/gocql/gocql/v2 => ../../../contrib/gocql/gocql replace github.com/DataDog/dd-trace-go/contrib/gofiber/fiber.v2/v2 => ../../../contrib/gofiber/fiber.v2 diff --git a/internal/orchestrion/_integration/zap/base.go b/internal/orchestrion/_integration/zap/base.go new file mode 100644 index 0000000000..2f0bcc5267 --- /dev/null +++ b/internal/orchestrion/_integration/zap/base.go @@ -0,0 +1,61 @@ +// 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 2023-present Datadog, Inc. + +package zap + +import ( + "bufio" + "bytes" + "context" + "encoding/json" + "strconv" + "testing" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +func newJSONCore(buf *bytes.Buffer) zapcore.Core { + return zapcore.NewCore( + zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig()), + zapcore.AddSync(buf), + zapcore.DebugLevel, + ) +} + +// runTest starts a root span, calls logFn with the context, then asserts every +// log line contains dd.trace_id and dd.span_id matching the active span exactly. +func runTest(ctx context.Context, t *testing.T, buf *bytes.Buffer, logFn func(context.Context)) { + t.Helper() + + span, ctx := tracer.StartSpanFromContext(ctx, "test.root") + defer span.Finish() + + logFn(ctx) + + wantTraceID := span.Context().TraceID() + wantSpanID := strconv.FormatUint(span.Context().SpanID(), 10) + + logs := buf.String() + t.Logf("got logs:\n%s", logs) + require.NotEmpty(t, logs, "no log output produced") + + s := bufio.NewScanner(bytes.NewBufferString(logs)) + for s.Scan() { + line := s.Bytes() + var data map[string]any + require.NoError(t, json.Unmarshal(line, &data), "log line is not valid JSON: %s", line) + assert.Equal(t, wantTraceID, data["dd.trace_id"], "wrong dd.trace_id in: %s", line) + assert.Equal(t, wantSpanID, data["dd.span_id"], "wrong dd.span_id in: %s", line) + } +} + +func expectedTraces() trace.Traces { return trace.Traces{} } diff --git a/internal/orchestrion/_integration/zap/child_logger.go b/internal/orchestrion/_integration/zap/child_logger.go new file mode 100644 index 0000000000..b58e8d8d13 --- /dev/null +++ b/internal/orchestrion/_integration/zap/child_logger.go @@ -0,0 +1,43 @@ +// 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 2023-present Datadog, Inc. + +package zap + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +// TestCaseChildLogger tests Datadog trace correlation when using a child logger +// created via logger.With(), the most common pattern in component-based code. +type TestCaseChildLogger struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseChildLogger) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseChildLogger) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, func(ctx context.Context) { + logWithChildLogger(ctx, tc.logger) + }) +} + +func (*TestCaseChildLogger) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logWithChildLogger(ctx context.Context, logger *zap.Logger) { + child := logger.With(zap.String("component", "test"), zap.Int("version", 1)) + child.Info("info from child") + child.Warn("warn from child") + child.Error("error from child") +} diff --git a/internal/orchestrion/_integration/zap/generated_test.go b/internal/orchestrion/_integration/zap/generated_test.go new file mode 100644 index 0000000000..c17e9641dd --- /dev/null +++ b/internal/orchestrion/_integration/zap/generated_test.go @@ -0,0 +1,62 @@ +// 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 2023-present Datadog, Inc. +// +// Code generated by 'go generate'; DO NOT EDIT. + +package zap + +import ( + "testing" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/harness" +) + +func TestChildLogger(t *testing.T) { + harness.Run(t, new(TestCaseChildLogger)) +} + +func TestGlobalLogger(t *testing.T) { + harness.Run(t, new(TestCaseGlobalLogger)) +} + +func TestGoroutine(t *testing.T) { + harness.Run(t, new(TestCaseGoroutine)) +} + +func TestLogMethod(t *testing.T) { + harness.Run(t, new(TestCaseLogMethod)) +} + +func TestNewLogger(t *testing.T) { + harness.Run(t, new(TestCaseNewLogger)) +} + +func TestNilRequest(t *testing.T) { + harness.Run(t, new(TestCaseNilRequest)) +} + +func TestNoContext(t *testing.T) { + harness.Run(t, new(TestCaseNoContext)) +} + +func TestRequestContext(t *testing.T) { + harness.Run(t, new(TestCaseRequestContext)) +} + +func TestSugaredLogMethod(t *testing.T) { + harness.Run(t, new(TestCaseSugaredLogMethod)) +} + +func TestSugaredLogger(t *testing.T) { + harness.Run(t, new(TestCaseSugaredLogger)) +} + +func TestValueReceiver(t *testing.T) { + harness.Run(t, new(TestCaseValueReceiver)) +} + +func TestVariadicForward(t *testing.T) { + harness.Run(t, new(TestCaseVariadicForward)) +} diff --git a/internal/orchestrion/_integration/zap/global_logger.go b/internal/orchestrion/_integration/zap/global_logger.go new file mode 100644 index 0000000000..7edd64e04a --- /dev/null +++ b/internal/orchestrion/_integration/zap/global_logger.go @@ -0,0 +1,41 @@ +// 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 2023-present Datadog, Inc. + +package zap + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +// TestCaseGlobalLogger tests Datadog trace correlation when using the zap +// global logger functions (zap.L()). +type TestCaseGlobalLogger struct { + logs *bytes.Buffer +} + +func (tc *TestCaseGlobalLogger) Setup(_ context.Context, t *testing.T) { + tc.logs = new(bytes.Buffer) + restore := zap.ReplaceGlobals(zap.New(newJSONCore(tc.logs))) + t.Cleanup(restore) +} + +func (tc *TestCaseGlobalLogger) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, logWithGlobalLogger) +} + +func (*TestCaseGlobalLogger) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logWithGlobalLogger(ctx context.Context) { + zap.L().Debug("debug message") + zap.L().Info("info message") + zap.L().Warn("warn message") + zap.L().Error("error message") +} diff --git a/internal/orchestrion/_integration/zap/goroutine.go b/internal/orchestrion/_integration/zap/goroutine.go new file mode 100644 index 0000000000..9079a2984e --- /dev/null +++ b/internal/orchestrion/_integration/zap/goroutine.go @@ -0,0 +1,47 @@ +// 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 2023-present Datadog, Inc. + +package zap + +// TestCaseGoroutine verifies that trace correlation works when logging from a +// goroutine that receives a context.Context as a parameter. This distinguishes +// call-site injection (which works correctly) from GLS-based approaches (which +// are unreliable across goroutine boundaries). + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +type TestCaseGoroutine struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseGoroutine) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseGoroutine) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, func(ctx context.Context) { + done := make(chan struct{}) + go logInGoroutine(ctx, tc.logger, done) + <-done + }) +} + +func (*TestCaseGoroutine) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logInGoroutine(ctx context.Context, logger *zap.Logger, done chan<- struct{}) { + defer close(done) + logger.Info("from goroutine") + logger.Warn("warn from goroutine") +} diff --git a/internal/orchestrion/_integration/zap/log_method.go b/internal/orchestrion/_integration/zap/log_method.go new file mode 100644 index 0000000000..98fc5de9d5 --- /dev/null +++ b/internal/orchestrion/_integration/zap/log_method.go @@ -0,0 +1,66 @@ +// 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 2023-present Datadog, Inc. + +package zap + +// TestCaseLogMethod and TestCaseSugaredLogMethod verify that trace correlation +// works for the generic, dynamic-level Log/Logf/Logw/Logln entrypoints, not +// just the fixed-level methods (Info, Warn, ...). + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +type TestCaseLogMethod struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseLogMethod) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseLogMethod) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, func(ctx context.Context) { + logWithLogMethod(ctx, tc.logger) + }) +} + +func (*TestCaseLogMethod) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logWithLogMethod(ctx context.Context, logger *zap.Logger) { + logger.Log(zapcore.InfoLevel, "dynamic level message") +} + +type TestCaseSugaredLogMethod struct { + logs *bytes.Buffer +} + +func (tc *TestCaseSugaredLogMethod) Setup(_ context.Context, t *testing.T) { + tc.logs = new(bytes.Buffer) + restore := zap.ReplaceGlobals(zap.New(newJSONCore(tc.logs))) + t.Cleanup(restore) +} + +func (tc *TestCaseSugaredLogMethod) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, logWithSugaredLogMethods) +} + +func (*TestCaseSugaredLogMethod) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logWithSugaredLogMethods(ctx context.Context) { + zap.S().Log(zapcore.InfoLevel, "dynamic level message") + zap.S().Logf(zapcore.InfoLevel, "formatted %s", "message") + zap.S().Logw(zapcore.InfoLevel, "structured message", "key", "value") + zap.S().Logln(zapcore.InfoLevel, "line message") +} diff --git a/internal/orchestrion/_integration/zap/new_logger.go b/internal/orchestrion/_integration/zap/new_logger.go new file mode 100644 index 0000000000..2315e13dc7 --- /dev/null +++ b/internal/orchestrion/_integration/zap/new_logger.go @@ -0,0 +1,43 @@ +// 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 2023-present Datadog, Inc. + +package zap + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +// TestCaseNewLogger tests Datadog trace correlation when using zap.New() to +// construct a logger and calling its log methods directly. +type TestCaseNewLogger struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseNewLogger) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseNewLogger) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, func(ctx context.Context) { + logWithLogger(ctx, tc.logger) + }) +} + +func (*TestCaseNewLogger) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logWithLogger(ctx context.Context, logger *zap.Logger) { + logger.Debug("debug message") + logger.Info("info message") + logger.Warn("warn message") + logger.Error("error message") +} diff --git a/internal/orchestrion/_integration/zap/nil_request.go b/internal/orchestrion/_integration/zap/nil_request.go new file mode 100644 index 0000000000..f84f391521 --- /dev/null +++ b/internal/orchestrion/_integration/zap/nil_request.go @@ -0,0 +1,65 @@ +// 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 2023-present Datadog, Inc. + +package zap + +// TestCaseNilRequest verifies that logging does not panic when the calling +// function has a *http.Request parameter but it is nil. The aspect falls back +// to TraceFieldsFromRequest, which is nil-safe, so trace fields are simply +// omitted rather than panicking on req.Context(). + +import ( + "bufio" + "bytes" + "context" + "net/http" + "regexp" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +type TestCaseNilRequest struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseNilRequest) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseNilRequest) Run(ctx context.Context, t *testing.T) { + span, _ := tracer.StartSpanFromContext(ctx, "test.root") + defer span.Finish() + + // Must not panic even though req is nil. + logWithNilRequest(nil, tc.logger) + + logs := tc.logs.String() + t.Logf("got logs:\n%s", logs) + + s := bufio.NewScanner(bytes.NewBufferString(logs)) + for s.Scan() { + line := s.Bytes() + if ok, _ := regexp.Match(`"dd\.trace_id"`, line); ok { + t.Errorf("unexpected dd.trace_id injected in log line (nil request): %s", line) + } + if ok, _ := regexp.Match(`"dd\.span_id"`, line); ok { + t.Errorf("unexpected dd.span_id injected in log line (nil request): %s", line) + } + } +} + +func (*TestCaseNilRequest) ExpectedTraces() trace.Traces { return expectedTraces() } + +// logWithNilRequest has a *http.Request but no context.Context parameter. The +// aspect must not panic when req is nil. +func logWithNilRequest(req *http.Request, logger *zap.Logger) { + logger.Info("handling request with nil request") +} diff --git a/internal/orchestrion/_integration/zap/no_context.go b/internal/orchestrion/_integration/zap/no_context.go new file mode 100644 index 0000000000..7067692e3d --- /dev/null +++ b/internal/orchestrion/_integration/zap/no_context.go @@ -0,0 +1,62 @@ +// 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 2023-present Datadog, Inc. + +package zap + +// TestCaseNoContext verifies that trace fields are NOT injected when no +// context.Context is available in the calling function's scope. + +import ( + "bufio" + "bytes" + "context" + "regexp" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +type TestCaseNoContext struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseNoContext) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseNoContext) Run(ctx context.Context, t *testing.T) { + // A span is active, but ctx is intentionally not passed to logWithoutContext. + span, _ := tracer.StartSpanFromContext(ctx, "test.root") + defer span.Finish() + + logWithoutContext(tc.logger) + + logs := tc.logs.String() + t.Logf("got logs:\n%s", logs) + + s := bufio.NewScanner(bytes.NewBufferString(logs)) + for s.Scan() { + line := s.Bytes() + if ok, _ := regexp.Match(`"dd\.trace_id"`, line); ok { + t.Errorf("unexpected dd.trace_id injected in log line (no context in scope): %s", line) + } + if ok, _ := regexp.Match(`"dd\.span_id"`, line); ok { + t.Errorf("unexpected dd.span_id injected in log line (no context in scope): %s", line) + } + } +} + +func (*TestCaseNoContext) ExpectedTraces() trace.Traces { return expectedTraces() } + +// logWithoutContext has no context.Context parameter — no trace fields should +// be injected into the log output. +func logWithoutContext(logger *zap.Logger) { + logger.Info("no context available") +} diff --git a/internal/orchestrion/_integration/zap/request_context.go b/internal/orchestrion/_integration/zap/request_context.go new file mode 100644 index 0000000000..253477ee8b --- /dev/null +++ b/internal/orchestrion/_integration/zap/request_context.go @@ -0,0 +1,49 @@ +// 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 2023-present Datadog, Inc. + +package zap + +// TestCaseRequestContext verifies that trace correlation works when the calling +// function has an *http.Request but no context.Context parameter directly. The +// aspect falls back to req.Context() to obtain the trace context. + +import ( + "bytes" + "context" + "net/http" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +type TestCaseRequestContext struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseRequestContext) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseRequestContext) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, func(ctx context.Context) { + req, _ := http.NewRequestWithContext(ctx, http.MethodGet, "/", nil) + logWithRequest(req, tc.logger) + }) +} + +func (*TestCaseRequestContext) ExpectedTraces() trace.Traces { return expectedTraces() } + +// logWithRequest has an *http.Request but no context.Context parameter. The +// aspect uses req.Context() as the trace source. +func logWithRequest(req *http.Request, logger *zap.Logger) { + logger.Info("handling request", + zap.String("method", req.Method), + zap.String("path", req.URL.Path), + ) +} diff --git a/internal/orchestrion/_integration/zap/sugared_logger.go b/internal/orchestrion/_integration/zap/sugared_logger.go new file mode 100644 index 0000000000..a0de6c7515 --- /dev/null +++ b/internal/orchestrion/_integration/zap/sugared_logger.go @@ -0,0 +1,41 @@ +// 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 2023-present Datadog, Inc. + +package zap + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +// TestCaseSugaredLogger tests Datadog trace correlation when using the zap +// global sugared logger (zap.S()), covering Print-style, structured, and +// printf calling conventions. +type TestCaseSugaredLogger struct { + logs *bytes.Buffer +} + +func (tc *TestCaseSugaredLogger) Setup(_ context.Context, t *testing.T) { + tc.logs = new(bytes.Buffer) + restore := zap.ReplaceGlobals(zap.New(newJSONCore(tc.logs))) + t.Cleanup(restore) +} + +func (tc *TestCaseSugaredLogger) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, logWithSugaredLogger) +} + +func (*TestCaseSugaredLogger) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logWithSugaredLogger(ctx context.Context) { + zap.S().Info("info message") + zap.S().Infow("structured message", "key", "value", "count", 42) + zap.S().Infof("formatted %s", "message") +} diff --git a/internal/orchestrion/_integration/zap/value_receiver.go b/internal/orchestrion/_integration/zap/value_receiver.go new file mode 100644 index 0000000000..a47ba1a1c8 --- /dev/null +++ b/internal/orchestrion/_integration/zap/value_receiver.go @@ -0,0 +1,42 @@ +// 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 2023-present Datadog, Inc. + +package zap + +// TestCaseValueReceiver verifies that trace correlation works when the logger +// is held as a value (zap.Logger) rather than a pointer (*zap.Logger). + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +type TestCaseValueReceiver struct { + logger zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseValueReceiver) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = *zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseValueReceiver) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, func(ctx context.Context) { + logWithValueLogger(ctx, tc.logger) + }) +} + +func (*TestCaseValueReceiver) ExpectedTraces() trace.Traces { return expectedTraces() } + +func logWithValueLogger(ctx context.Context, logger zap.Logger) { + logger.Info("value receiver info") + logger.Warn("value receiver warn") +} diff --git a/internal/orchestrion/_integration/zap/variadic_forward.go b/internal/orchestrion/_integration/zap/variadic_forward.go new file mode 100644 index 0000000000..f89dad566b --- /dev/null +++ b/internal/orchestrion/_integration/zap/variadic_forward.go @@ -0,0 +1,72 @@ +// 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 2023-present Datadog, Inc. + +package zap + +// TestCaseVariadicForward exercises the canonical "logging wrapper" pattern in +// which a helper forwards its variadic []zap.Field argument to an inner zap +// method via the spread operator (fields...). The orchestrion rewrite must +// preserve the call's Ellipsis when wrapping the receiver chain; if it drops +// the spread, the rewritten code passes []zap.Field where zap.Field is +// expected and fails to compile. +// +// Reproduces the failure seen when building etcd via +// github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap, where +// ctxzap.Debug/Info/Warn/Error forward their variadic fields to the underlying +// *zap.Logger. + +import ( + "bytes" + "context" + "testing" + + "go.uber.org/zap" + + "github.com/DataDog/dd-trace-go/v2/internal/orchestrion/_integration/internal/trace" +) + +type TestCaseVariadicForward struct { + logger *zap.Logger + logs *bytes.Buffer +} + +func (tc *TestCaseVariadicForward) Setup(_ context.Context, _ *testing.T) { + tc.logs = new(bytes.Buffer) + tc.logger = zap.New(newJSONCore(tc.logs)) +} + +func (tc *TestCaseVariadicForward) Run(ctx context.Context, t *testing.T) { + runTest(ctx, t, tc.logs, func(ctx context.Context) { + forwardDebug(ctx, tc.logger, "debug forwarded", zap.String("k", "v")) + forwardInfo(ctx, tc.logger, "info forwarded", zap.String("k", "v")) + forwardWarn(ctx, tc.logger, "warn forwarded", zap.String("k", "v")) + forwardError(ctx, tc.logger, "error forwarded", zap.String("k", "v")) + }) +} + +func (*TestCaseVariadicForward) ExpectedTraces() trace.Traces { return expectedTraces() } + +// The wrappers below intentionally forward fields via the spread operator. +// ctx is in scope so the orchestrion zap aspect fires on the inner call. + +func forwardDebug(ctx context.Context, logger *zap.Logger, msg string, fields ...zap.Field) { + _ = ctx + logger.Debug(msg, fields...) +} + +func forwardInfo(ctx context.Context, logger *zap.Logger, msg string, fields ...zap.Field) { + _ = ctx + logger.Info(msg, fields...) +} + +func forwardWarn(ctx context.Context, logger *zap.Logger, msg string, fields ...zap.Field) { + _ = ctx + logger.Warn(msg, fields...) +} + +func forwardError(ctx context.Context, logger *zap.Logger, msg string, fields ...zap.Field) { + _ = ctx + logger.Error(msg, fields...) +} diff --git a/orchestrion/all/go.mod b/orchestrion/all/go.mod index a70103fe98..f75b5e3436 100644 --- a/orchestrion/all/go.mod +++ b/orchestrion/all/go.mod @@ -23,6 +23,7 @@ require ( github.com/DataDog/dd-trace-go/contrib/go-redis/redis/v2 v2.11.0-dev github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver.v2/v2 v2.11.0-dev github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver/v2 v2.11.0-dev + github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 v2.11.0-dev github.com/DataDog/dd-trace-go/contrib/gocql/gocql/v2 v2.11.0-dev github.com/DataDog/dd-trace-go/contrib/gofiber/fiber.v2/v2 v2.11.0-dev github.com/DataDog/dd-trace-go/contrib/gomodule/redigo/v2 v2.11.0-dev @@ -334,6 +335,7 @@ replace ( github.com/DataDog/dd-trace-go/contrib/go-redis/redis/v2 => ../../contrib/go-redis/redis github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver.v2/v2 => ../../contrib/go.mongodb.org/mongo-driver.v2 github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver/v2 => ../../contrib/go.mongodb.org/mongo-driver + github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2 => ../../contrib/go.uber.org/zap github.com/DataDog/dd-trace-go/contrib/gocql/gocql/v2 => ../../contrib/gocql/gocql github.com/DataDog/dd-trace-go/contrib/gofiber/fiber.v2/v2 => ../../contrib/gofiber/fiber.v2 github.com/DataDog/dd-trace-go/contrib/gomodule/redigo/v2 => ../../contrib/gomodule/redigo diff --git a/orchestrion/all/orchestrion.tool.go b/orchestrion/all/orchestrion.tool.go index 7d91ad2b33..07e2d30ef3 100644 --- a/orchestrion/all/orchestrion.tool.go +++ b/orchestrion/all/orchestrion.tool.go @@ -42,6 +42,7 @@ import ( _ "github.com/DataDog/dd-trace-go/contrib/go-redis/redis/v2" // integration _ "github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver.v2/v2/mongo" // integration _ "github.com/DataDog/dd-trace-go/contrib/go.mongodb.org/mongo-driver/v2/mongo" // integration + _ "github.com/DataDog/dd-trace-go/contrib/go.uber.org/zap/v2" // integration _ "github.com/DataDog/dd-trace-go/contrib/gocql/gocql/v2" // integration _ "github.com/DataDog/dd-trace-go/contrib/gofiber/fiber.v2/v2" // integration _ "github.com/DataDog/dd-trace-go/contrib/gomodule/redigo/v2" // integration