diff --git a/README.md b/README.md index 522d1962ed..a3cf8117b9 100644 --- a/README.md +++ b/README.md @@ -95,10 +95,10 @@ Before considering contributions to the project, please take a moment to read ou Tests can be run locally using the Go toolset. To run integration tests locally, you should set the `INTEGRATION` environment variable. The dependencies of the integration tests are best run via Docker. To find out the versions and the set-up take a look at our [docker-compose config](./docker-compose.yaml). -The best way to run the entire test suite is using the [test.sh](./test.sh) script. You'll need Docker and docker-compose installed. Run `./test.sh --all` to run all of the integration tests through the docker-compose environment. Run `./test.sh --help` for more options. +The best way to run the entire test suite is using the [test.sh](./test.sh) script. You'll need Docker and docker-compose installed. If this is your first time running the tests, you should run `./test.sh -t` to install any missing test tools/dependencies. Run `./test.sh --all` to run all of the integration tests through the docker-compose environment. Run `./test.sh --help` for more options. If you're only interested in the tests for a specific integration it can be useful to spin up just the required containers via docker-compose. For example if you're running tests that need the `mysql` database container to be up: ```shell docker compose -f docker-compose.yaml -p dd-trace-go up -d mysql -``` +``` \ No newline at end of file diff --git a/ddtrace/tracer/sqlcomment.go b/ddtrace/tracer/sqlcomment.go index 99726fbbe7..0bcfe97d67 100644 --- a/ddtrace/tracer/sqlcomment.go +++ b/ddtrace/tracer/sqlcomment.go @@ -40,6 +40,10 @@ const ( sqlCommentDBService = "dddbs" sqlCommentParentVersion = "ddpv" sqlCommentEnv = "dde" + // These keys are for the database we are connecting to, instead of the service we are running in. + // "Peer" is the OpenTelemetry nomenclature for "thing I am talking to" + sqlCommentPeerHostname = "ddh" + sqlCommentPeerDBName = "dddb" ) // Current trace context version (see https://www.w3.org/TR/trace-context/#version) @@ -49,10 +53,12 @@ const w3cContextVersion = "00" // of a sqlcommenter formatted comment prepended to the original query text. // See https://google.github.io/sqlcommenter/spec/ for more details. type SQLCommentCarrier struct { - Query string - Mode DBMPropagationMode - DBServiceName string - SpanID uint64 + Query string + Mode DBMPropagationMode + DBServiceName string + SpanID uint64 + PeerDBHostname string + PeerDBName string } // Inject injects a span context in the carrier's Query field as a comment. @@ -83,7 +89,12 @@ func (c *SQLCommentCarrier) Inject(ctx *SpanContext) error { if v, ok := ctx.meta(ext.Version); ok && v != "" { tags[sqlCommentParentVersion] = v } - + if c.PeerDBName != "" { + tags[sqlCommentPeerDBName] = c.PeerDBName + } + if c.PeerDBHostname != "" { + tags[sqlCommentPeerHostname] = c.PeerDBHostname + } } if globalconfig.ServiceName() != "" { tags[sqlCommentParentService] = globalconfig.ServiceName() @@ -134,7 +145,7 @@ func commentQuery(query string, tags map[string]string) string { var b strings.Builder // the sqlcommenter specification dictates that tags should be sorted. Since we know all injected keys, // we skip a sorting operation by specifying the order of keys statically - orderedKeys := []string{sqlCommentDBService, sqlCommentEnv, sqlCommentParentService, sqlCommentParentVersion, sqlCommentTraceParent} + orderedKeys := []string{sqlCommentDBService, sqlCommentEnv, sqlCommentParentService, sqlCommentParentVersion, sqlCommentTraceParent, sqlCommentPeerHostname, sqlCommentPeerDBName} first := true for _, k := range orderedKeys { if v, ok := tags[k]; ok { diff --git a/ddtrace/tracer/sqlcomment_test.go b/ddtrace/tracer/sqlcomment_test.go index 5f77593023..f36defd8cd 100644 --- a/ddtrace/tracer/sqlcomment_test.go +++ b/ddtrace/tracer/sqlcomment_test.go @@ -25,6 +25,8 @@ func TestSQLCommentCarrier(t *testing.T) { mode DBMPropagationMode injectSpan bool samplingPriority int + peerDBHostname string + peerDBName string expectedQuery string expectedSpanIDGen bool expectedExtractErr error @@ -34,6 +36,8 @@ func TestSQLCommentCarrier(t *testing.T) { query: "SELECT * from FOO", mode: DBMPropagationModeFull, injectSpan: true, + peerDBHostname: "", + peerDBName: "", expectedQuery: "/*dddbs='whiskey-db',dde='test-env',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',ddpv='1.0.0',traceparent='00-0000000000000000000000000000000a--00'*/ SELECT * from FOO", expectedSpanIDGen: true, expectedExtractErr: nil, @@ -43,6 +47,8 @@ func TestSQLCommentCarrier(t *testing.T) { query: "SELECT * from FOO", mode: DBMPropagationModeService, injectSpan: true, + peerDBHostname: "", + peerDBName: "", expectedQuery: "/*dddbs='whiskey-db',dde='test-env',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',ddpv='1.0.0'*/ SELECT * from FOO", expectedSpanIDGen: false, expectedExtractErr: ErrSpanContextNotFound, @@ -51,6 +57,8 @@ func TestSQLCommentCarrier(t *testing.T) { name: "no-trace", query: "SELECT * from FOO", mode: DBMPropagationModeFull, + peerDBHostname: "", + peerDBName: "", expectedQuery: "/*dddbs='whiskey-db',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',traceparent='00-0000000000000000--00'*/ SELECT * from FOO", expectedSpanIDGen: true, expectedExtractErr: nil, @@ -60,6 +68,8 @@ func TestSQLCommentCarrier(t *testing.T) { query: "", mode: DBMPropagationModeFull, injectSpan: true, + peerDBHostname: "", + peerDBName: "", expectedQuery: "/*dddbs='whiskey-db',dde='test-env',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',ddpv='1.0.0',traceparent='00-0000000000000000000000000000000a--00'*/", expectedSpanIDGen: true, expectedExtractErr: nil, @@ -90,10 +100,48 @@ func TestSQLCommentCarrier(t *testing.T) { mode: DBMPropagationModeFull, injectSpan: true, samplingPriority: 1, + peerDBHostname: "", + peerDBName: "", expectedQuery: "/*dddbs='whiskey-db',dde='test-env',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',ddpv='1.0.0',traceparent='00-0000000000000000000000000000000a--01'*/ /* c */ SELECT * from FOO /**/", expectedSpanIDGen: true, expectedExtractErr: nil, }, + { + name: "peer_entity_tags_dddb", + query: "/* c */ SELECT * from FOO /**/", + mode: DBMPropagationModeFull, + injectSpan: true, + samplingPriority: 1, + peerDBName: "fake-database", + peerDBHostname: "", + expectedQuery: "/*dddbs='whiskey-db',dde='test-env',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',ddpv='1.0.0',traceparent='00-0000000000000000000000000000000a--01',dddb='fake-database'*/ /* c */ SELECT * from FOO /**/", + expectedSpanIDGen: true, + expectedExtractErr: nil, + }, + { + name: "peer_entity_tags_ddh", + query: "/* c */ SELECT * from FOO /**/", + mode: DBMPropagationModeFull, + injectSpan: true, + samplingPriority: 1, + peerDBHostname: "fake-hostname", + peerDBName: "", + expectedQuery: "/*dddbs='whiskey-db',dde='test-env',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',ddpv='1.0.0',traceparent='00-0000000000000000000000000000000a--01',ddh='fake-hostname'*/ /* c */ SELECT * from FOO /**/", + expectedSpanIDGen: true, + expectedExtractErr: nil, + }, + { + name: "peer_entity_tags_dddb_and_ddh", + query: "/* c */ SELECT * from FOO /**/", + mode: DBMPropagationModeFull, + injectSpan: true, + samplingPriority: 1, + peerDBHostname: "fake-hostname", + peerDBName: "fake-database", + expectedQuery: "/*dddbs='whiskey-db',dde='test-env',ddps='whiskey-service%20%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D',ddpv='1.0.0',traceparent='00-0000000000000000000000000000000a--01',ddh='fake-hostname',dddb='fake-database'*/ /* c */ SELECT * from FOO /**/", + expectedSpanIDGen: true, + expectedExtractErr: nil, + }, } for _, tc := range testCases { diff --git a/go.work.sum b/go.work.sum index 8142a88f36..eaed492b4f 100644 --- a/go.work.sum +++ b/go.work.sum @@ -511,6 +511,7 @@ github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= +github.com/Shopify/toxiproxy/v2 v2.5.0/go.mod h1:yhM2epWtAmel9CB8r2+L+PCmhH6yH2pITaPAo7jxJl0= github.com/actgardner/gogen-avro/v10 v10.2.1 h1:z3pOGblRjAJCYpkIJ8CmbMJdksi4rAhaygw0dyXZ930= github.com/actgardner/gogen-avro/v9 v9.1.0 h1:YZ5tCwV5xnDZrG4uRDQYT2VAWZCRAG3eyQH/WYR2T6Q= github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9 h1:7kQgkwGRoLzC9K0oyXdJo7nve/bynv/KwUsxbiTlzAM= @@ -543,6 +544,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/boombuler/barcode v1.0.1 h1:NDBbPmhS+EqABEs5Kg3n/5ZNjy73Pz7SIV+KCeqyXcs= github.com/bshuster-repo/logrus-logstash-hook v0.4.1 h1:pgAtgj+A31JBVtEHu2uHuEx0n+2ukqUJnS2vVe5pQNA= +github.com/bsm/ginkgo/v2 v2.9.5/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd h1:rFt+Y/IK1aEZkEHchZRSq9OQbsSzIT/OrI8YFFmRIng= github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ= @@ -663,6 +666,7 @@ github.com/dvyukov/go-fuzz v0.0.0-20210103155950-6a8e9d1f2415 h1:q1oJaUPdmpDm/Vy github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/emicklei/go-restful v2.9.5+incompatible h1:spTtZBk5DYEvbxMVutUuTyh1Ao2r4iyvLdACqsl/Ljk= github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM= +github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.11.1 h1:wSUXTlLfiAQRWs2F+p+EKOY9rUyis1MyGqJ2DIk5HpM= @@ -684,6 +688,8 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa h1:RDBNVkRviHZtvDvId8XSGPu3rmpmSe+wKRcEWNgsfWU= github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7 h1:LofdAjjjqCSXMwLGgOgnE+rdPuvX9DxCqaHwKy7i/ko= +github.com/garyburd/redigo v1.6.4 h1:LFu2R3+ZOPgSMWMOL+saa/zXRjw0ID2G8FepO53BGlg= +github.com/garyburd/redigo v1.6.4/go.mod h1:rTb6epsqigu3kYKBnaF028A7Tf/Aw5s0cqA47doKKqw= github.com/getkin/kin-openapi v0.76.0 h1:j77zg3Ec+k+r+GA3d8hBoXpAc6KX9TbBPrwQGBIy2sY= github.com/getsentry/raven-go v0.2.0 h1:no+xWJRb5ZI7eE8TWgIq1jLulQiIoLG0IfYxv5JYMGs= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= @@ -709,8 +715,10 @@ github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXym github.com/go-openapi/spec v0.19.3 h1:0XRyw8kguri6Yw4SxhsQA/atC88yqrk0+G4YhI2wabc= github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-pdf/fpdf v0.6.0 h1:MlgtGIfsdMEEQJr2le6b/HNr1ZlQwxyWr77r2aj2U/8= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-text/typesetting v0.0.0-20230329143336-a38d00edd832 h1:yV4rFdcvwZXE0lZZ3EoBWjVysHyVo8DLY8VihDciNN0= github.com/go-text/typesetting v0.0.0-20230329143336-a38d00edd832/go.mod h1:zvWM81wAVW6QfVDI6yxfbCuoLnobSYTuMsrXU/u11y8= github.com/gobwas/httphead v0.1.0 h1:exrUm0f4YX0L7EBwZHuCF4GDp8aJfVeBrlLQrs6NqWU= @@ -723,6 +731,8 @@ github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e h1:BWhy2j3IXJhjCbC68Fp github.com/godbus/dbus/v5 v5.0.6 h1:mkgN1ofwASrYnJ5W6U/BxG15eXXXjirgZc7CLqkcaro= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= @@ -760,10 +770,12 @@ github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92Bcuy github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk= github.com/hamba/avro v1.5.6 h1:/UBljlJ9hLjkcY7PhpI/bFYb4RMEXHEwHr17gAm/+l8= +github.com/hashicorp/consul/sdk v0.14.1/go.mod h1:vFt03juSzocLRFo59NkeQHHmQa6+g7oU0pfzdI1mUhg= github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0 h1:pSjQfW3vPtrOTcasTUKgCTQT7OGPPTTMVRrOfU6FJD8= github.com/hashicorp/go-kms-wrapping/entropy/v2 v2.0.0/go.mod h1:xvb32K2keAc+R8DSFG2IwDcydK9DBQE+fGA5fsw6hSk= github.com/hashicorp/go-kms-wrapping/v2 v2.0.8 h1:9Q2lu1YbbmiAgvYZ7Pr31RdlVonUpX+mmDL7Z7qTA2U= github.com/hashicorp/go-kms-wrapping/v2 v2.0.8/go.mod h1:qTCjxGig/kjuj3hk1z8pOUrzbse/GxB1tGfbrq8tGJg= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM= github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= github.com/hashicorp/go-secure-stdlib/base62 v0.1.2 h1:ET4pqyjiGmY09R5y+rSd70J2w45CtbWDNvGqWp/R3Ng= @@ -798,6 +810,8 @@ github.com/j-keck/arping v1.0.2 h1:hlLhuXgQkzIJTZuhMigvG/CuSkaspeaD9hRDk2zuiMI= github.com/jhump/gopoet v0.1.0 h1:gYjOPnzHd2nzB37xYQZxj4EIQNpBrBskRqQQ3q4ZgSg= github.com/jhump/goprotoc v0.5.0 h1:Y1UgUX+txUznfqcGdDef8ZOVlyQvnV0pKWZH08RmZuo= github.com/jhump/protoreflect v1.14.1 h1:N88q7JkxTHWFEqReuTsYH1dPIwXxA0ITNQp7avLY10s= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= github.com/joefitzgerald/rainbow-reporter v0.1.0 h1:AuMG652zjdzI0YCCnXAqATtRBpGXMcAnrajcaTrSeuo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= @@ -820,6 +834,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg= +github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80 h1:6Yzfa6GP0rIo/kULo2bwGEkFvCePZ3qHDDTC3/J9Swo= github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs= github.com/linkedin/goavro v2.1.0+incompatible h1:DV2aUlj2xZiuxQyvag8Dy7zjY69ENjS66bWkSfdpddY= @@ -860,6 +875,7 @@ github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= github.com/moby/sys/mount v0.3.3 h1:fX1SVkXFJ47XWDoeFW4Sq7PdQJnV2QIDZAqjNqgEjUs= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= github.com/moby/sys/signal v0.6.0 h1:aDpY94H8VlhTGa9sNYUFCFsMZIUh5wm0B6XkIoJj/iY= github.com/moby/sys/signal v0.7.0 h1:25RW3d5TnQEoKvRbEKUGay6DCQ46IxAVTT9CUMgmsSI= github.com/moby/sys/signal v0.7.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= @@ -957,6 +973,8 @@ github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtse github.com/tchap/go-patricia v2.2.6+incompatible h1:JvoDL7JSoIP2HDE8AbDH3zC8QBPxmzYe32HHy5yQ+Ck= github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes= github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= +github.com/tidwall/assert v0.1.0/go.mod h1:QLYtGyeqse53vuELQheYl9dngGCJQ+mTtlxcktb+Kj8= +github.com/tidwall/lotsa v1.0.2/go.mod h1:X6NiU+4yHA3fE3Puvpnn1XMDrFZrE9JO2/w+UMuqgR8= github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA= github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c h1:u6SKchux2yDvFQnDHS3lPnIRmfVJ5Sxy3ao2SIdysLQ= github.com/ugorji/go v1.1.4 h1:j4s+tAvLfL3bZyefP2SEWmhBzmuIlH/eqNuPdFPgngw= @@ -985,6 +1003,8 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8= +github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= @@ -1124,8 +1144,12 @@ gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXa gopkg.in/go-playground/validator.v8 v8.18.2 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ= gopkg.in/httprequest.v1 v1.2.1 h1:pEPLMdF/gjWHnKxLpuCYaHFjc8vAB2wrYjXrqDVC16E= gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= +gopkg.in/jinzhu/gorm.v1 v1.9.2 h1:sTqyEcgrxG68jdeUXA9syQHNdeRhhfaYZ+vcL3x730I= +gopkg.in/jinzhu/gorm.v1 v1.9.2/go.mod h1:56JJPUzbikvTVnoyP1nppSkbJ2L8sunqTBDY2fDrmFg= gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw= gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/olivere/elastic.v3 v3.0.75 h1:u3B8p1VlHF3yNLVOlhIWFT3F1ICcHfM5V6FFJe6pPSo= +gopkg.in/olivere/elastic.v3 v3.0.75/go.mod h1:yDEuSnrM51Pc8dM5ov7U8aI/ToR3PG0llA8aRv2qmw0= gopkg.in/resty.v1 v1.12.0 h1:CuXP0Pjfw9rOuY6EP+UvtNvt5DSqHpIxILZKT/quCZI= gopkg.in/retry.v1 v1.0.3 h1:a9CArYczAVv6Qs6VGoLMio99GEs7kY9UzSF9+LD+iGs= gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI= diff --git a/v2/contrib/IBM/sarama/option.go b/v2/contrib/IBM/sarama/option.go index c52dfd709e..9d21448b32 100644 --- a/v2/contrib/IBM/sarama/option.go +++ b/v2/contrib/IBM/sarama/option.go @@ -20,6 +20,8 @@ type config struct { consumerSpanName string producerSpanName string analyticsRate float64 + dataStreamsEnabled bool + groupID string } func defaults(cfg *config) { @@ -37,28 +39,33 @@ func defaults(cfg *config) { } } -// Option describes options for the Sarama integration. -type Option interface { - apply(*config) -} +// An Option is used to customize the config for the sarama tracer. +type Option func(cfg *config) -// OptionFn represents options applicable to WrapConsumer, WrapPartitionConsumer, WrapAsyncProducer and WrapSyncProducer. -type OptionFn func(*config) +// WithServiceName sets the given service name for the intercepted client. +func WithServiceName(name string) Option { + return func(cfg *config) { + cfg.consumerServiceName = name + cfg.producerServiceName = name + } +} -func (fn OptionFn) apply(cfg *config) { - fn(cfg) +// WithDataStreams enables the Data Streams monitoring product features: https://www.datadoghq.com/product/data-streams-monitoring/ +func WithDataStreams() Option { + return func(cfg *config) { + cfg.dataStreamsEnabled = true + } } -// WithService sets the given service name for the intercepted client. -func WithService(name string) OptionFn { +// WithGroupID tags the produced data streams metrics with the given groupID (aka consumer group) +func WithGroupID(groupID string) Option { return func(cfg *config) { - cfg.consumerServiceName = name - cfg.producerServiceName = name + cfg.groupID = groupID } } // WithAnalytics enables Trace Analytics for all started spans. -func WithAnalytics(on bool) OptionFn { +func WithAnalytics(on bool) Option { return func(cfg *config) { if on { cfg.analyticsRate = 1.0 @@ -70,7 +77,7 @@ func WithAnalytics(on bool) OptionFn { // WithAnalyticsRate sets the sampling rate for Trace Analytics events // correlated to started spans. -func WithAnalyticsRate(rate float64) OptionFn { +func WithAnalyticsRate(rate float64) Option { return func(cfg *config) { if rate >= 0.0 && rate <= 1.0 { cfg.analyticsRate = rate diff --git a/v2/contrib/IBM/sarama/sarama.go b/v2/contrib/IBM/sarama/sarama.go index e5f23e6a89..df6dbe4799 100644 --- a/v2/contrib/IBM/sarama/sarama.go +++ b/v2/contrib/IBM/sarama/sarama.go @@ -7,8 +7,11 @@ package sarama // import "github.com/DataDog/dd-trace-go/v2/contrib/IBM/sarama" import ( + "context" "math" + "github.com/DataDog/dd-trace-go/v2/datastreams" + "github.com/DataDog/dd-trace-go/v2/datastreams/options" "github.com/DataDog/dd-trace-go/v2/ddtrace" "github.com/DataDog/dd-trace-go/v2/ddtrace/ext" "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" @@ -42,7 +45,7 @@ func WrapPartitionConsumer(pc sarama.PartitionConsumer, opts ...Option) sarama.P cfg := new(config) defaults(cfg) for _, opt := range opts { - opt.apply(cfg) + opt(cfg) } log.Debug("contrib/IBM/sarama: Wrapping Partition Consumer: %#v", cfg) wrapped := &partitionConsumer{ @@ -76,6 +79,7 @@ func WrapPartitionConsumer(pc sarama.PartitionConsumer, opts ...Option) sarama.P next := tracer.StartSpan(cfg.consumerSpanName, opts...) // reinject the span context so consumers can pick it up tracer.Inject(next.Context(), carrier) + setConsumeCheckpoint(cfg.dataStreamsEnabled, cfg.groupID, msg) wrapped.messages <- msg @@ -127,8 +131,12 @@ type syncProducer struct { // SendMessage calls sarama.SyncProducer.SendMessage and traces the request. func (p *syncProducer) SendMessage(msg *sarama.ProducerMessage) (partition int32, offset int64, err error) { span := startProducerSpan(p.cfg, p.version, msg) + setProduceCheckpoint(p.cfg.dataStreamsEnabled, msg, p.version) partition, offset, err = p.SyncProducer.SendMessage(msg) finishProducerSpan(span, partition, offset, err) + if err == nil && p.cfg.dataStreamsEnabled { + tracer.TrackKafkaProduceOffset(msg.Topic, partition, offset) + } return partition, offset, err } @@ -138,12 +146,19 @@ func (p *syncProducer) SendMessages(msgs []*sarama.ProducerMessage) error { // treated individually, so we create a span for each one spans := make([]*tracer.Span, len(msgs)) for i, msg := range msgs { + setProduceCheckpoint(p.cfg.dataStreamsEnabled, msg, p.version) spans[i] = startProducerSpan(p.cfg, p.version, msg) } err := p.SyncProducer.SendMessages(msgs) for i, span := range spans { finishProducerSpan(span, msgs[i].Partition, msgs[i].Offset, err) } + if err == nil && p.cfg.dataStreamsEnabled { + // we only track Kafka lag if messages have been sent successfully. Otherwise, we have no way to know to which partition data was sent to. + for _, msg := range msgs { + tracer.TrackKafkaProduceOffset(msg.Topic, msg.Partition, msg.Offset) + } + } return err } @@ -153,7 +168,7 @@ func WrapSyncProducer(saramaConfig *sarama.Config, producer sarama.SyncProducer, cfg := new(config) defaults(cfg) for _, opt := range opts { - opt.apply(cfg) + opt(cfg) } log.Debug("contrib/IBM/sarama: Wrapping Sync Producer: %#v", cfg) if saramaConfig == nil { @@ -197,7 +212,7 @@ func WrapAsyncProducer(saramaConfig *sarama.Config, p sarama.AsyncProducer, opts cfg := new(config) defaults(cfg) for _, opt := range opts { - opt.apply(cfg) + opt(cfg) } log.Debug("contrib/IBM/sarama: Wrapping Async Producer: %#v", cfg) if saramaConfig == nil { @@ -221,6 +236,7 @@ func WrapAsyncProducer(saramaConfig *sarama.Config, p sarama.AsyncProducer, opts select { case msg := <-wrapped.input: span := startProducerSpan(cfg, saramaConfig.Version, msg) + setProduceCheckpoint(cfg.dataStreamsEnabled, msg, saramaConfig.Version) p.Input() <- msg if saramaConfig.Producer.Return.Successes { spanID := span.Context().SpanID() @@ -236,6 +252,10 @@ func WrapAsyncProducer(saramaConfig *sarama.Config, p sarama.AsyncProducer, opts // producer was closed, so exit return } + if cfg.dataStreamsEnabled { + // we only track Kafka lag if returning successes is enabled. Otherwise, we have no way to know to which partition data was sent to. + tracer.TrackKafkaProduceOffset(msg.Topic, msg.Partition, msg.Offset) + } if spanctx, spanFound := getSpanContext(msg); spanFound { spanID := spanctx.SpanID() if span, ok := spans[spanID]; ok { @@ -303,3 +323,57 @@ func getSpanContext(msg *sarama.ProducerMessage) (ddtrace.SpanContext, bool) { return spanctx, true } + +func setProduceCheckpoint(enabled bool, msg *sarama.ProducerMessage, version sarama.KafkaVersion) { + if !enabled || msg == nil { + return + } + edges := []string{"direction:out", "topic:" + msg.Topic, "type:kafka"} + carrier := NewProducerMessageCarrier(msg) + ctx, ok := tracer.SetDataStreamsCheckpointWithParams(datastreams.ExtractFromBase64Carrier(context.Background(), carrier), options.CheckpointParams{PayloadSize: getProducerMsgSize(msg)}, edges...) + if !ok || !version.IsAtLeast(sarama.V0_11_0_0) { + return + } + datastreams.InjectToBase64Carrier(ctx, carrier) +} + +func setConsumeCheckpoint(enabled bool, groupID string, msg *sarama.ConsumerMessage) { + if !enabled || msg == nil { + return + } + edges := []string{"direction:in", "topic:" + msg.Topic, "type:kafka"} + if groupID != "" { + edges = append(edges, "group:"+groupID) + } + carrier := NewConsumerMessageCarrier(msg) + ctx, ok := tracer.SetDataStreamsCheckpointWithParams(datastreams.ExtractFromBase64Carrier(context.Background(), carrier), options.CheckpointParams{PayloadSize: getConsumerMsgSize(msg)}, edges...) + if !ok { + return + } + datastreams.InjectToBase64Carrier(ctx, carrier) + if groupID != "" { + // only track Kafka lag if a consumer group is set. + // since there is no ack mechanism, we consider that messages read are committed right away. + tracer.TrackKafkaCommitOffset(groupID, msg.Topic, msg.Partition, msg.Offset) + } +} + +func getProducerMsgSize(msg *sarama.ProducerMessage) (size int64) { + for _, header := range msg.Headers { + size += int64(len(header.Key) + len(header.Value)) + } + if msg.Value != nil { + size += int64(msg.Value.Length()) + } + if msg.Key != nil { + size += int64(msg.Key.Length()) + } + return size +} + +func getConsumerMsgSize(msg *sarama.ConsumerMessage) (size int64) { + for _, header := range msg.Headers { + size += int64(len(header.Key) + len(header.Value)) + } + return size + int64(len(msg.Value)+len(msg.Key)) +} diff --git a/v2/contrib/IBM/sarama/sarama_test.go b/v2/contrib/IBM/sarama/sarama_test.go index e33cc73a41..db263b5e8a 100644 --- a/v2/contrib/IBM/sarama/sarama_test.go +++ b/v2/contrib/IBM/sarama/sarama_test.go @@ -10,6 +10,7 @@ import ( "testing" "time" + "github.com/DataDog/dd-trace-go/v2/datastreams" "github.com/DataDog/dd-trace-go/v2/ddtrace/ext" "github.com/DataDog/dd-trace-go/v2/ddtrace/mocktracer" "github.com/DataDog/dd-trace-go/v2/ddtrace/tracer" @@ -23,7 +24,7 @@ import ( func genTestSpans(t *testing.T, serviceOverride string) []*mocktracer.Span { var opts []Option if serviceOverride != "" { - opts = append(opts, WithService(serviceOverride)) + opts = append(opts, WithServiceName(serviceOverride)) } mt := mocktracer.Start() defer mt.Stop() @@ -115,7 +116,7 @@ func TestConsumer(t *testing.T) { } defer consumer.Close() - consumer = WrapConsumer(consumer) + consumer = WrapConsumer(consumer, WithDataStreams()) partitionConsumer, err := consumer.ConsumePartition("test-topic", 0, 0) if err != nil { @@ -145,6 +146,12 @@ func TestConsumer(t *testing.T) { assert.Equal(t, "IBM/sarama", s.Tag(ext.Component)) assert.Equal(t, ext.SpanKindConsumer, s.Tag(ext.SpanKind)) assert.Equal(t, "kafka", s.Tag(ext.MessagingSystem)) + p, ok := datastreams.PathwayFromContext(datastreams.ExtractFromBase64Carrier(context.Background(), NewConsumerMessageCarrier(msg1))) + assert.True(t, ok) + expectedCtx, _ := tracer.SetDataStreamsCheckpoint(context.Background(), "direction:in", "topic:test-topic", "type:kafka") + expected, _ := datastreams.PathwayFromContext(expectedCtx) + assert.NotEqual(t, expected.GetHash(), 0) + assert.Equal(t, expected.GetHash(), p.GetHash()) } { s := spans[1] @@ -162,6 +169,12 @@ func TestConsumer(t *testing.T) { assert.Equal(t, "IBM/sarama", s.Tag(ext.Component)) assert.Equal(t, ext.SpanKindConsumer, s.Tag(ext.SpanKind)) assert.Equal(t, "kafka", s.Tag(ext.MessagingSystem)) + p, ok := datastreams.PathwayFromContext(datastreams.ExtractFromBase64Carrier(context.Background(), NewConsumerMessageCarrier(msg1))) + assert.True(t, ok) + expectedCtx, _ := tracer.SetDataStreamsCheckpoint(context.Background(), "direction:in", "topic:test-topic", "type:kafka") + expected, _ := datastreams.PathwayFromContext(expectedCtx) + assert.NotEqual(t, expected.GetHash(), 0) + assert.Equal(t, expected.GetHash(), p.GetHash()) } } @@ -176,23 +189,25 @@ func TestSyncProducer(t *testing.T) { defer leader.Close() metadataResponse := new(sarama.MetadataResponse) + metadataResponse.Version = 1 metadataResponse.AddBroker(leader.Addr(), leader.BrokerID()) metadataResponse.AddTopicPartition("my_topic", 0, leader.BrokerID(), nil, nil, nil, sarama.ErrNoError) seedBroker.Returns(metadataResponse) prodSuccess := new(sarama.ProduceResponse) + prodSuccess.Version = 2 prodSuccess.AddTopicPartition("my_topic", 0, sarama.ErrNoError) leader.Returns(prodSuccess) cfg := sarama.NewConfig() - cfg.Version = sarama.MinVersion + cfg.Version = sarama.V0_11_0_0 // first version that supports headers cfg.Producer.Return.Successes = true producer, err := sarama.NewSyncProducer([]string{seedBroker.Addr()}, cfg) if err != nil { t.Fatal(err) } - producer = WrapSyncProducer(cfg, producer) + producer = WrapSyncProducer(cfg, producer, WithDataStreams()) msg1 := &sarama.ProducerMessage{ Topic: "my_topic", @@ -214,6 +229,12 @@ func TestSyncProducer(t *testing.T) { assert.Equal(t, "IBM/sarama", s.Tag(ext.Component)) assert.Equal(t, ext.SpanKindProducer, s.Tag(ext.SpanKind)) assert.Equal(t, "kafka", s.Tag(ext.MessagingSystem)) + p, ok := datastreams.PathwayFromContext(datastreams.ExtractFromBase64Carrier(context.Background(), NewProducerMessageCarrier(msg1))) + assert.True(t, ok) + expectedCtx, _ := tracer.SetDataStreamsCheckpoint(context.Background(), "direction:out", "topic:my_topic", "type:kafka") + expected, _ := datastreams.PathwayFromContext(expectedCtx) + assert.NotEqual(t, expected.GetHash(), 0) + assert.Equal(t, expected.GetHash(), p.GetHash()) } } @@ -283,7 +304,7 @@ func TestAsyncProducer(t *testing.T) { broker := newMockBroker(t) cfg := sarama.NewConfig() - cfg.Version = sarama.V0_11_0_0 + cfg.Version = sarama.MaxVersion producer, err := sarama.NewAsyncProducer([]string{broker.Addr()}, cfg) if err != nil { t.Fatal(err) diff --git a/v2/contrib/database/sql/conn.go b/v2/contrib/database/sql/conn.go index 54548d7a9a..f3c0f70559 100644 --- a/v2/contrib/database/sql/conn.go +++ b/v2/contrib/database/sql/conn.go @@ -252,7 +252,7 @@ func (tc *TracedConn) injectComments(ctx context.Context, query string, mode tra if span, ok := tracer.SpanFromContext(ctx); ok { spanCtx = span.Context() } - carrier := tracer.SQLCommentCarrier{Query: query, Mode: mode, DBServiceName: tc.cfg.serviceName} + carrier := tracer.SQLCommentCarrier{Query: query, Mode: mode, DBServiceName: tc.cfg.serviceName, PeerDBHostname: tc.meta[ext.TargetHost], PeerDBName: tc.meta[ext.DBName]} if err := carrier.Inject(spanCtx); err != nil { // this should never happen log.Warn("contrib/database/sql: failed to inject query comments: %v", err) diff --git a/v2/contrib/database/sql/internal/dsn.go b/v2/contrib/database/sql/internal/dsn.go index 30022098c4..a80939c9f3 100644 --- a/v2/contrib/database/sql/internal/dsn.go +++ b/v2/contrib/database/sql/internal/dsn.go @@ -3,13 +3,15 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016 Datadog, Inc. -package internal // import "github.com/DataDog/dd-trace-go/v2/contrib/database/sql/internal" +package internal // import "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql/internal" import ( "net" + "net/url" "strings" "github.com/DataDog/dd-trace-go/v2/ddtrace/ext" + "github.com/DataDog/dd-trace-go/v2/internal/log" ) // ParseDSN parses various supported DSN types into a map of key/value pairs which can be used as valid tags. @@ -19,20 +21,36 @@ func ParseDSN(driverName, dsn string) (meta map[string]string, err error) { case "mysql": meta, err = parseMySQLDSN(dsn) if err != nil { + log.Debug("Error parsing DSN for mysql: %v", err) return } case "postgres", "pgx": meta, err = parsePostgresDSN(dsn) if err != nil { + log.Debug("Error parsing DSN for postgres: %v", err) return } case "sqlserver": meta, err = parseSQLServerDSN(dsn) if err != nil { + log.Debug("Error parsing DSN for sqlserver: %v", err) return } default: - // not supported + // Try to parse the DSN and see if the scheme contains a known driver name. + u, e := url.Parse(dsn) + if e != nil { + // dsn is not a valid URL, so just ignore + log.Debug("Error parsing driver name from DSN: %v", e) + return + } + if driverName != u.Scheme { + // In some cases the driver is registered under a non-official name. + // For example, "Test" may be the registered name with a DSN of "postgres://postgres:postgres@127.0.0.1:5432/fakepreparedb" + // for the purposes of testing/mocking. + // In these cases, we try to parse the DSN based upon the DSN itself, instead of the registered driver name + return ParseDSN(u.Scheme, dsn) + } } return reduceKeys(meta), nil } diff --git a/v2/contrib/database/sql/propagation_test.go b/v2/contrib/database/sql/propagation_test.go index 8ba3b92afa..d7dec33211 100644 --- a/v2/contrib/database/sql/propagation_test.go +++ b/v2/contrib/database/sql/propagation_test.go @@ -37,6 +37,7 @@ func TestDBMPropagation(t *testing.T) { opts []Option callDB func(ctx context.Context, db *sql.DB) error prepared []string + dsn string executed []*regexp.Regexp }{ { @@ -73,7 +74,8 @@ func TestDBMPropagation(t *testing.T) { _, err := db.PrepareContext(ctx, "SELECT 1 from DUAL") return err }, - prepared: []string{"/*dddbs='test.db',dde='test-env',ddps='test-service',ddpv='1.0.0'*/ SELECT 1 from DUAL"}, + dsn: "postgres://postgres:postgres@127.0.0.1:5432/fakepreparedb?sslmode=disable", + prepared: []string{"/*dddbs='test.db',dde='test-env',ddps='test-service',ddpv='1.0.0',ddh='127.0.0.1',dddb='fakepreparedb'*/ SELECT 1 from DUAL"}, }, { name: "query", @@ -109,7 +111,8 @@ func TestDBMPropagation(t *testing.T) { _, err := db.QueryContext(ctx, "SELECT 1 from DUAL") return err }, - executed: []*regexp.Regexp{regexp.MustCompile("/\\*dddbs='test.db',dde='test-env',ddps='test-service',ddpv='1.0.0',traceparent='00-00000000000000000000000000000001-[\\da-f]{16}-01'\\*/ SELECT 1 from DUAL")}, + dsn: "postgres://postgres:postgres@127.0.0.1:5432/fakequerydb?sslmode=disable", + executed: []*regexp.Regexp{regexp.MustCompile("/\\*dddbs='test.db',dde='test-env',ddps='test-service',ddpv='1.0.0',traceparent='00-00000000000000000000000000000001-[\\da-f]{16}-01',ddh='127.0.0.1',dddb='fakequerydb'\\*/ SELECT 1 from DUAL")}, }, { name: "exec", @@ -145,7 +148,8 @@ func TestDBMPropagation(t *testing.T) { _, err := db.ExecContext(ctx, "SELECT 1 from DUAL") return err }, - executed: []*regexp.Regexp{regexp.MustCompile("/\\*dddbs='test.db',dde='test-env',ddps='test-service',ddpv='1.0.0',traceparent='00-00000000000000000000000000000001-[\\da-f]{16}-01'\\*/ SELECT 1 from DUAL")}, + dsn: "postgres://postgres:postgres@127.0.0.1:5432/fakeexecdb?sslmode=disable", + executed: []*regexp.Regexp{regexp.MustCompile("/\\*dddbs='test.db',dde='test-env',ddps='test-service',ddpv='1.0.0',traceparent='00-00000000000000000000000000000001-[\\da-f]{16}-01',ddh='127.0.0.1',dddb='fakeexecdb'\\*/ SELECT 1 from DUAL")}, }, } @@ -163,9 +167,12 @@ func TestDBMPropagation(t *testing.T) { Register("test", d, tc.opts...) defer unregister("test") - db, err := Open("test", "dn") + dsn := "dn" + if tc.dsn != "" { + dsn = tc.dsn + } + db, err := Open("test", dsn) require.NoError(t, err) - s, ctx := tracer.StartSpanFromContext(context.Background(), "test.call", tracer.WithSpanID(1)) err = tc.callDB(ctx, db) s.Finish()