From 95dcf65b9bc8d42052124d96eefbf95db1e2ad15 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 27 Dec 2024 17:09:27 -0600 Subject: [PATCH 01/34] feat: adding instrumentation support for mongo-driver/v2 --- instrumentation/README.md | 1 + .../mongo-driver/v2/mongo/otelmongo/config.go | 68 +++++ .../mongo-driver/v2/mongo/otelmongo/doc.go | 15 + .../v2/mongo/otelmongo/example_test.go | 41 +++ .../mongo-driver/v2/mongo/otelmongo/go.mod | 29 ++ .../mongo-driver/v2/mongo/otelmongo/go.sum | 76 +++++ .../mongo-driver/v2/mongo/otelmongo/mongo.go | 150 ++++++++++ .../v2/mongo/otelmongo/test/doc.go | 11 + .../v2/mongo/otelmongo/test/go.mod | 38 +++ .../v2/mongo/otelmongo/test/go.sum | 82 ++++++ .../v2/mongo/otelmongo/test/mongo_test.go | 260 ++++++++++++++++++ .../v2/mongo/otelmongo/test/version.go | 17 ++ .../v2/mongo/otelmongo/test/version_test.go | 24 ++ .../v2/mongo/otelmongo/version.go | 17 ++ .../v2/mongo/otelmongo/version_test.go | 24 ++ versions.yaml | 2 + 16 files changed, 855 insertions(+) create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/config.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go create mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go diff --git a/instrumentation/README.md b/instrumentation/README.md index 77fe61c45c1..306f6b2750e 100644 --- a/instrumentation/README.md +++ b/instrumentation/README.md @@ -48,6 +48,7 @@ The following instrumentation packages are provided for popular Go packages and | [github.com/gorilla/mux](./github.com/gorilla/mux/otelmux) | | ✓ | | [github.com/labstack/echo](./github.com/labstack/echo/otelecho) | | ✓ | | [go.mongodb.org/mongo-driver](./go.mongodb.org/mongo-driver/mongo/otelmongo) | | ✓ | +| [go.mongodb.org/mongo-driver/v2](./go.mongodb.org/mongo-driver/v2/mongo/otelmongo) | | ✓ | | [google.golang.org/grpc](./google.golang.org/grpc/otelgrpc) | ✓ | ✓ | | [host](./host) | ✓ | | | [net/http](./net/http/otelhttp) | ✓ | ✓ | diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/config.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/config.go new file mode 100644 index 00000000000..07e36c87660 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/config.go @@ -0,0 +1,68 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" + +import ( + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" +) + +// ScopeName is the instrumentation scope name. +const ScopeName = "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" + +// config is used to configure the mongo tracer. +type config struct { + TracerProvider trace.TracerProvider + + Tracer trace.Tracer + + CommandAttributeDisabled bool +} + +// newConfig returns a config with all Options set. +func newConfig(opts ...Option) config { + cfg := config{ + TracerProvider: otel.GetTracerProvider(), + CommandAttributeDisabled: true, + } + for _, opt := range opts { + opt.apply(&cfg) + } + + cfg.Tracer = cfg.TracerProvider.Tracer( + ScopeName, + trace.WithInstrumentationVersion(Version()), + ) + return cfg +} + +// Option specifies instrumentation configuration options. +type Option interface { + apply(*config) +} + +type optionFunc func(*config) + +func (o optionFunc) apply(c *config) { + o(c) +} + +// WithTracerProvider specifies a tracer provider to use for creating a tracer. +// If none is specified, the global provider is used. +func WithTracerProvider(provider trace.TracerProvider) Option { + return optionFunc(func(cfg *config) { + if provider != nil { + cfg.TracerProvider = provider + } + }) +} + +// WithCommandAttributeDisabled specifies if the MongoDB command is added as an attribute to Spans or not. +// This is disabled by default and the MongoDB command will not be added as an attribute +// to Spans if this option is not provided. +func WithCommandAttributeDisabled(disabled bool) Option { + return optionFunc(func(cfg *config) { + cfg.CommandAttributeDisabled = disabled + }) +} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go new file mode 100644 index 00000000000..e7a95f89267 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go @@ -0,0 +1,15 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +// Package otelmongo instruments go.mongodb.org/mongo-driver/mongo. +// +// This package is compatible with v0.2.0 of +// go.mongodb.org/mongo-driver/mongo. +// +// `NewMonitor` will return an event.CommandMonitor which is used to trace +// requests. +// +// This code was originally based on the following: +// - https://github.com/DataDog/dd-trace-go/tree/02f0449efa3cb382d499fadc873957385dcb2192/contrib/go.mongodb.org/mongo-driver/mongo +// - https://github.com/DataDog/dd-trace-go/tree/v1.23.3/ddtrace/ext +package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go new file mode 100644 index 00000000000..c6c03826287 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go @@ -0,0 +1,41 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelmongo_test + +import ( + "context" + + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" + + "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" +) + +func Example() { + // connect to MongoDB + opts := options.Client() + opts.Monitor = otelmongo.NewMonitor() + opts.ApplyURI("mongodb://localhost:27017") + client, err := mongo.Connect(opts) + if err != nil { + panic(err) + } + db := client.Database("example") + inventory := db.Collection("inventory") + + _, err = inventory.InsertOne(context.Background(), bson.D{ + {Key: "item", Value: "canvas"}, + {Key: "qty", Value: 100}, + {Key: "attributes", Value: bson.A{"cotton"}}, + {Key: "size", Value: bson.D{ + {Key: "h", Value: 28}, + {Key: "w", Value: 35.5}, + {Key: "uom", Value: "cm"}, + }}, + }) + if err != nil { + panic(err) + } +} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod new file mode 100644 index 00000000000..c5469b9d0b9 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod @@ -0,0 +1,29 @@ +module go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo + +go 1.22.0 + +require ( + github.com/stretchr/testify v1.10.0 + go.mongodb.org/mongo-driver/v2 v2.0.0 + go.opentelemetry.io/otel v1.33.0 + go.opentelemetry.io/otel/trace v1.33.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.33.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/text v0.21.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum new file mode 100644 index 00000000000..d0d169d2446 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum @@ -0,0 +1,76 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver/v2 v2.0.0 h1:Jfd7XpdZa9yk3eY774bO7SWVb30noLSirL9nKTpavhI= +go.mongodb.org/mongo-driver/v2 v2.0.0/go.mod h1:nSjmNq4JUstE8IRZKTktLgMHM4F1fccL6HGX1yh+8RA= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +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/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go new file mode 100644 index 00000000000..3a04fa3921e --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -0,0 +1,150 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" + +import ( + "context" + "errors" + "fmt" + "strconv" + "strings" + "sync" + + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + semconv "go.opentelemetry.io/otel/semconv/v1.21.0" + "go.opentelemetry.io/otel/trace" + + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/event" +) + +type spanKey struct { + ConnectionID string + RequestID int64 +} + +type monitor struct { + sync.Mutex + spans map[spanKey]trace.Span + cfg config +} + +func (m *monitor) Started(ctx context.Context, evt *event.CommandStartedEvent) { + var spanName string + + hostname, port := peerInfo(evt) + + attrs := []attribute.KeyValue{ + semconv.DBSystemMongoDB, + semconv.DBOperation(evt.CommandName), + semconv.DBName(evt.DatabaseName), + semconv.NetPeerName(hostname), + semconv.NetPeerPort(port), + semconv.NetTransportTCP, + } + if !m.cfg.CommandAttributeDisabled { + attrs = append(attrs, semconv.DBStatement(sanitizeCommand(evt.Command))) + } + if collection, err := extractCollection(evt); err == nil && collection != "" { + spanName = collection + "." + attrs = append(attrs, semconv.DBMongoDBCollection(collection)) + } + spanName += evt.CommandName + opts := []trace.SpanStartOption{ + trace.WithSpanKind(trace.SpanKindClient), + trace.WithAttributes(attrs...), + } + _, span := m.cfg.Tracer.Start(ctx, spanName, opts...) + key := spanKey{ + ConnectionID: evt.ConnectionID, + RequestID: evt.RequestID, + } + m.Lock() + m.spans[key] = span + m.Unlock() +} + +func (m *monitor) Succeeded(ctx context.Context, evt *event.CommandSucceededEvent) { + m.Finished(&evt.CommandFinishedEvent, nil) +} + +func (m *monitor) Failed(ctx context.Context, evt *event.CommandFailedEvent) { + m.Finished(&evt.CommandFinishedEvent, fmt.Errorf("%s", evt.Failure)) +} + +func (m *monitor) Finished(evt *event.CommandFinishedEvent, err error) { + key := spanKey{ + ConnectionID: evt.ConnectionID, + RequestID: evt.RequestID, + } + m.Lock() + span, ok := m.spans[key] + if ok { + delete(m.spans, key) + } + m.Unlock() + if !ok { + return + } + + if err != nil { + span.SetStatus(codes.Error, err.Error()) + } + + span.End() +} + +// TODO sanitize values where possible, then re-enable `db.statement` span attributes default. +// TODO limit maximum size. +func sanitizeCommand(command bson.Raw) string { + b, _ := bson.MarshalExtJSON(command, false, false) + return string(b) +} + +// extractCollection extracts the collection for the given mongodb command event. +// For CRUD operations, this is the first key/value string pair in the bson +// document where key == "" (e.g. key == "insert"). +// For database meta-level operations, such a key may not exist. +func extractCollection(evt *event.CommandStartedEvent) (string, error) { + elt, err := evt.Command.IndexErr(0) + if err != nil { + return "", err + } + if key, err := elt.KeyErr(); err == nil && key == evt.CommandName { + var v bson.RawValue + if v, err = elt.ValueErr(); err != nil || v.Type != bson.TypeString { + return "", err + } + return v.StringValue(), nil + } + return "", errors.New("collection name not found") +} + +// NewMonitor creates a new mongodb event CommandMonitor. +func NewMonitor(opts ...Option) *event.CommandMonitor { + cfg := newConfig(opts...) + m := &monitor{ + spans: make(map[spanKey]trace.Span), + cfg: cfg, + } + return &event.CommandMonitor{ + Started: m.Started, + Succeeded: m.Succeeded, + Failed: m.Failed, + } +} + +func peerInfo(evt *event.CommandStartedEvent) (hostname string, port int) { + hostname = evt.ConnectionID + port = 27017 + if idx := strings.IndexByte(hostname, '['); idx >= 0 { + hostname = hostname[:idx] + } + if idx := strings.IndexByte(hostname, ':'); idx >= 0 { + port = func(p int, e error) int { return p }(strconv.Atoi(hostname[idx+1:])) + hostname = hostname[:idx] + } + return hostname, port +} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go new file mode 100644 index 00000000000..91f42a97c48 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go @@ -0,0 +1,11 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +/* +Package test validates the otelmongo instrumentation with the default SDK. + +This package is in a separate module from the instrumentation it tests to +isolate the dependency of the default SDK and not impose this as a transitive +dependency for users. +*/ +package test // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test" diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod new file mode 100644 index 00000000000..1af1073901a --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod @@ -0,0 +1,38 @@ +module go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test + +go 1.22.0 + +require ( + github.com/stretchr/testify v1.10.0 + go.mongodb.org/mongo-driver/v2 v2.0.0 + go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo v0.0.0-00010101000000-000000000000 + go.opentelemetry.io/otel v1.33.0 + go.opentelemetry.io/otel/sdk v1.33.0 + go.opentelemetry.io/otel/trace v1.33.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + go.opentelemetry.io/auto/sdk v1.1.0 // indirect + go.opentelemetry.io/otel/metric v1.33.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +replace ( + go.opentelemetry.io/contrib => ../../../../../.. + go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo => ../ +) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum new file mode 100644 index 00000000000..071688c8174 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum @@ -0,0 +1,82 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver/v2 v2.0.0 h1:Jfd7XpdZa9yk3eY774bO7SWVb30noLSirL9nKTpavhI= +go.mongodb.org/mongo-driver/v2 v2.0.0/go.mod h1:nSjmNq4JUstE8IRZKTktLgMHM4F1fccL6HGX1yh+8RA= +go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= +go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= +go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= +go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= +go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +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/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go new file mode 100644 index 00000000000..b5b53c32377 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -0,0 +1,260 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package test + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" + "go.mongodb.org/mongo-driver/v2/mongo/options" + + "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" + "go.opentelemetry.io/otel/trace" +) + +type validator func(sdktrace.ReadOnlySpan) bool + +func TestDBCrudOperation(t *testing.T) { + commonValidators := []validator{ + func(s sdktrace.ReadOnlySpan) bool { + return assert.Equal(t, "test-collection.insert", s.Name(), "expected %s", s.Name()) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Contains(t, s.Attributes(), attribute.String("db.operation", "insert")) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Contains(t, s.Attributes(), attribute.String("db.mongodb.collection", "test-collection")) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Equal(t, codes.Unset, s.Status().Code) + }, + } + + tt := []struct { + title string + operation func(context.Context, *mongo.Database) (interface{}, error) + mockResponses []bson.D + excludeCommand bool + validators []validator + }{ + { + title: "insert", + operation: func(ctx context.Context, db *mongo.Database) (interface{}, error) { + return db.Collection("test-collection").InsertOne(ctx, bson.D{{Key: "test-item", Value: "test-value"}}) + }, + mockResponses: []bson.D{{{Key: "ok", Value: 1}}}, + excludeCommand: false, + validators: append(commonValidators, func(s sdktrace.ReadOnlySpan) bool { + for _, attr := range s.Attributes() { + if attr.Key == "db.statement" { + return assert.Contains(t, attr.Value.AsString(), `"test-item":"test-value"`) + } + } + return false + }), + }, + { + title: "insert", + operation: func(ctx context.Context, db *mongo.Database) (interface{}, error) { + return db.Collection("test-collection").InsertOne(ctx, bson.D{{Key: "test-item", Value: "test-value"}}) + }, + mockResponses: []bson.D{{{Key: "ok", Value: 1}}}, + excludeCommand: true, + validators: append(commonValidators, func(s sdktrace.ReadOnlySpan) bool { + for _, attr := range s.Attributes() { + if attr.Key == "db.statement" { + return false + } + } + return true + }), + }, + } + for _, tc := range tt { + tc := tc + + title := tc.title + if tc.excludeCommand { + title = title + "/excludeCommand" + } else { + title = title + "/includeCommand" + } + + t.Run(title, func(t *testing.T) { + md := drivertest.NewMockDeployment() + + sr := tracetest.NewSpanRecorder() + provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr)) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + ctx, span := provider.Tracer("test").Start(ctx, "mongodb-test") + + addr := "mongodb://localhost:27017/?connect=direct" + opts := options.Client() + opts.Deployment = md + opts.Monitor = otelmongo.NewMonitor( + otelmongo.WithTracerProvider(provider), + otelmongo.WithCommandAttributeDisabled(tc.excludeCommand), + ) + opts.ApplyURI(addr) + + md.AddResponses(tc.mockResponses...) + client, err := mongo.Connect(opts) + if err != nil { + t.FailNow() + } + + _, err = tc.operation(ctx, client.Database("test-database")) + if err != nil { + t.Error(err) + } + + span.End() + + spans := sr.Ended() + if !assert.Len(t, spans, 2, "expected 2 spans, received %d", len(spans)) { + t.FailNow() + } + assert.Len(t, spans, 2) + assert.Equal(t, spans[0].SpanContext().TraceID(), spans[1].SpanContext().TraceID()) + assert.Equal(t, spans[0].Parent().SpanID(), spans[1].SpanContext().SpanID()) + assert.Equal(t, span.SpanContext().SpanID(), spans[1].SpanContext().SpanID()) + + s := spans[0] + assert.Equal(t, trace.SpanKindClient, s.SpanKind()) + attrs := s.Attributes() + assert.Contains(t, attrs, attribute.String("db.system", "mongodb")) + assert.Contains(t, attrs, attribute.String("net.peer.name", "")) + assert.Contains(t, attrs, attribute.Int64("net.peer.port", int64(27017))) + assert.Contains(t, attrs, attribute.String("net.transport", "ip_tcp")) + assert.Contains(t, attrs, attribute.String("db.name", "test-database")) + for _, v := range tc.validators { + assert.True(t, v(s)) + } + }) + } +} + +func TestDBCollectionAttribute(t *testing.T) { + tt := []struct { + title string + operation func(context.Context, *mongo.Database) (interface{}, error) + mockResponses []bson.D + validators []validator + }{ + { + title: "delete", + operation: func(ctx context.Context, db *mongo.Database) (interface{}, error) { + return db.Collection("test-collection").DeleteOne(ctx, bson.D{{Key: "test-item"}}) + }, + mockResponses: []bson.D{{{Key: "ok", Value: 1}}}, + validators: []validator{ + func(s sdktrace.ReadOnlySpan) bool { + return assert.Equal(t, "test-collection.delete", s.Name()) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Contains(t, s.Attributes(), attribute.String("db.operation", "delete")) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Contains(t, s.Attributes(), attribute.String("db.mongodb.collection", "test-collection")) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Equal(t, codes.Unset, s.Status().Code) + }, + }, + }, + { + title: "listCollectionNames", + operation: func(ctx context.Context, db *mongo.Database) (interface{}, error) { + return db.ListCollectionNames(ctx, bson.D{}) + }, + mockResponses: []bson.D{ + { + {Key: "ok", Value: 1}, + {Key: "cursor", Value: bson.D{{Key: "firstBatch", Value: bson.A{}}}}, + }, + }, + validators: []validator{ + func(s sdktrace.ReadOnlySpan) bool { + return assert.Equal(t, "listCollections", s.Name()) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Contains(t, s.Attributes(), attribute.String("db.operation", "listCollections")) + }, + func(s sdktrace.ReadOnlySpan) bool { + return assert.Equal(t, codes.Unset, s.Status().Code) + }, + }, + }, + } + for _, tc := range tt { + tc := tc + + t.Run(tc.title, func(t *testing.T) { + md := drivertest.NewMockDeployment() + + sr := tracetest.NewSpanRecorder() + provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr)) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) + defer cancel() + + ctx, span := provider.Tracer("test").Start(ctx, "mongodb-test") + + addr := "mongodb://localhost:27017/?connect=direct" + opts := options.Client() + opts.Deployment = md + opts.Monitor = otelmongo.NewMonitor( + otelmongo.WithTracerProvider(provider), + otelmongo.WithCommandAttributeDisabled(true), + ) + opts.ApplyURI(addr) + + md.AddResponses(tc.mockResponses...) + client, err := mongo.Connect(opts) + if err != nil { + t.FailNow() + } + + _, err = tc.operation(ctx, client.Database("test-database")) + if err != nil { + t.Error(err) + } + + span.End() + + spans := sr.Ended() + if !assert.Len(t, spans, 2, "expected 2 spans, received %d", len(spans)) { + t.FailNow() + } + assert.Len(t, spans, 2) + assert.Equal(t, spans[0].SpanContext().TraceID(), spans[1].SpanContext().TraceID()) + assert.Equal(t, spans[0].Parent().SpanID(), spans[1].SpanContext().SpanID()) + assert.Equal(t, span.SpanContext().SpanID(), spans[1].SpanContext().SpanID()) + + s := spans[0] + assert.Equal(t, trace.SpanKindClient, s.SpanKind()) + attrs := s.Attributes() + assert.Contains(t, attrs, attribute.String("db.system", "mongodb")) + assert.Contains(t, attrs, attribute.String("net.peer.name", "")) + assert.Contains(t, attrs, attribute.Int64("net.peer.port", int64(27017))) + assert.Contains(t, attrs, attribute.String("net.transport", "ip_tcp")) + assert.Contains(t, attrs, attribute.String("db.name", "test-database")) + for _, v := range tc.validators { + assert.True(t, v(s)) + } + }) + } +} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go new file mode 100644 index 00000000000..e6c1d5c800e --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package test // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test" + +// Version is the current release version of the mongo-driver instrumentation test module. +func Version() string { + return "0.58.0" + // This string is updated by the pre_release.sh script during release +} + +// SemVersion is the semantic version to be supplied to tracer/meter creation. +// +// Deprecated: Use [Version] instead. +func SemVersion() string { + return Version() +} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go new file mode 100644 index 00000000000..851ec95a599 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package test_test + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test" +) + +// regex taken from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string +var versionRegex = regexp.MustCompile(`^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)` + + `(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)` + + `(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` + + `(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`) + +func TestVersionSemver(t *testing.T) { + v := test.Version() + assert.NotNil(t, versionRegex.FindStringSubmatch(v), "version is not semver: %s", v) +} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go new file mode 100644 index 00000000000..93caa863b79 --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go @@ -0,0 +1,17 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" + +// Version is the current release version of the mongo-driver instrumentation. +func Version() string { + return "0.58.0" + // This string is updated by the pre_release.sh script during release +} + +// SemVersion is the semantic version to be supplied to tracer/meter creation. +// +// Deprecated: Use [Version] instead. +func SemVersion() string { + return Version() +} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go new file mode 100644 index 00000000000..491537d1f0d --- /dev/null +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go @@ -0,0 +1,24 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +package otelmongo_test + +import ( + "regexp" + "testing" + + "github.com/stretchr/testify/assert" + + "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" +) + +// regex taken from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string +var versionRegex = regexp.MustCompile(`^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)` + + `(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)` + + `(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` + + `(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`) + +func TestVersionSemver(t *testing.T) { + v := otelmongo.Version() + assert.NotNil(t, versionRegex.FindStringSubmatch(v), "version is not semver: %s", v) +} diff --git a/versions.yaml b/versions.yaml index 771487a0d6b..5d794a5029c 100644 --- a/versions.yaml +++ b/versions.yaml @@ -36,6 +36,8 @@ module-sets: - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/test - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo/test + - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo + - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test - go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux - go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux/example - go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux/test From 24b5f1e7441b652ee4ed4aa0aa2b6fb8dd41106d Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Mon, 13 Jan 2025 11:28:36 -0600 Subject: [PATCH 02/34] Update LInting --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go index 3a04fa3921e..68942aee4bb 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -71,7 +71,7 @@ func (m *monitor) Succeeded(ctx context.Context, evt *event.CommandSucceededEven } func (m *monitor) Failed(ctx context.Context, evt *event.CommandFailedEvent) { - m.Finished(&evt.CommandFinishedEvent, fmt.Errorf("%s", evt.Failure)) + m.Finished(&evt.CommandFinishedEvent, fmt.Errorf("%w", evt.Failure)) } func (m *monitor) Finished(evt *event.CommandFinishedEvent, err error) { From b3cbb84a05dd3bc182aea08943af40069ccebdba Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:24:54 -0600 Subject: [PATCH 03/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go Co-authored-by: Preston Vasquez --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go index e7a95f89267..e6b848d6b7f 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -// Package otelmongo instruments go.mongodb.org/mongo-driver/mongo. +// Package otelmongo instruments go.mongodb.org/mongo-driver/v2/mongo. // // This package is compatible with v0.2.0 of // go.mongodb.org/mongo-driver/mongo. From a0f083bb7223080c11cadf1ef74fc3547abb3f58 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:25:20 -0600 Subject: [PATCH 04/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go Co-authored-by: Preston Vasquez --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go index e6b848d6b7f..c2017b49c5e 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go @@ -3,8 +3,6 @@ // Package otelmongo instruments go.mongodb.org/mongo-driver/v2/mongo. // -// This package is compatible with v0.2.0 of -// go.mongodb.org/mongo-driver/mongo. // // `NewMonitor` will return an event.CommandMonitor which is used to trace // requests. From f83a9ab035d955dfedab46a90083c997c0219e9e Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:26:29 -0600 Subject: [PATCH 05/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go Co-authored-by: Preston Vasquez --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go index 91f42a97c48..839d36f57d5 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 /* -Package test validates the otelmongo instrumentation with the default SDK. +Package test validates the otelmongo V2 instrumentation with the default SDK. This package is in a separate module from the instrumentation it tests to isolate the dependency of the default SDK and not impose this as a transitive From 8e90ad0638bc0f7cc001afaf32e12bc4d92dc4f5 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:26:39 -0600 Subject: [PATCH 06/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go Co-authored-by: Damien Mathieu <42@dmathieu.com> --- .../mongo-driver/v2/mongo/otelmongo/test/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go index e6c1d5c800e..e3551c39c0a 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go @@ -5,7 +5,7 @@ package test // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.o // Version is the current release version of the mongo-driver instrumentation test module. func Version() string { - return "0.58.0" + return "0.60.0" // This string is updated by the pre_release.sh script during release } From 959088719b422e2ceae270898edc34cc8b8321ce Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:26:47 -0600 Subject: [PATCH 07/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go Co-authored-by: Preston Vasquez --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go index 93caa863b79..c540c604ead 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go @@ -3,7 +3,7 @@ package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" -// Version is the current release version of the mongo-driver instrumentation. +// Version is the current release version of the mongo-go-driver V2 instrumentation. func Version() string { return "0.58.0" // This string is updated by the pre_release.sh script during release From 6d22da1c63b2f9f21ee4dd1d35b84bb03728e978 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:32:20 -0600 Subject: [PATCH 08/34] chore: Updating version --- .../mongo-driver/v2/mongo/otelmongo/version.go | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go index c540c604ead..3378a98a54e 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version.go @@ -5,13 +5,6 @@ package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mong // Version is the current release version of the mongo-go-driver V2 instrumentation. func Version() string { - return "0.58.0" + return "0.60.0" // This string is updated by the pre_release.sh script during release } - -// SemVersion is the semantic version to be supplied to tracer/meter creation. -// -// Deprecated: Use [Version] instead. -func SemVersion() string { - return Version() -} From 37c8729edc0e074f0e812e10c5f91b7c42a90874 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:39:26 -0600 Subject: [PATCH 09/34] chore: removing version unit test --- .../v2/mongo/otelmongo/version_test.go | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go deleted file mode 100644 index 491537d1f0d..00000000000 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/version_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package otelmongo_test - -import ( - "regexp" - "testing" - - "github.com/stretchr/testify/assert" - - "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" -) - -// regex taken from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string -var versionRegex = regexp.MustCompile(`^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)` + - `(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)` + - `(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` + - `(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`) - -func TestVersionSemver(t *testing.T) { - v := otelmongo.Version() - assert.NotNil(t, versionRegex.FindStringSubmatch(v), "version is not semver: %s", v) -} From 4e44c3ee3102e019a6522e973cea438e30c7975f Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 14 Feb 2025 20:43:16 -0600 Subject: [PATCH 10/34] Update code reference source --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go index c2017b49c5e..729136bc029 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go @@ -8,6 +8,5 @@ // requests. // // This code was originally based on the following: -// - https://github.com/DataDog/dd-trace-go/tree/02f0449efa3cb382d499fadc873957385dcb2192/contrib/go.mongodb.org/mongo-driver/mongo -// - https://github.com/DataDog/dd-trace-go/tree/v1.23.3/ddtrace/ext +// - https://github.com/open-telemetry/opentelemetry-go-contrib/tree/323e373a6c15ae310bdd0617e3ed52d8cb8e4e6f/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" From d38d11537cb52aa3730098a9669d3beb3fb8a9bc Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Mon, 17 Feb 2025 11:30:55 -0600 Subject: [PATCH 11/34] lint: fix extra empty comment line --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go index 729136bc029..0b4f3643ba0 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/doc.go @@ -3,7 +3,6 @@ // Package otelmongo instruments go.mongodb.org/mongo-driver/v2/mongo. // -// // `NewMonitor` will return an event.CommandMonitor which is used to trace // requests. // From e97fcde02e4023aa69f2125f8dd3c2fb1e3bd3b0 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Wed, 19 Feb 2025 21:19:01 -0600 Subject: [PATCH 12/34] fix: fixed lint issue --- .../mongo-driver/v2/mongo/otelmongo/go.mod | 4 ---- .../mongo-driver/v2/mongo/otelmongo/go.sum | 9 --------- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 10 ++++++---- 3 files changed, 6 insertions(+), 17 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod index c5469b9d0b9..6d7d922c823 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod @@ -3,19 +3,16 @@ module go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v go 1.22.0 require ( - github.com/stretchr/testify v1.10.0 go.mongodb.org/mongo-driver/v2 v2.0.0 go.opentelemetry.io/otel v1.33.0 go.opentelemetry.io/otel/trace v1.33.0 ) require ( - github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/klauspost/compress v1.17.11 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect @@ -25,5 +22,4 @@ require ( golang.org/x/crypto v0.31.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/text v0.21.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum index d0d169d2446..32daa773bc9 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum @@ -11,14 +11,8 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= @@ -69,8 +63,5 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index b5b53c32377..2f4e9fa40b5 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/assert" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" - "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" "go.mongodb.org/mongo-driver/v2/mongo/options" + "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" "go.opentelemetry.io/otel/attribute" @@ -103,7 +103,8 @@ func TestDBCrudOperation(t *testing.T) { addr := "mongodb://localhost:27017/?connect=direct" opts := options.Client() - opts.Deployment = md + //nolint:staticcheck + opts.Deployment = md // This method is the current documented way to set the mongodb mock. See https://github.com/mongodb/mongo-go-driver/blob/v2.0.0/x/mongo/driver/drivertest/opmsg_deployment_test.go#L24 opts.Monitor = otelmongo.NewMonitor( otelmongo.WithTracerProvider(provider), otelmongo.WithCommandAttributeDisabled(tc.excludeCommand), @@ -115,7 +116,7 @@ func TestDBCrudOperation(t *testing.T) { if err != nil { t.FailNow() } - + _, err = tc.operation(ctx, client.Database("test-database")) if err != nil { t.Error(err) @@ -215,7 +216,8 @@ func TestDBCollectionAttribute(t *testing.T) { addr := "mongodb://localhost:27017/?connect=direct" opts := options.Client() - opts.Deployment = md + //nolint:staticcheck + opts.Deployment = md // This method is the current documented way to set the mongodb mock. See https://github.com/mongodb/mongo-go-driver/blob/v2.0.0/x/mongo/driver/drivertest/opmsg_deployment_test.go#L24 opts.Monitor = otelmongo.NewMonitor( otelmongo.WithTracerProvider(provider), otelmongo.WithCommandAttributeDisabled(true), From bd3c9c52b9ed0c55012b5874ecdd0fb9aa14a7af Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Thu, 20 Feb 2025 08:19:40 -0600 Subject: [PATCH 13/34] feat: adding changelog entry for #6539 adding instrumentation for go.mongodb.org/mongo-driver/v2 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 844c4e1dbe7..4111a4d7b4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The next release will require at least [Go 1.23]. ### Added +- Add instrumentation support for `go.mongodb.org/mongo-driver/v2` in `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo`(#6539) - Add support for configuring `ClientCertificate` and `ClientKey` field for OTLP exporters in `go.opentelemetry.io/contrib/config`. (#6378) - Add `WithAttributeBuilder`, `AttributeBuilder`, `DefaultAttributeBuilder`, `DynamoDBAttributeBuilder`, `SNSAttributeBuilder` to support adding attributes based on SDK input and output in `go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws`. (#6543) - Support for the OTEL_HTTP_CLIENT_COMPATIBILITY_MODE=http/dup environment variable in `go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux` to emit attributes for both the v1.20.0 and v1.26.0 semantic conventions. (#6652) From c0d2e16c5e551ea7373a658e7efb160b4a24ba80 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:11:25 -0500 Subject: [PATCH 14/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/example_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go index c6c03826287..6f1c258f1b8 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go @@ -25,7 +25,7 @@ func Example() { db := client.Database("example") inventory := db.Collection("inventory") - _, err = inventory.InsertOne(context.Background(), bson.D{ + _, err = inventory.InsertOne(context.TODO(), bson.D{ {Key: "item", Value: "canvas"}, {Key: "qty", Value: 100}, {Key: "attributes", Value: bson.A{"cotton"}}, From 6ab56e183144d5aaa669ba032b086a66774ec8b8 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:11:52 -0500 Subject: [PATCH 15/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index 2f4e9fa40b5..6292af61fe7 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -113,6 +113,10 @@ func TestDBCrudOperation(t *testing.T) { md.AddResponses(tc.mockResponses...) client, err := mongo.Connect(opts) + defer func() { + err := client.Disconnect(context.Background()) + require.NoError(t, err) + }() if err != nil { t.FailNow() } From dd6d736a7bd051b195c49d67557062fb99af4661 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:12:03 -0500 Subject: [PATCH 16/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index 6292af61fe7..a9b30c918a1 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -117,9 +117,7 @@ func TestDBCrudOperation(t *testing.T) { err := client.Disconnect(context.Background()) require.NoError(t, err) }() - if err != nil { - t.FailNow() - } + require.NoError(t, err) _, err = tc.operation(ctx, client.Database("test-database")) if err != nil { From 7b9fc3e52e974299d83f8ddb34c8d6ee4360d7e5 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:12:20 -0500 Subject: [PATCH 17/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index a9b30c918a1..380829af8ae 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -120,9 +120,7 @@ func TestDBCrudOperation(t *testing.T) { require.NoError(t, err) _, err = tc.operation(ctx, client.Database("test-database")) - if err != nil { - t.Error(err) - } + require.NoError(t, err) span.End() From c40e17c325f0486b0fd386a28f264f8b51c3539b Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:12:39 -0500 Subject: [PATCH 18/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index 380829af8ae..e6fc61b762f 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -125,9 +125,7 @@ func TestDBCrudOperation(t *testing.T) { span.End() spans := sr.Ended() - if !assert.Len(t, spans, 2, "expected 2 spans, received %d", len(spans)) { - t.FailNow() - } + require.Len(t, spans, 2, "expected 2 spans, received %d", len(spans)) assert.Len(t, spans, 2) assert.Equal(t, spans[0].SpanContext().TraceID(), spans[1].SpanContext().TraceID()) assert.Equal(t, spans[0].Parent().SpanID(), spans[1].SpanContext().SpanID()) From 7675b51942a7dc332ed639b63655143c07446a41 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:12:47 -0500 Subject: [PATCH 19/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index e6fc61b762f..3fb5d4b1f53 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -229,9 +229,7 @@ func TestDBCollectionAttribute(t *testing.T) { } _, err = tc.operation(ctx, client.Database("test-database")) - if err != nil { - t.Error(err) - } + require.NoError(t, err) span.End() From afa32f5a41eaa1839b28772dc2880688b071daf9 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:12:57 -0500 Subject: [PATCH 20/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index 3fb5d4b1f53..12d773096dc 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -234,9 +234,7 @@ func TestDBCollectionAttribute(t *testing.T) { span.End() spans := sr.Ended() - if !assert.Len(t, spans, 2, "expected 2 spans, received %d", len(spans)) { - t.FailNow() - } + require.Len(t, spans, 2, "expected 2 spans, received %d", len(spans)) assert.Len(t, spans, 2) assert.Equal(t, spans[0].SpanContext().TraceID(), spans[1].SpanContext().TraceID()) assert.Equal(t, spans[0].Parent().SpanID(), spans[1].SpanContext().SpanID()) From ee21b8954594c9831cdb3c003ca6fe18cae1df07 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:13:24 -0500 Subject: [PATCH 21/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/test/mongo_test.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go index 12d773096dc..6e25e77bd00 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go @@ -224,9 +224,12 @@ func TestDBCollectionAttribute(t *testing.T) { md.AddResponses(tc.mockResponses...) client, err := mongo.Connect(opts) - if err != nil { - t.FailNow() - } + require.NoError(t, err) + + defer func() { + err := client.Disconnect(context.Background()) + require.NoError(t, err) + }() _, err = tc.operation(ctx, client.Database("test-database")) require.NoError(t, err) From 80b0e887d6e63b066256331506e2a898e9b52c3f Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 13:14:06 -0500 Subject: [PATCH 22/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go Co-authored-by: Preston Vasquez --- .../mongo-driver/v2/mongo/otelmongo/example_test.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go index 6f1c258f1b8..42b33434745 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/example_test.go @@ -22,6 +22,12 @@ func Example() { if err != nil { panic(err) } + + defer func() { + if err := client.Disconnect(context.TODO()); err != nil { + panic(err) + } + }() db := client.Database("example") inventory := db.Collection("inventory") From f2cd40609bc7754c2419b5c9192c4f2e8ba9266a Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 18 Mar 2025 14:19:12 -0500 Subject: [PATCH 23/34] fix: updated as per PR fedback --- CHANGELOG.md | 2 +- CODEOWNERS | 1 + .../mongo-driver/v2/mongo/otelmongo/go.mod | 15 +++- .../mongo-driver/v2/mongo/otelmongo/go.sum | 31 +++++-- .../mongo-driver/v2/mongo/otelmongo/mongo.go | 18 ++-- .../mongo/otelmongo/{test => }/mongo_test.go | 37 +++++---- .../v2/mongo/otelmongo/test/doc.go | 11 --- .../v2/mongo/otelmongo/test/go.mod | 38 --------- .../v2/mongo/otelmongo/test/go.sum | 82 ------------------- .../v2/mongo/otelmongo/test/version.go | 17 ---- .../v2/mongo/otelmongo/test/version_test.go | 24 ------ 11 files changed, 64 insertions(+), 212 deletions(-) rename instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/{test => }/mongo_test.go (87%) delete mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go delete mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod delete mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum delete mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go delete mode 100644 instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index e9170e2ccb1..d90ee101b04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,7 +43,6 @@ migration](https://github.com/open-telemetry/semantic-conventions/blob/main/docs ### Added -- Add instrumentation support for `go.mongodb.org/mongo-driver/v2` in `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo`(#6539) - Add support for configuring `ClientCertificate` and `ClientKey` field for OTLP exporters in `go.opentelemetry.io/contrib/config`. (#6378) - Add `WithAttributeBuilder`, `AttributeBuilder`, `DefaultAttributeBuilder`, `DynamoDBAttributeBuilder`, `SNSAttributeBuilder` to support adding attributes based on SDK input and output in `go.opentelemetry.io/contrib/instrumentation/github.com/aws/aws-sdk-go-v2/otelaws`. (#6543) - Support for the `OTEL_SEMCONV_STABILITY_OPT_IN=http/dup` environment variable in `go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux` to emit attributes for both the v1.20.0 and v1.26.0 semantic conventions. (#6652) @@ -60,6 +59,7 @@ migration](https://github.com/open-telemetry/semantic-conventions/blob/main/docs - Add support for configuring `HeadersList` field for OTLP exporters in `go.opentelemetry.io/contrib/config`. (#6657) - Add `go.opentelemetry.io/contrib/otelconf` module which is a replacement for `go.opentelemetry.io/contrib/config`. (#6796) - Added `WithFallbackLogExporter` to allow setting a fallback log exporter when `OTEL_LOGS_EXPORTER` is unset in `go.opentelemetry.io/contrib/exporters/autoexport`. (#6844) +- Add instrumentation support for `go.mongodb.org/mongo-driver/v2` in `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo`(#6539) ### Changed diff --git a/CODEOWNERS b/CODEOWNERS index 5481e8170e5..db8fd3fc6b6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -49,6 +49,7 @@ instrumentation/github.com/gin-gonic/gin/otelgin/ @open-te instrumentation/github.com/gorilla/mux/otelmux/ @open-telemetry/go-approvers @akats7 instrumentation/github.com/labstack/echo/otelecho/ @open-telemetry/go-approvers @scorpionknifes instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo/ @open-telemetry/go-approvers +instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/ @open-telemetry/go-approvers instrumentation/google.golang.org/grpc/otelgrpc/ @open-telemetry/go-approvers @dashpole instrumentation/host/ @open-telemetry/go-approvers @dmathieu diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod index 6d7d922c823..f89dfd5c39a 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.mod @@ -1,25 +1,32 @@ module go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo -go 1.22.0 +go 1.23.0 require ( + github.com/stretchr/testify v1.10.0 go.mongodb.org/mongo-driver/v2 v2.0.0 - go.opentelemetry.io/otel v1.33.0 - go.opentelemetry.io/otel/trace v1.33.0 + go.opentelemetry.io/otel v1.35.0 + go.opentelemetry.io/otel/sdk v1.33.0 + go.opentelemetry.io/otel/trace v1.35.0 ) require ( + github.com/davecgh/go-spew v1.1.1 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/golang/snappy v0.0.4 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/klauspost/compress v1.17.11 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect + go.opentelemetry.io/otel/metric v1.35.0 // indirect golang.org/x/crypto v0.31.0 // indirect golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/text v0.21.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum index 32daa773bc9..5bc6dce8be0 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/go.sum @@ -7,12 +7,20 @@ 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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +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/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= @@ -28,12 +36,14 @@ go.mongodb.org/mongo-driver/v2 v2.0.0 h1:Jfd7XpdZa9yk3eY774bO7SWVb30noLSirL9nKTp go.mongodb.org/mongo-driver/v2 v2.0.0/go.mod h1:nSjmNq4JUstE8IRZKTktLgMHM4F1fccL6HGX1yh+8RA= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ= +go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M= +go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= +go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs= +go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= @@ -51,6 +61,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -63,5 +75,8 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go index 68942aee4bb..b2815d62e6b 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -13,7 +13,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" - semconv "go.opentelemetry.io/otel/semconv/v1.21.0" + semconv "go.opentelemetry.io/otel/semconv/v1.30.0" "go.opentelemetry.io/otel/trace" "go.mongodb.org/mongo-driver/v2/bson" @@ -37,19 +37,19 @@ func (m *monitor) Started(ctx context.Context, evt *event.CommandStartedEvent) { hostname, port := peerInfo(evt) attrs := []attribute.KeyValue{ - semconv.DBSystemMongoDB, - semconv.DBOperation(evt.CommandName), - semconv.DBName(evt.DatabaseName), - semconv.NetPeerName(hostname), - semconv.NetPeerPort(port), - semconv.NetTransportTCP, + semconv.DBSystemNameMongoDB, + semconv.DBOperationName(evt.CommandName), + semconv.DBNamespace(evt.DatabaseName), + semconv.NetworkPeerAddress(hostname), + semconv.NetworkPeerPort(port), + semconv.NetworkTransportTCP, } if !m.cfg.CommandAttributeDisabled { - attrs = append(attrs, semconv.DBStatement(sanitizeCommand(evt.Command))) + attrs = append(attrs, semconv.DBQueryText(sanitizeCommand(evt.Command))) } if collection, err := extractCollection(evt); err == nil && collection != "" { spanName = collection + "." - attrs = append(attrs, semconv.DBMongoDBCollection(collection)) + attrs = append(attrs, semconv.DBCollectionName(collection)) } spanName += evt.CommandName opts := []trace.SpanStartOption{ diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go similarity index 87% rename from instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go rename to instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go index 6e25e77bd00..c2218e6af46 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package test +package otelmongo_test import ( "context" @@ -9,6 +9,7 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/v2/bson" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" @@ -30,10 +31,10 @@ func TestDBCrudOperation(t *testing.T) { return assert.Equal(t, "test-collection.insert", s.Name(), "expected %s", s.Name()) }, func(s sdktrace.ReadOnlySpan) bool { - return assert.Contains(t, s.Attributes(), attribute.String("db.operation", "insert")) + return assert.Contains(t, s.Attributes(), attribute.String("db.operation.name", "insert")) }, func(s sdktrace.ReadOnlySpan) bool { - return assert.Contains(t, s.Attributes(), attribute.String("db.mongodb.collection", "test-collection")) + return assert.Contains(t, s.Attributes(), attribute.String("db.collection.name", "test-collection")) }, func(s sdktrace.ReadOnlySpan) bool { return assert.Equal(t, codes.Unset, s.Status().Code) @@ -56,7 +57,7 @@ func TestDBCrudOperation(t *testing.T) { excludeCommand: false, validators: append(commonValidators, func(s sdktrace.ReadOnlySpan) bool { for _, attr := range s.Attributes() { - if attr.Key == "db.statement" { + if attr.Key == "db.query.text" { return assert.Contains(t, attr.Value.AsString(), `"test-item":"test-value"`) } } @@ -134,11 +135,11 @@ func TestDBCrudOperation(t *testing.T) { s := spans[0] assert.Equal(t, trace.SpanKindClient, s.SpanKind()) attrs := s.Attributes() - assert.Contains(t, attrs, attribute.String("db.system", "mongodb")) - assert.Contains(t, attrs, attribute.String("net.peer.name", "")) - assert.Contains(t, attrs, attribute.Int64("net.peer.port", int64(27017))) - assert.Contains(t, attrs, attribute.String("net.transport", "ip_tcp")) - assert.Contains(t, attrs, attribute.String("db.name", "test-database")) + assert.Contains(t, attrs, attribute.String("db.system.name", "mongodb")) + assert.Contains(t, attrs, attribute.String("network.peer.address", "")) + assert.Contains(t, attrs, attribute.Int64("network.peer.port", int64(27017))) + assert.Contains(t, attrs, attribute.String("network.transport", "tcp")) + assert.Contains(t, attrs, attribute.String("db.namespace", "test-database")) for _, v := range tc.validators { assert.True(t, v(s)) } @@ -164,10 +165,10 @@ func TestDBCollectionAttribute(t *testing.T) { return assert.Equal(t, "test-collection.delete", s.Name()) }, func(s sdktrace.ReadOnlySpan) bool { - return assert.Contains(t, s.Attributes(), attribute.String("db.operation", "delete")) + return assert.Contains(t, s.Attributes(), attribute.String("db.operation.name", "delete")) }, func(s sdktrace.ReadOnlySpan) bool { - return assert.Contains(t, s.Attributes(), attribute.String("db.mongodb.collection", "test-collection")) + return assert.Contains(t, s.Attributes(), attribute.String("db.collection.name", "test-collection")) }, func(s sdktrace.ReadOnlySpan) bool { return assert.Equal(t, codes.Unset, s.Status().Code) @@ -190,7 +191,7 @@ func TestDBCollectionAttribute(t *testing.T) { return assert.Equal(t, "listCollections", s.Name()) }, func(s sdktrace.ReadOnlySpan) bool { - return assert.Contains(t, s.Attributes(), attribute.String("db.operation", "listCollections")) + return assert.Contains(t, s.Attributes(), attribute.String("db.operation.name", "listCollections")) }, func(s sdktrace.ReadOnlySpan) bool { return assert.Equal(t, codes.Unset, s.Status().Code) @@ -225,7 +226,7 @@ func TestDBCollectionAttribute(t *testing.T) { md.AddResponses(tc.mockResponses...) client, err := mongo.Connect(opts) require.NoError(t, err) - + defer func() { err := client.Disconnect(context.Background()) require.NoError(t, err) @@ -246,11 +247,11 @@ func TestDBCollectionAttribute(t *testing.T) { s := spans[0] assert.Equal(t, trace.SpanKindClient, s.SpanKind()) attrs := s.Attributes() - assert.Contains(t, attrs, attribute.String("db.system", "mongodb")) - assert.Contains(t, attrs, attribute.String("net.peer.name", "")) - assert.Contains(t, attrs, attribute.Int64("net.peer.port", int64(27017))) - assert.Contains(t, attrs, attribute.String("net.transport", "ip_tcp")) - assert.Contains(t, attrs, attribute.String("db.name", "test-database")) + assert.Contains(t, attrs, attribute.String("db.system.name", "mongodb")) + assert.Contains(t, attrs, attribute.String("network.peer.address", "")) + assert.Contains(t, attrs, attribute.Int64("network.peer.port", int64(27017))) + assert.Contains(t, attrs, attribute.String("network.transport", "tcp")) + assert.Contains(t, attrs, attribute.String("db.namespace", "test-database")) for _, v := range tc.validators { assert.True(t, v(s)) } diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go deleted file mode 100644 index 839d36f57d5..00000000000 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/doc.go +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -/* -Package test validates the otelmongo V2 instrumentation with the default SDK. - -This package is in a separate module from the instrumentation it tests to -isolate the dependency of the default SDK and not impose this as a transitive -dependency for users. -*/ -package test // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test" diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod deleted file mode 100644 index 1af1073901a..00000000000 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.mod +++ /dev/null @@ -1,38 +0,0 @@ -module go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test - -go 1.22.0 - -require ( - github.com/stretchr/testify v1.10.0 - go.mongodb.org/mongo-driver/v2 v2.0.0 - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo v0.0.0-00010101000000-000000000000 - go.opentelemetry.io/otel v1.33.0 - go.opentelemetry.io/otel/sdk v1.33.0 - go.opentelemetry.io/otel/trace v1.33.0 -) - -require ( - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/golang/snappy v0.0.4 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/klauspost/compress v1.17.11 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/xdg-go/pbkdf2 v1.0.0 // indirect - github.com/xdg-go/scram v1.1.2 // indirect - github.com/xdg-go/stringprep v1.0.4 // indirect - github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect - go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect -) - -replace ( - go.opentelemetry.io/contrib => ../../../../../.. - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo => ../ -) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum deleted file mode 100644 index 071688c8174..00000000000 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/go.sum +++ /dev/null @@ -1,82 +0,0 @@ -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= -github.com/go-logr/logr v1.4.2/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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -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/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= -github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= -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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= -github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= -github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= -github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= -github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= -github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -go.mongodb.org/mongo-driver/v2 v2.0.0 h1:Jfd7XpdZa9yk3eY774bO7SWVb30noLSirL9nKTpavhI= -go.mongodb.org/mongo-driver/v2 v2.0.0/go.mod h1:nSjmNq4JUstE8IRZKTktLgMHM4F1fccL6HGX1yh+8RA= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= -go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -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/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go deleted file mode 100644 index e3551c39c0a..00000000000 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package test // import "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test" - -// Version is the current release version of the mongo-driver instrumentation test module. -func Version() string { - return "0.60.0" - // This string is updated by the pre_release.sh script during release -} - -// SemVersion is the semantic version to be supplied to tracer/meter creation. -// -// Deprecated: Use [Version] instead. -func SemVersion() string { - return Version() -} diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go deleted file mode 100644 index 851ec95a599..00000000000 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test/version_test.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 - -package test_test - -import ( - "regexp" - "testing" - - "github.com/stretchr/testify/assert" - - "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test" -) - -// regex taken from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string -var versionRegex = regexp.MustCompile(`^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)` + - `(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)` + - `(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` + - `(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`) - -func TestVersionSemver(t *testing.T) { - v := test.Version() - assert.NotNil(t, versionRegex.FindStringSubmatch(v), "version is not semver: %s", v) -} From d9dbc542a40212aaae6dcd3696fdc2ede9119221 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Mon, 24 Mar 2025 09:36:55 -0500 Subject: [PATCH 24/34] chore: removed go.mongodb.org/mongo-driver/v2/mongo/otelmongo and adjusted related changelog --- CHANGELOG.md | 2 +- versions.yaml | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 69da127d8a2..0558c72c1cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Add `WithAttributes` option to set instrumentation scope attributes on the created `log.Logger` in `go.opentelemetry.io/contrib/bridges/otellogrus`. (#6966) - Add `WithAttributes` option to set instrumentation scope attributes on the created `log.Logger` in `go.opentelemetry.io/contrib/bridges/otellogr`. (#6967) - Add the `WithGinMetricAttributes` option to allow setting dynamic, per-request metric attributes based on `*gin.Context` in `go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin`. (#6932) +- Add instrumentation support for `go.mongodb.org/mongo-driver/v2` in `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo`(#6539) ### Changed @@ -74,7 +75,6 @@ migration](https://github.com/open-telemetry/semantic-conventions/blob/main/docs - Add support for configuring `HeadersList` field for OTLP exporters in `go.opentelemetry.io/contrib/config`. (#6657) - Add `go.opentelemetry.io/contrib/otelconf` module which is a replacement for `go.opentelemetry.io/contrib/config`. (#6796) - Added `WithFallbackLogExporter` to allow setting a fallback log exporter when `OTEL_LOGS_EXPORTER` is unset in `go.opentelemetry.io/contrib/exporters/autoexport`. (#6844) -- Add instrumentation support for `go.mongodb.org/mongo-driver/v2` in `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo`(#6539) ### Changed diff --git a/versions.yaml b/versions.yaml index a0cf027c60a..eae3cd2771b 100644 --- a/versions.yaml +++ b/versions.yaml @@ -36,8 +36,6 @@ module-sets: - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/test - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo/test - - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo - - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/test - go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux - go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux/example - go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux/test From 199af6e98e7a19dedb7c015e09b44cdb81c0f08f Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Mon, 31 Mar 2025 08:25:02 -0500 Subject: [PATCH 25/34] feat: adding go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo exclusion --- versions.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/versions.yaml b/versions.yaml index eae3cd2771b..abaf1ca68f7 100644 --- a/versions.yaml +++ b/versions.yaml @@ -23,7 +23,7 @@ module-sets: - go.opentelemetry.io/contrib/exporters/autoexport - go.opentelemetry.io/contrib/propagators/autoprop - go.opentelemetry.io/contrib/propagators/opencensus - - go.opentelemetry.io/contrib/propagators/opencensus/examples + - go.opentelemetry.io/contrib/propagators/opencensus/examplesx - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/example - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/test @@ -97,3 +97,4 @@ excluded-modules: - go.opentelemetry.io/contrib/examples/passthrough - go.opentelemetry.io/contrib/examples/prometheus - go.opentelemetry.io/contrib/examples/zipkin + - go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo From 6104456c662fe90861a6b0db30f20cfb6a8d26f1 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Wed, 2 Apr 2025 15:52:39 -0500 Subject: [PATCH 26/34] Update versions.yaml Co-authored-by: Damien Mathieu <42@dmathieu.com> --- versions.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/versions.yaml b/versions.yaml index abaf1ca68f7..ae5426ebbf2 100644 --- a/versions.yaml +++ b/versions.yaml @@ -23,7 +23,7 @@ module-sets: - go.opentelemetry.io/contrib/exporters/autoexport - go.opentelemetry.io/contrib/propagators/autoprop - go.opentelemetry.io/contrib/propagators/opencensus - - go.opentelemetry.io/contrib/propagators/opencensus/examplesx + - go.opentelemetry.io/contrib/propagators/opencensus/examples - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/example - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp/internal/semconv/test From ef0cecb15bd2c9d44e4cf33324274e78d65440cf Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Tue, 22 Apr 2025 09:55:29 -0500 Subject: [PATCH 27/34] Update CODEOWNERS Co-authored-by: Damien Mathieu <42@dmathieu.com> --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index e0adb8080e1..436bd73303e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -47,7 +47,7 @@ instrumentation/github.com/gin-gonic/gin/otelgin/ @open-te instrumentation/github.com/gorilla/mux/otelmux/ @open-telemetry/go-approvers @akats7 instrumentation/github.com/labstack/echo/otelecho/ @open-telemetry/go-approvers @scorpionknifes instrumentation/go.mongodb.org/mongo-driver/mongo/otelmongo/ @open-telemetry/go-approvers @prestonvasquez -instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/ @open-telemetry/go-approvers +instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/ @open-telemetry/go-approvers @prestonvasquez instrumentation/google.golang.org/grpc/otelgrpc/ @open-telemetry/go-approvers @dashpole instrumentation/host/ @open-telemetry/go-approvers @dmathieu From d996ffa350d0b9b11a87ed89aaa7ca60b3100ce2 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Mon, 28 Apr 2025 08:43:55 -0500 Subject: [PATCH 28/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go Co-authored-by: Sam Xie --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go index b2815d62e6b..76a7d1e6e76 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -71,7 +71,7 @@ func (m *monitor) Succeeded(ctx context.Context, evt *event.CommandSucceededEven } func (m *monitor) Failed(ctx context.Context, evt *event.CommandFailedEvent) { - m.Finished(&evt.CommandFinishedEvent, fmt.Errorf("%w", evt.Failure)) + m.Finished(&evt.CommandFinishedEvent, evt.Failure) } func (m *monitor) Finished(evt *event.CommandFinishedEvent, err error) { From 008b27e6990b6a55e8266569a21d8c60e1c3cf65 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Mon, 28 Apr 2025 11:55:03 -0500 Subject: [PATCH 29/34] chore: update imports --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go index 76a7d1e6e76..423a08a2b16 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -6,7 +6,6 @@ package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mong import ( "context" "errors" - "fmt" "strconv" "strings" "sync" From 11147fc95a93c6fdebf9f5af5c77b3c8ed0ab508 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 2 May 2025 09:45:25 -0500 Subject: [PATCH 30/34] Update instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go Co-authored-by: Sam Xie --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go index 423a08a2b16..3f741276f26 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -142,7 +142,7 @@ func peerInfo(evt *event.CommandStartedEvent) (hostname string, port int) { hostname = hostname[:idx] } if idx := strings.IndexByte(hostname, ':'); idx >= 0 { - port = func(p int, e error) int { return p }(strconv.Atoi(hostname[idx+1:])) + port, _ = strconv.Atoi(hostname[idx+1:]) hostname = hostname[:idx] } return hostname, port From a5981a95a0ab7f4826945d260efc8dccf45a7986 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 2 May 2025 10:24:40 -0500 Subject: [PATCH 31/34] fix: added unit test for peerInfo and fixed logic issue --- .../mongo-driver/v2/mongo/otelmongo/mongo.go | 37 +++++++-- .../v2/mongo/otelmongo/mongo_test.go | 80 +++++++++++++++++-- 2 files changed, 102 insertions(+), 15 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go index 3f741276f26..835a4f35fb0 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -135,15 +135,38 @@ func NewMonitor(opts ...Option) *event.CommandMonitor { } } +// peerInfo will parse the hostname and port from the mongo connection ID. func peerInfo(evt *event.CommandStartedEvent) (hostname string, port int) { hostname = evt.ConnectionID - port = 27017 - if idx := strings.IndexByte(hostname, '['); idx >= 0 { - hostname = hostname[:idx] - } - if idx := strings.IndexByte(hostname, ':'); idx >= 0 { - port, _ = strconv.Atoi(hostname[idx+1:]) - hostname = hostname[:idx] + port = 27017 // Default MongoDB port + + if strings.HasPrefix(hostname, "[") { + // IPv6 address with square brackets + if idx := strings.LastIndex(hostname, "]:"); idx >= 0 { + // IPv6 address with port + // e.g. [::1]:27017 + port, _ = strconv.Atoi(hostname[idx+2:]) + hostname = hostname[1:idx] + } else if strings.HasSuffix(hostname, "]") { + // IPv6 address without port + // e.g. [::1] + hostname = hostname[1 : len(hostname)-1] + } + } else if strings.Contains(hostname, ":") { + // IPv6 address without square brackets + if idx := strings.LastIndex(hostname, ":"); !(idx >= 0 && strings.Count(hostname, ":") > 1) { + // IPv4 or hostname with port + // This logic also excludes IPv6 addresses without ports, e.g. ::1 + port, _ = strconv.Atoi(hostname[idx+1:]) + hostname = hostname[:idx] + } + } else { + // IPv4 or hostname without port + if idx := strings.LastIndex(hostname, ":"); idx >= 0 { + port, _ = strconv.Atoi(hostname[idx+1:]) + hostname = hostname[:idx] + } } + return hostname, port } diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go index c2218e6af46..54a8972461f 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go @@ -1,7 +1,7 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 -package otelmongo_test +package otelmongo import ( "context" @@ -11,11 +11,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.mongodb.org/mongo-driver/v2/bson" + "go.mongodb.org/mongo-driver/v2/event" "go.mongodb.org/mongo-driver/v2/mongo" "go.mongodb.org/mongo-driver/v2/mongo/options" "go.mongodb.org/mongo-driver/v2/x/mongo/driver/drivertest" - "go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/codes" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -106,9 +106,9 @@ func TestDBCrudOperation(t *testing.T) { opts := options.Client() //nolint:staticcheck opts.Deployment = md // This method is the current documented way to set the mongodb mock. See https://github.com/mongodb/mongo-go-driver/blob/v2.0.0/x/mongo/driver/drivertest/opmsg_deployment_test.go#L24 - opts.Monitor = otelmongo.NewMonitor( - otelmongo.WithTracerProvider(provider), - otelmongo.WithCommandAttributeDisabled(tc.excludeCommand), + opts.Monitor = NewMonitor( + WithTracerProvider(provider), + WithCommandAttributeDisabled(tc.excludeCommand), ) opts.ApplyURI(addr) @@ -217,9 +217,9 @@ func TestDBCollectionAttribute(t *testing.T) { opts := options.Client() //nolint:staticcheck opts.Deployment = md // This method is the current documented way to set the mongodb mock. See https://github.com/mongodb/mongo-go-driver/blob/v2.0.0/x/mongo/driver/drivertest/opmsg_deployment_test.go#L24 - opts.Monitor = otelmongo.NewMonitor( - otelmongo.WithTracerProvider(provider), - otelmongo.WithCommandAttributeDisabled(true), + opts.Monitor = NewMonitor( + WithTracerProvider(provider), + WithCommandAttributeDisabled(true), ) opts.ApplyURI(addr) @@ -258,3 +258,67 @@ func TestDBCollectionAttribute(t *testing.T) { }) } } +func TestPeerInfo(t *testing.T) { + tests := []struct { + name string + connectionID string + expectedHost string + expectedPort int + }{ + { + name: "IPv4 with port", + connectionID: "127.0.0.1:27018", + expectedHost: "127.0.0.1", + expectedPort: 27018, + }, + { + name: "IPv4 without port", + connectionID: "127.0.0.1", + expectedHost: "127.0.0.1", + expectedPort: 27017, + }, + { + name: "IPv6 with port", + connectionID: "[::1]:27019", + expectedHost: "::1", + expectedPort: 27019, + }, + { + name: "IPv6 without port with square brackets", + connectionID: "[::1]", + expectedHost: "::1", + expectedPort: 27017, + }, + { + name: "IPv6 without port", + connectionID: "::1", + expectedHost: "::1", + expectedPort: 27017, + }, + { + name: "Hostname with port", + connectionID: "example.com:27020", + expectedHost: "example.com", + expectedPort: 27020, + }, + { + name: "Hostname without port", + connectionID: "example.com", + expectedHost: "example.com", + expectedPort: 27017, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + + evt := &event.CommandStartedEvent{ + ConnectionID: tc.connectionID, + } + host, port := peerInfo(evt) + assert.Equal(t, tc.expectedHost, host) + assert.Equal(t, tc.expectedPort, port) + }) + } +} From e67c9dc117ac32b02dd4054836ba7bb4c5df3567 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 2 May 2025 10:31:14 -0500 Subject: [PATCH 32/34] switch logic to use net.SplitHostPort --- .../mongo-driver/v2/mongo/otelmongo/mongo.go | 44 ++++++------------- .../v2/mongo/otelmongo/mongo_test.go | 2 +- 2 files changed, 15 insertions(+), 31 deletions(-) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go index 835a4f35fb0..2e959caa14b 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo.go @@ -6,8 +6,8 @@ package otelmongo // import "go.opentelemetry.io/contrib/instrumentation/go.mong import ( "context" "errors" + "net" "strconv" - "strings" "sync" "go.opentelemetry.io/otel/attribute" @@ -137,35 +137,19 @@ func NewMonitor(opts ...Option) *event.CommandMonitor { // peerInfo will parse the hostname and port from the mongo connection ID. func peerInfo(evt *event.CommandStartedEvent) (hostname string, port int) { - hostname = evt.ConnectionID - port = 27017 // Default MongoDB port - - if strings.HasPrefix(hostname, "[") { - // IPv6 address with square brackets - if idx := strings.LastIndex(hostname, "]:"); idx >= 0 { - // IPv6 address with port - // e.g. [::1]:27017 - port, _ = strconv.Atoi(hostname[idx+2:]) - hostname = hostname[1:idx] - } else if strings.HasSuffix(hostname, "]") { - // IPv6 address without port - // e.g. [::1] - hostname = hostname[1 : len(hostname)-1] - } - } else if strings.Contains(hostname, ":") { - // IPv6 address without square brackets - if idx := strings.LastIndex(hostname, ":"); !(idx >= 0 && strings.Count(hostname, ":") > 1) { - // IPv4 or hostname with port - // This logic also excludes IPv6 addresses without ports, e.g. ::1 - port, _ = strconv.Atoi(hostname[idx+1:]) - hostname = hostname[:idx] - } - } else { - // IPv4 or hostname without port - if idx := strings.LastIndex(hostname, ":"); idx >= 0 { - port, _ = strconv.Atoi(hostname[idx+1:]) - hostname = hostname[:idx] - } + defaultMongoPort := 27017 + hostname, portStr, err := net.SplitHostPort(evt.ConnectionID) + if err != nil { + // If parsing fails, assume default MongoDB port and return the entire ConnectionID as hostname + hostname = evt.ConnectionID + port = defaultMongoPort + return + } + + port, err = strconv.Atoi(portStr) + if err != nil || port < 1 { + // If port parsing fails, fallback to default MongoDB port + port = defaultMongoPort } return hostname, port diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go index 54a8972461f..b951eebc8f2 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go @@ -286,7 +286,7 @@ func TestPeerInfo(t *testing.T) { { name: "IPv6 without port with square brackets", connectionID: "[::1]", - expectedHost: "::1", + expectedHost: "[::1]", expectedPort: 27017, }, { From 56fad4e63e7663903f60395a26b8ea7dcd3a7a92 Mon Sep 17 00:00:00 2001 From: Alaric Whitney Date: Fri, 2 May 2025 11:06:06 -0500 Subject: [PATCH 33/34] chore: linting --- .../go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go index b951eebc8f2..f5363b40192 100644 --- a/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go +++ b/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo/mongo_test.go @@ -258,6 +258,7 @@ func TestDBCollectionAttribute(t *testing.T) { }) } } + func TestPeerInfo(t *testing.T) { tests := []struct { name string From 2c6ae997a1163cfcf76a1bd91091224c4791350f Mon Sep 17 00:00:00 2001 From: Damien Mathieu <42@dmathieu.com> Date: Wed, 7 May 2025 09:04:51 +0200 Subject: [PATCH 34/34] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7aeba5bec62..edbb73f1415 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm - Allow configuring samplers in `go.opentelemetry.io/contrib/otelconf`. (#7148) - Slog log bridge now sets `SeverityText` attribute using source value in `go.opentelemetry.io/contrib/bridges/otelslog`. (#7198) - Add `http.route` metric attribute in `go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin`. (#7275) -- Add instrumentation support for `go.mongodb.org/mongo-driver/v2` in `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo`(#6539) +- Add instrumentation support for `go.mongodb.org/mongo-driver/v2` in `go.opentelemetry.io/contrib/instrumentation/go.mongodb.org/mongo-driver/v2/mongo/otelmongo`. (#6539) ### Changed