From d003b3288528cb0a5dfdd0e75cce074743b10d58 Mon Sep 17 00:00:00 2001 From: Andrew Glaude Date: Mon, 19 Aug 2024 11:21:20 -0400 Subject: [PATCH 1/2] Drop support for ancient and unused grpc.v12 --- .github/workflows/govulncheck.yml | 3 +- .github/workflows/multios-unit-tests.yml | 2 +- .github/workflows/unit-integration-tests.yml | 28 +- .gitignore | 1 - .golangci.yml | 4 +- README.md | 4 +- .../grpc.v12/example_test.go | 50 --- .../grpc.v12/fixtures_test.pb.go | 173 -------- .../grpc.v12/fixtures_test.proto | 21 - contrib/google.golang.org/grpc.v12/grpc.go | 133 ------ .../google.golang.org/grpc.v12/grpc_test.go | 417 ------------------ contrib/google.golang.org/grpc.v12/option.go | 82 ---- contrib/google.golang.org/grpc.v12/tags.go | 12 - ddtrace/tracer/option.go | 20 +- ddtrace/tracer/option_test.go | 35 +- test.sh | 2 +- 16 files changed, 8 insertions(+), 979 deletions(-) delete mode 100644 contrib/google.golang.org/grpc.v12/example_test.go delete mode 100644 contrib/google.golang.org/grpc.v12/fixtures_test.pb.go delete mode 100644 contrib/google.golang.org/grpc.v12/fixtures_test.proto delete mode 100644 contrib/google.golang.org/grpc.v12/grpc.go delete mode 100644 contrib/google.golang.org/grpc.v12/grpc_test.go delete mode 100644 contrib/google.golang.org/grpc.v12/option.go delete mode 100644 contrib/google.golang.org/grpc.v12/tags.go diff --git a/.github/workflows/govulncheck.yml b/.github/workflows/govulncheck.yml index 9c271a919e..152b5b50b8 100644 --- a/.github/workflows/govulncheck.yml +++ b/.github/workflows/govulncheck.yml @@ -32,7 +32,6 @@ jobs: run: govulncheck ./ddtrace/... ./appsec/... ./profiler/... ./internal/... - name: Run govulncheck-contribs run: | - # Excluding legacy contrib grpc.v12 - go list -f '{{.Dir}}' ./contrib/... | grep -v -e grpc.v12 | while read dir ; do + go list -f '{{.Dir}}' ./contrib/... | while read dir ; do govulncheck -C $dir . done \ No newline at end of file diff --git a/.github/workflows/multios-unit-tests.yml b/.github/workflows/multios-unit-tests.yml index b9f8a7f9ba..3ca8900602 100644 --- a/.github/workflows/multios-unit-tests.yml +++ b/.github/workflows/multios-unit-tests.yml @@ -53,7 +53,7 @@ jobs: - name: "Runner ${{ matrix.runner-index }}: Test Core and Contrib (No Integration Tests)" shell: bash run: | - go list ./... | grep -v -e grpc.v12 -e google.golang.org/api -e sarama -e confluent-kafka-go -e cmemprof | sort >packages.txt + go list ./... | grep -v -e google.golang.org/api -e sarama -e confluent-kafka-go -e cmemprof | sort >packages.txt gotestsum --junitfile ${REPORT} -- $(cat packages.txt) -v -coverprofile=coverage.txt -covermode=atomic -timeout 15m - name: Upload the results to Datadog CI App if: always() diff --git a/.github/workflows/unit-integration-tests.yml b/.github/workflows/unit-integration-tests.yml index 36312fba7a..0eb78e3b7e 100644 --- a/.github/workflows/unit-integration-tests.yml +++ b/.github/workflows/unit-integration-tests.yml @@ -197,7 +197,7 @@ jobs: - name: Test Contrib run: | mkdir -p $TEST_RESULTS - PACKAGE_NAMES=$(go list ./contrib/... | grep -v -e grpc.v12 -e google.golang.org/api) + PACKAGE_NAMES=$(go list ./contrib/... | grep -v -e google.golang.org/api) gotestsum --junitfile ${TEST_RESULTS}/gotestsum-report.xml -- $PACKAGE_NAMES -v -race -coverprofile=coverage.txt -covermode=atomic - name: Upload the results to Datadog CI App @@ -249,32 +249,6 @@ jobs: go mod tidy # Go1.16 doesn't update the sum file correctly after the go get, this tidy fixes it go test -v ./contrib/google.golang.org/api/... - - name: Testing outlier gRPC v1.2 - run: | - # This hacky approach is necessary because running the tests regularly - # do not allow using grpc-go@v1.2.0 alongside sketches-go@v1.1.0. - # sketches-go@v1.0.0 is no longer possible to test because internal/datastreams/propagator.go - # expects sketches-go to have the package `github.com/DataDog/sketches-go/ddsketch/encoding` which - # is only present from v1.1.0 onwards. - go mod vendor - - # Checkout grpc-go@v1.2.0 - cd vendor/google.golang.org && rm -rf grpc - git clone https://github.com/grpc/grpc-go grpc && cd grpc - git fetch origin && git checkout v1.2.0 && cd ../../.. - - # Checkout sketches-go@v1.1.0 - cd vendor/github.com/DataDog && rm -rf sketches-go - git clone https://github.com/DataDog/sketches-go && cd sketches-go - git fetch origin && git checkout v1.1.0 && cd ../../../.. - - # Revert to old metadata functions as FromIncomingContext and NewOutgoingContext are not present in v1.2.0. - # These functions were updated to current versions to avoid compilation errors in the development environments. - sed -i 's/metadata\.FromIncomingContext/metadata.FromContext/g' ./contrib/google.golang.org/grpc.v12/* - sed -i 's/metadata\.NewOutgoingContext/metadata.NewContext/g' ./contrib/google.golang.org/grpc.v12/* - - go test -mod=vendor -v ./contrib/google.golang.org/grpc.v12/... - test-core: runs-on: group: "APM Larger Runners" diff --git a/.gitignore b/.gitignore index 66bca130e5..5528039708 100644 --- a/.gitignore +++ b/.gitignore @@ -15,7 +15,6 @@ go.work* dd-trace-go.iml vendor -/contrib/google.golang.org/grpc.v12/vendor/ /contrib_coverage.txt /core_coverage.txt /gotestsum-report.xml diff --git a/.golangci.yml b/.golangci.yml index 88a9f92c5b..6fcd0cd10e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,8 +1,6 @@ run: deadline: 10m - skip-dirs: - # This package is an exception and has its own test job (Testing outlier gRPC v1.2). - - contrib/google.golang.org/grpc.v12 + linters: disable-all: true enable: diff --git a/README.md b/README.md index 8ea1c5ad10..070fb5720a 100644 --- a/README.md +++ b/README.md @@ -53,9 +53,7 @@ Before considering contributions to the project, please take a moment to read ou ### Testing -Tests can be run locally using the Go toolset. The grpc.v12 integration will fail (and this is normal), because it covers for deprecated methods. In the CI environment -we vendor this version of the library inside the integration. Under normal circumstances this is not something that we want to do, because users using this integration -might be running versions different from the vendored one, creating hard to debug conflicts. +Tests can be run locally using the Go toolset. To run integration tests locally, you should set the `INTEGRATION` environment variable. The dependencies of the integration tests are best run via Docker. To get an idea about the versions and the set-up take a look at our [docker-compose config](./docker-compose.yaml). diff --git a/contrib/google.golang.org/grpc.v12/example_test.go b/contrib/google.golang.org/grpc.v12/example_test.go deleted file mode 100644 index 677e897519..0000000000 --- a/contrib/google.golang.org/grpc.v12/example_test.go +++ /dev/null @@ -1,50 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016 Datadog, Inc. - -package grpc_test - -import ( - "log" - "net" - - grpctrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/google.golang.org/grpc.v12" - - "google.golang.org/grpc" -) - -func Example_client() { - // Create the client interceptor using the grpc trace package. - i := grpctrace.UnaryClientInterceptor(grpctrace.WithServiceName("my-grpc-client")) - - // Dial in using the created interceptor... - conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithUnaryInterceptor(i)) - if err != nil { - log.Fatal(err) - } - defer conn.Close() - - // And continue using the connection as normal. -} - -func Example_server() { - // Create a listener for the server. - ln, err := net.Listen("tcp", ":50051") - if err != nil { - log.Fatal(err) - } - - // Create the unary server interceptor using the grpc trace package. - i := grpctrace.UnaryServerInterceptor(grpctrace.WithServiceName("my-grpc-client")) - - // Initialize the grpc server as normal, using the tracing interceptor. - s := grpc.NewServer(grpc.UnaryInterceptor(i)) - - // ... register your services - - // Start serving incoming connections. - if err := s.Serve(ln); err != nil { - log.Fatalf("failed to serve: %v", err) - } -} diff --git a/contrib/google.golang.org/grpc.v12/fixtures_test.pb.go b/contrib/google.golang.org/grpc.v12/fixtures_test.pb.go deleted file mode 100644 index 5567277baf..0000000000 --- a/contrib/google.golang.org/grpc.v12/fixtures_test.pb.go +++ /dev/null @@ -1,173 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016 Datadog, Inc. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: fixtures_test.proto - -/* -Package grpc is a generated protocol buffer package. - -It is generated from these files: - - fixtures_test.proto - -It has these top-level messages: - - FixtureRequest - FixtureReply -*/ -package grpc - -import ( - fmt "fmt" - - proto "github.com/golang/protobuf/proto" - - math "math" - - context "golang.org/x/net/context" - - grpc1 "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// The request message containing the user's name. -type FixtureRequest struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` -} - -func (m *FixtureRequest) Reset() { *m = FixtureRequest{} } -func (m *FixtureRequest) String() string { return proto.CompactTextString(m) } -func (*FixtureRequest) ProtoMessage() {} -func (*FixtureRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *FixtureRequest) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -// The response message containing the greetings -type FixtureReply struct { - Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` -} - -func (m *FixtureReply) Reset() { *m = FixtureReply{} } -func (m *FixtureReply) String() string { return proto.CompactTextString(m) } -func (*FixtureReply) ProtoMessage() {} -func (*FixtureReply) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -func (m *FixtureReply) GetMessage() string { - if m != nil { - return m.Message - } - return "" -} - -func init() { - proto.RegisterType((*FixtureRequest)(nil), "grpc.FixtureRequest") - proto.RegisterType((*FixtureReply)(nil), "grpc.FixtureReply") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc1.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc1.SupportPackageIsVersion4 - -// Client API for Fixture service - -type FixtureClient interface { - Ping(ctx context.Context, in *FixtureRequest, opts ...grpc1.CallOption) (*FixtureReply, error) -} - -type fixtureClient struct { - cc *grpc1.ClientConn -} - -func NewFixtureClient(cc *grpc1.ClientConn) FixtureClient { - return &fixtureClient{cc} -} - -func (c *fixtureClient) Ping(ctx context.Context, in *FixtureRequest, opts ...grpc1.CallOption) (*FixtureReply, error) { - out := new(FixtureReply) - err := grpc1.Invoke(ctx, "/grpc.Fixture/Ping", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for Fixture service - -type FixtureServer interface { - Ping(context.Context, *FixtureRequest) (*FixtureReply, error) -} - -func RegisterFixtureServer(s *grpc1.Server, srv FixtureServer) { - s.RegisterService(&_Fixture_serviceDesc, srv) -} - -func _Fixture_Ping_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc1.UnaryServerInterceptor) (interface{}, error) { - in := new(FixtureRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(FixtureServer).Ping(ctx, in) - } - info := &grpc1.UnaryServerInfo{ - Server: srv, - FullMethod: "/grpc.Fixture/Ping", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(FixtureServer).Ping(ctx, req.(*FixtureRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _Fixture_serviceDesc = grpc1.ServiceDesc{ - ServiceName: "grpc.Fixture", - HandlerType: (*FixtureServer)(nil), - Methods: []grpc1.MethodDesc{ - { - MethodName: "Ping", - Handler: _Fixture_Ping_Handler, - }, - }, - Streams: []grpc1.StreamDesc{}, - Metadata: "fixtures_test.proto", -} - -func init() { proto.RegisterFile("fixtures_test.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 177 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0x4e, 0xcb, 0xac, 0x28, - 0x29, 0x2d, 0x4a, 0x2d, 0x8e, 0x2f, 0x49, 0x2d, 0x2e, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, - 0x62, 0x49, 0x2f, 0x2a, 0x48, 0x56, 0x52, 0xe1, 0xe2, 0x73, 0x83, 0x48, 0x06, 0xa5, 0x16, 0x96, - 0xa6, 0x16, 0x97, 0x08, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6, 0xa6, 0x4a, 0x30, 0x2a, 0x30, 0x6a, - 0x70, 0x06, 0x81, 0xd9, 0x4a, 0x1a, 0x5c, 0x3c, 0x70, 0x55, 0x05, 0x39, 0x95, 0x42, 0x12, 0x5c, - 0xec, 0xb9, 0xa9, 0xc5, 0xc5, 0x89, 0xe9, 0x30, 0x65, 0x30, 0xae, 0x91, 0x2d, 0x17, 0x3b, 0x54, - 0xa5, 0x90, 0x11, 0x17, 0x4b, 0x40, 0x66, 0x5e, 0xba, 0x90, 0x88, 0x1e, 0xc8, 0x26, 0x3d, 0x54, - 0x6b, 0xa4, 0x84, 0xd0, 0x44, 0x0b, 0x72, 0x2a, 0x95, 0x18, 0x9c, 0x74, 0xb8, 0x24, 0x33, 0xf3, - 0x21, 0x32, 0xa9, 0x15, 0x89, 0xb9, 0x05, 0x39, 0xa9, 0xc5, 0x7a, 0x20, 0x37, 0x83, 0x44, 0x9c, - 0x78, 0x43, 0x52, 0x8b, 0x4b, 0xdc, 0x83, 0x02, 0x9c, 0x03, 0x40, 0x1e, 0x08, 0x60, 0x4c, 0x62, - 0x03, 0xfb, 0xc4, 0x18, 0x10, 0x00, 0x00, 0xff, 0xff, 0x18, 0x42, 0x90, 0x4d, 0xe0, 0x00, 0x00, - 0x00, -} diff --git a/contrib/google.golang.org/grpc.v12/fixtures_test.proto b/contrib/google.golang.org/grpc.v12/fixtures_test.proto deleted file mode 100644 index 15a8aa5cb3..0000000000 --- a/contrib/google.golang.org/grpc.v12/fixtures_test.proto +++ /dev/null @@ -1,21 +0,0 @@ -syntax = "proto3"; - -option java_multiple_files = true; -option java_package = "io.grpc.examples.testgrpc"; -option java_outer_classname = "TestGRPCProto"; - -package grpc; - -service Fixture { - rpc Ping (FixtureRequest) returns (FixtureReply) {} -} - -// The request message containing the user's name. -message FixtureRequest { - string name = 1; -} - -// The response message containing the greetings -message FixtureReply { - string message = 1; -} diff --git a/contrib/google.golang.org/grpc.v12/grpc.go b/contrib/google.golang.org/grpc.v12/grpc.go deleted file mode 100644 index ede5748332..0000000000 --- a/contrib/google.golang.org/grpc.v12/grpc.go +++ /dev/null @@ -1,133 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016 Datadog, Inc. - -//go:generate protoc -I . fixtures_test.proto --go_out=plugins=grpc:. - -// Package grpc provides functions to trace the google.golang.org/grpc package v1.2. -package grpc // import "gopkg.in/DataDog/dd-trace-go.v1/contrib/google.golang.org/grpc.v12" - -import ( - "net" - "strings" - - "gopkg.in/DataDog/dd-trace-go.v1/contrib/google.golang.org/internal/grpcutil" - "gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/options" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" - "gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig" - "gopkg.in/DataDog/dd-trace-go.v1/internal/log" - "gopkg.in/DataDog/dd-trace-go.v1/internal/telemetry" - - context "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/metadata" - "google.golang.org/grpc/peer" -) - -const componentName = "google.golang.org/grpc.v12" - -func init() { - telemetry.LoadIntegration(componentName) - tracer.MarkIntegrationImported("google.golang.org/grpc/v12") -} - -// UnaryServerInterceptor will trace requests to the given grpc server. -func UnaryServerInterceptor(opts ...InterceptorOption) grpc.UnaryServerInterceptor { - cfg := new(interceptorConfig) - serverDefaults(cfg) - for _, fn := range opts { - fn(cfg) - } - if cfg.serviceName == "" { - cfg.serviceName = "grpc.server" - if svc := globalconfig.ServiceName(); svc != "" { - cfg.serviceName = svc - } - } - - log.Debug("contrib/google.golang.org/grpc.v12: Configuring UnaryServerInterceptor: %#v", cfg) - return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - span, ctx := startServerSpanFromContext(ctx, info.FullMethod, cfg) - resp, err := handler(ctx, req) - span.Finish(tracer.WithError(err)) - return resp, err - } -} - -func startServerSpanFromContext(ctx context.Context, method string, cfg *interceptorConfig) (ddtrace.Span, context.Context) { - methodElements := strings.SplitN(strings.TrimPrefix(method, "/"), "/", 2) - extraOpts := []tracer.StartSpanOption{ - tracer.ServiceName(cfg.serviceName), - tracer.ResourceName(method), - tracer.Tag(tagMethod, method), - tracer.SpanType(ext.AppTypeRPC), - tracer.Measured(), - tracer.Tag(ext.Component, componentName), - tracer.Tag(ext.SpanKind, ext.SpanKindServer), - tracer.Tag(ext.RPCSystem, ext.RPCSystemGRPC), - tracer.Tag(ext.RPCService, methodElements[0]), - tracer.Tag(ext.GRPCFullMethod, method), - } - // copy opts in case the caller reuses the slice in parallel - // we will add the items in extraOpts - optsLocal := options.Copy(cfg.spanOpts...) - optsLocal = append(optsLocal, extraOpts...) - md, _ := metadata.FromIncomingContext(ctx) // nil is ok - if sctx, err := tracer.Extract(grpcutil.MDCarrier(md)); err == nil { - optsLocal = append(optsLocal, tracer.ChildOf(sctx)) - } - return tracer.StartSpanFromContext(ctx, cfg.spanName, optsLocal...) -} - -// UnaryClientInterceptor will add tracing to a grpc client. -func UnaryClientInterceptor(opts ...InterceptorOption) grpc.UnaryClientInterceptor { - cfg := new(interceptorConfig) - clientDefaults(cfg) - for _, fn := range opts { - fn(cfg) - } - log.Debug("contrib/google.golang.org/grpc.v12: Configuring UnaryClientInterceptor: %#v", cfg) - return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - var ( - span ddtrace.Span - p peer.Peer - ) - methodElements := strings.Split(strings.TrimPrefix(method, "/"), "/") - spanopts := cfg.spanOpts - spanopts = append(spanopts, - tracer.ServiceName(cfg.serviceName), - tracer.Tag(tagMethod, method), - tracer.SpanType(ext.AppTypeRPC), - tracer.Tag(ext.Component, componentName), - tracer.Tag(ext.SpanKind, ext.SpanKindClient), - tracer.Tag(ext.RPCSystem, ext.RPCSystemGRPC), - tracer.Tag(ext.RPCService, methodElements[0]), - tracer.Tag(ext.GRPCFullMethod, method), - ) - span, ctx = tracer.StartSpanFromContext(ctx, cfg.spanName, spanopts...) - md, ok := metadata.FromIncomingContext(ctx) - if !ok { - md = metadata.MD{} - } - _ = tracer.Inject(span.Context(), grpcutil.MDCarrier(md)) - ctx = metadata.NewOutgoingContext(ctx, md) - opts = append(opts, grpc.Peer(&p)) - err := invoker(ctx, method, req, reply, cc, opts...) - if p.Addr != nil { - addr := p.Addr.String() - host, port, err := net.SplitHostPort(addr) - if err == nil { - if host != "" { - span.SetTag(ext.TargetHost, host) - } - span.SetTag(ext.TargetPort, port) - } - } - span.SetTag(tagCode, grpc.Code(err).String()) - span.Finish(tracer.WithError(err)) - return err - } -} diff --git a/contrib/google.golang.org/grpc.v12/grpc_test.go b/contrib/google.golang.org/grpc.v12/grpc_test.go deleted file mode 100644 index d67c917a3d..0000000000 --- a/contrib/google.golang.org/grpc.v12/grpc_test.go +++ /dev/null @@ -1,417 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016 Datadog, Inc. - -package grpc - -import ( - "fmt" - "net" - "testing" - - "gopkg.in/DataDog/dd-trace-go.v1/contrib/internal/namingschematest" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/mocktracer" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" - "gopkg.in/DataDog/dd-trace-go.v1/internal/globalconfig" - - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - context "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" -) - -func TestClient(t *testing.T) { - assert := assert.New(t) - mt := mocktracer.Start() - defer mt.Stop() - - rig, err := newRig(true, true) - if err != nil { - t.Fatalf("error setting up rig: %s", err) - } - defer rig.Close() - client := rig.client - - span, ctx := tracer.StartSpanFromContext(context.Background(), "a", tracer.ServiceName("b"), tracer.ResourceName("c")) - resp, err := client.Ping(ctx, &FixtureRequest{Name: "pass"}) - assert.Nil(err) - span.Finish() - assert.Equal(resp.Message, "passed") - - spans := mt.FinishedSpans() - assert.Len(spans, 3) - - var serverSpan, clientSpan, rootSpan mocktracer.Span - - for _, s := range spans { - // order of traces in buffer is not garanteed - switch s.OperationName() { - case "grpc.server": - serverSpan = s - case "grpc.client": - clientSpan = s - case "a": - rootSpan = s - } - } - - assert.NotNil(serverSpan) - assert.NotNil(clientSpan) - assert.NotNil(rootSpan) - - assert.Equal(clientSpan.Tag(ext.TargetHost), "127.0.0.1") - assert.Equal(clientSpan.Tag(ext.TargetPort), rig.port) - assert.Equal(clientSpan.Tag(tagCode), codes.OK.String()) - assert.Equal(clientSpan.TraceID(), rootSpan.TraceID()) - assert.Equal(clientSpan.Tag(ext.Component), "google.golang.org/grpc.v12") - assert.Equal(clientSpan.Tag(ext.SpanKind), ext.SpanKindClient) - assert.Equal("grpc", clientSpan.Tag(ext.RPCSystem)) - assert.Equal("grpc.Fixture", clientSpan.Tag(ext.RPCService)) - assert.Equal("/grpc.Fixture/Ping", clientSpan.Tag(ext.GRPCFullMethod)) - - assert.Equal(serverSpan.Tag(ext.ServiceName), "grpc") - assert.Equal(serverSpan.Tag(ext.ResourceName), "/grpc.Fixture/Ping") - assert.Equal(serverSpan.TraceID(), rootSpan.TraceID()) - assert.Equal(serverSpan.Tag(ext.Component), "google.golang.org/grpc.v12") - assert.Equal(serverSpan.Tag(ext.SpanKind), ext.SpanKindServer) - assert.Equal("grpc", serverSpan.Tag(ext.RPCSystem)) - assert.Equal("grpc.Fixture", serverSpan.Tag(ext.RPCService)) - assert.Equal("/grpc.Fixture/Ping", serverSpan.Tag(ext.GRPCFullMethod)) -} - -func TestChild(t *testing.T) { - assert := assert.New(t) - mt := mocktracer.Start() - defer mt.Stop() - - rig, err := newRig(true, false) - if err != nil { - t.Fatalf("error setting up rig: %s", err) - } - defer rig.Close() - - client := rig.client - resp, err := client.Ping(context.Background(), &FixtureRequest{Name: "child"}) - assert.Nil(err) - assert.Equal(resp.Message, "child") - - spans := mt.FinishedSpans() - assert.Len(spans, 2) - - var serverSpan, clientSpan mocktracer.Span - - for _, s := range spans { - // order of traces in buffer is not garanteed - switch s.OperationName() { - case "grpc.server": - serverSpan = s - case "child": - clientSpan = s - } - } - - assert.NotNil(clientSpan) - assert.Nil(clientSpan.Tag(ext.Error)) - assert.Equal(clientSpan.Tag(ext.ServiceName), "grpc") - assert.Equal(clientSpan.Tag(ext.ResourceName), "child") - assert.True(clientSpan.FinishTime().Sub(clientSpan.StartTime()) > 0) - - assert.NotNil(serverSpan) - assert.Nil(serverSpan.Tag(ext.Error)) - assert.Equal(serverSpan.Tag(ext.ServiceName), "grpc") - assert.Equal(serverSpan.Tag(ext.ResourceName), "/grpc.Fixture/Ping") - assert.True(serverSpan.FinishTime().Sub(serverSpan.StartTime()) > 0) - assert.Equal(serverSpan.Tag(ext.Component), "google.golang.org/grpc.v12") - assert.Equal(serverSpan.Tag(ext.SpanKind), ext.SpanKindServer) - assert.Equal("grpc", serverSpan.Tag(ext.RPCSystem)) - assert.Equal("grpc.Fixture", serverSpan.Tag(ext.RPCService)) - assert.Equal("/grpc.Fixture/Ping", serverSpan.Tag(ext.GRPCFullMethod)) -} - -func TestPass(t *testing.T) { - assert := assert.New(t) - mt := mocktracer.Start() - defer mt.Stop() - - rig, err := newRig(true, false) - if err != nil { - t.Fatalf("error setting up rig: %s", err) - } - defer rig.Close() - - client := rig.client - resp, err := client.Ping(context.Background(), &FixtureRequest{Name: "pass"}) - assert.Nil(err) - assert.Equal(resp.Message, "passed") - - spans := mt.FinishedSpans() - assert.Len(spans, 1) - - s := spans[0] - assert.Nil(s.Tag(ext.Error)) - assert.Equal(s.OperationName(), "grpc.server") - assert.Equal(s.Tag(ext.ServiceName), "grpc") - assert.Equal(s.Tag(ext.ResourceName), "/grpc.Fixture/Ping") - assert.Equal(s.Tag(ext.SpanType), ext.AppTypeRPC) - assert.True(s.FinishTime().Sub(s.StartTime()) > 0) - assert.Equal(s.Tag(ext.Component), "google.golang.org/grpc.v12") - assert.Equal(s.Tag(ext.SpanKind), ext.SpanKindServer) - assert.Equal(s.Tag(ext.RPCService), "grpc.Fixture") -} - -// fixtureServer a dummy implemenation of our grpc fixtureServer. -type fixtureServer struct{} - -func (s *fixtureServer) Ping(ctx context.Context, in *FixtureRequest) (*FixtureReply, error) { - switch { - case in.Name == "child": - span, _ := tracer.StartSpanFromContext(ctx, "child") - span.Finish() - return &FixtureReply{Message: "child"}, nil - case in.Name == "disabled": - if _, ok := tracer.SpanFromContext(ctx); ok { - panic("should be disabled") - } - return &FixtureReply{Message: "disabled"}, nil - } - return &FixtureReply{Message: "passed"}, nil -} - -// ensure it's a fixtureServer -var _ FixtureServer = &fixtureServer{} - -// rig contains all of the servers and connections we'd need for a -// grpc integration test -type rig struct { - server *grpc.Server - port string - listener net.Listener - conn *grpc.ClientConn - client FixtureClient -} - -func (r *rig) Close() { - r.server.Stop() - r.conn.Close() - r.listener.Close() -} - -func newRig(traceServer, traceClient bool) (*rig, error) { - return newRigWithOpts(traceServer, traceClient, WithServiceName("grpc")) -} - -func newRigWithOpts(traceServer, traceClient bool, iopts ...InterceptorOption) (*rig, error) { - var serverOpts []grpc.ServerOption - if traceServer { - serverOpts = append(serverOpts, grpc.UnaryInterceptor(UnaryServerInterceptor(iopts...))) - } - server := grpc.NewServer(serverOpts...) - - RegisterFixtureServer(server, new(fixtureServer)) - - li, err := net.Listen("tcp", "127.0.0.1:0") - if err != nil { - return nil, err - } - _, port, _ := net.SplitHostPort(li.Addr().String()) - // start our test fixtureServer. - go server.Serve(li) - - opts := []grpc.DialOption{grpc.WithInsecure()} - if traceClient { - opts = append(opts, grpc.WithUnaryInterceptor(UnaryClientInterceptor(iopts...))) - } - conn, err := grpc.Dial(li.Addr().String(), opts...) - if err != nil { - return nil, fmt.Errorf("error dialing: %s", err) - } - return &rig{ - listener: li, - port: port, - server: server, - conn: conn, - client: NewFixtureClient(conn), - }, err -} - -func TestAnalyticsSettings(t *testing.T) { - assertRate := func(t *testing.T, mt mocktracer.Tracer, rate interface{}, opts ...InterceptorOption) { - rig, err := newRigWithOpts(true, true, opts...) - if err != nil { - t.Fatalf("error setting up rig: %s", err) - } - defer rig.Close() - - client := rig.client - resp, err := client.Ping(context.Background(), &FixtureRequest{Name: "pass"}) - assert.Nil(t, err) - assert.Equal(t, resp.Message, "passed") - - spans := mt.FinishedSpans() - assert.Len(t, spans, 2) - - var serverSpan, clientSpan mocktracer.Span - - for _, s := range spans { - // order of traces in buffer is not garanteed - switch s.OperationName() { - case "grpc.server": - serverSpan = s - case "grpc.client": - clientSpan = s - } - } - - assert.Equal(t, rate, clientSpan.Tag(ext.EventSampleRate)) - assert.Equal(t, rate, serverSpan.Tag(ext.EventSampleRate)) - } - - t.Run("defaults", func(t *testing.T) { - mt := mocktracer.Start() - defer mt.Stop() - - assertRate(t, mt, nil) - }) - - t.Run("global", func(t *testing.T) { - t.Skip("global flag disabled") - mt := mocktracer.Start() - defer mt.Stop() - - rate := globalconfig.AnalyticsRate() - defer globalconfig.SetAnalyticsRate(rate) - globalconfig.SetAnalyticsRate(0.4) - - assertRate(t, mt, 0.4) - }) - - t.Run("enabled", func(t *testing.T) { - mt := mocktracer.Start() - defer mt.Stop() - - assertRate(t, mt, 1.0, WithAnalytics(true)) - }) - - t.Run("disabled", func(t *testing.T) { - mt := mocktracer.Start() - defer mt.Stop() - - assertRate(t, mt, nil, WithAnalytics(false)) - }) - - t.Run("override", func(t *testing.T) { - mt := mocktracer.Start() - defer mt.Stop() - - rate := globalconfig.AnalyticsRate() - defer globalconfig.SetAnalyticsRate(rate) - globalconfig.SetAnalyticsRate(0.4) - - assertRate(t, mt, 0.23, WithAnalyticsRate(0.23)) - }) - - t.Run("spanOpts", func(t *testing.T) { - mt := mocktracer.Start() - defer mt.Stop() - - assertRate(t, mt, 0.23, WithAnalyticsRate(0.33), WithSpanOptions(tracer.AnalyticsRate(0.23))) - }) -} - -func TestSpanOpts(t *testing.T) { - assert := assert.New(t) - mt := mocktracer.Start() - defer mt.Stop() - - rig, err := newRigWithOpts(true, true, WithSpanOptions(tracer.Tag("foo", "bar"))) - if err != nil { - t.Fatalf("error setting up rig: %s", err) - } - defer rig.Close() - client := rig.client - - resp, err := client.Ping(context.Background(), &FixtureRequest{Name: "pass"}) - assert.Nil(err) - assert.Equal(resp.Message, "passed") - - spans := mt.FinishedSpans() - assert.Len(spans, 2) - - for _, s := range spans { - assert.Equal(s.Tags()["foo"], "bar") - } -} - -func TestServerNamingSchema(t *testing.T) { - genSpans := namingschematest.GenSpansFn(func(t *testing.T, serviceOverride string) []mocktracer.Span { - var opts []InterceptorOption - if serviceOverride != "" { - opts = append(opts, WithServiceName(serviceOverride)) - } - mt := mocktracer.Start() - defer mt.Stop() - - rig, err := newRigWithOpts(true, false, opts...) - require.NoError(t, err) - defer rig.Close() - _, err = rig.client.Ping(context.Background(), &FixtureRequest{Name: "pass"}) - require.NoError(t, err) - - return mt.FinishedSpans() - }) - assertOpV0 := func(t *testing.T, spans []mocktracer.Span) { - require.Len(t, spans, 1) - assert.Equal(t, "grpc.server", spans[0].OperationName()) - } - assertOpV1 := func(t *testing.T, spans []mocktracer.Span) { - require.Len(t, spans, 1) - assert.Equal(t, "grpc.server.request", spans[0].OperationName()) - } - ddService := namingschematest.TestDDService - serviceOverride := namingschematest.TestServiceOverride - wantServiceNameV0 := namingschematest.ServiceNameAssertions{ - WithDefaults: []string{"grpc.server"}, - WithDDService: []string{ddService}, - WithDDServiceAndOverride: []string{serviceOverride}, - } - t.Run("ServiceName", namingschematest.NewServiceNameTest(genSpans, wantServiceNameV0)) - t.Run("SpanName", namingschematest.NewSpanNameTest(genSpans, assertOpV0, assertOpV1)) -} - -func TestClientNamingSchema(t *testing.T) { - genSpans := namingschematest.GenSpansFn(func(t *testing.T, serviceOverride string) []mocktracer.Span { - var opts []InterceptorOption - if serviceOverride != "" { - opts = append(opts, WithServiceName(serviceOverride)) - } - mt := mocktracer.Start() - defer mt.Stop() - - rig, err := newRigWithOpts(false, true, opts...) - require.NoError(t, err) - defer rig.Close() - _, err = rig.client.Ping(context.Background(), &FixtureRequest{Name: "pass"}) - require.NoError(t, err) - - return mt.FinishedSpans() - }) - assertOpV0 := func(t *testing.T, spans []mocktracer.Span) { - require.Len(t, spans, 1) - assert.Equal(t, "grpc.client", spans[0].OperationName()) - } - assertOpV1 := func(t *testing.T, spans []mocktracer.Span) { - require.Len(t, spans, 1) - assert.Equal(t, "grpc.client.request", spans[0].OperationName()) - } - serviceOverride := namingschematest.TestServiceOverride - wantServiceNameV0 := namingschematest.ServiceNameAssertions{ - WithDefaults: []string{"grpc.client"}, - WithDDService: []string{"grpc.client"}, - WithDDServiceAndOverride: []string{serviceOverride}, - } - t.Run("ServiceName", namingschematest.NewServiceNameTest(genSpans, wantServiceNameV0)) - t.Run("SpanName", namingschematest.NewSpanNameTest(genSpans, assertOpV0, assertOpV1)) -} diff --git a/contrib/google.golang.org/grpc.v12/option.go b/contrib/google.golang.org/grpc.v12/option.go deleted file mode 100644 index f367f38d21..0000000000 --- a/contrib/google.golang.org/grpc.v12/option.go +++ /dev/null @@ -1,82 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016 Datadog, Inc. - -package grpc - -import ( - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" - "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" - "gopkg.in/DataDog/dd-trace-go.v1/internal" - "gopkg.in/DataDog/dd-trace-go.v1/internal/namingschema" -) - -const ( - defaultClientServiceName = "grpc.client" - defaultServerServiceName = "grpc.server" -) - -type interceptorConfig struct { - serviceName string - spanName string - spanOpts []ddtrace.StartSpanOption -} - -// InterceptorOption represents an option that can be passed to the grpc unary -// client and server interceptors. -type InterceptorOption func(*interceptorConfig) - -func defaults(cfg *interceptorConfig) { - // cfg.serviceName default set in interceptor - // cfg.spanOpts = append(cfg.spanOpts, tracer.AnalyticsRate(globalconfig.AnalyticsRate())) - if internal.BoolEnv("DD_TRACE_GRPC_ANALYTICS_ENABLED", false) { - cfg.spanOpts = append(cfg.spanOpts, tracer.AnalyticsRate(1.0)) - } -} - -func clientDefaults(cfg *interceptorConfig) { - cfg.serviceName = namingschema.ServiceNameOverrideV0(defaultClientServiceName, defaultClientServiceName) - cfg.spanName = namingschema.OpName(namingschema.GRPCClient) - defaults(cfg) -} - -func serverDefaults(cfg *interceptorConfig) { - cfg.serviceName = namingschema.ServiceName(defaultServerServiceName) - cfg.spanName = namingschema.OpName(namingschema.GRPCServer) - defaults(cfg) -} - -// WithServiceName sets the given service name for the intercepted client. -func WithServiceName(name string) InterceptorOption { - return func(cfg *interceptorConfig) { - cfg.serviceName = name - } -} - -// WithAnalytics enables Trace Analytics for all started spans. -func WithAnalytics(on bool) InterceptorOption { - return func(cfg *interceptorConfig) { - if on { - WithSpanOptions(tracer.AnalyticsRate(1.0))(cfg) - } - } -} - -// WithAnalyticsRate sets the sampling rate for Trace Analytics events -// correlated to started spans. -func WithAnalyticsRate(rate float64) InterceptorOption { - return func(cfg *interceptorConfig) { - if rate >= 0.0 && rate <= 1.0 { - WithSpanOptions(tracer.AnalyticsRate(rate))(cfg) - } - } -} - -// WithSpanOptions defines a set of additional ddtrace.StartSpanOption to be added -// to spans started by the integration. -func WithSpanOptions(opts ...ddtrace.StartSpanOption) InterceptorOption { - return func(cfg *interceptorConfig) { - cfg.spanOpts = append(cfg.spanOpts, opts...) - } -} diff --git a/contrib/google.golang.org/grpc.v12/tags.go b/contrib/google.golang.org/grpc.v12/tags.go deleted file mode 100644 index 6952e05ade..0000000000 --- a/contrib/google.golang.org/grpc.v12/tags.go +++ /dev/null @@ -1,12 +0,0 @@ -// Unless explicitly stated otherwise all files in this repository are licensed -// under the Apache License Version 2.0. -// This product includes software developed at Datadog (https://www.datadoghq.com/). -// Copyright 2016 Datadog, Inc. - -package grpc - -// Tags used for gRPC -const ( - tagMethod = "grpc.method" - tagCode = "grpc.code" -) diff --git a/ddtrace/tracer/option.go b/ddtrace/tracer/option.go index 55041e943c..9175c20efe 100644 --- a/ddtrace/tracer/option.go +++ b/ddtrace/tracer/option.go @@ -15,7 +15,6 @@ import ( "net/url" "os" "path/filepath" - "regexp" "runtime" "runtime/debug" "strconv" @@ -23,6 +22,7 @@ import ( "time" "golang.org/x/mod/semver" + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace" "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/ext" "gopkg.in/DataDog/dd-trace-go.v1/internal" @@ -69,7 +69,6 @@ var contribIntegrations = map[string]struct { "github.com/gomodule/redigo": {"Redigo", false}, "google.golang.org/api": {"Google API", false}, "google.golang.org/grpc": {"gRPC", false}, - "google.golang.org/grpc/v12": {"gRPC v12", false}, "gopkg.in/jinzhu/gorm.v1": {"Gorm (gopkg)", false}, "github.com/gorilla/mux": {"Gorilla Mux", false}, "gorm.io/gorm.v1": {"Gorm v1", false}, @@ -697,23 +696,6 @@ func (c *config) loadContribIntegrations(deps []*debug.Module) { } for _, d := range deps { p := d.Path - // special use case, since gRPC does not update version number - if p == "google.golang.org/grpc" { - re := regexp.MustCompile(`v(\d.\d)\d*`) - match := re.FindStringSubmatch(d.Version) - if match == nil { - log.Warn("Unable to parse version of GRPC %v", d.Version) - continue - } - ver, err := strconv.ParseFloat(match[1], 32) - if err != nil { - log.Warn("Unable to parse version of GRPC %v as a float", d.Version) - continue - } - if ver <= 1.2 { - p = p + "/v12" - } - } s, ok := contribIntegrations[p] if !ok { continue diff --git a/ddtrace/tracer/option_test.go b/ddtrace/tracer/option_test.go index 56d1bc4fb5..d4259e9f5c 100644 --- a/ddtrace/tracer/option_test.go +++ b/ddtrace/tracer/option_test.go @@ -258,7 +258,7 @@ func TestAgentIntegration(t *testing.T) { defer clearIntegrationsForTests() cfg.loadContribIntegrations(nil) - assert.Equal(t, 57, len(cfg.integrations)) + assert.Equal(t, 56, len(cfg.integrations)) for integrationName, v := range cfg.integrations { assert.False(t, v.Instrumented, "integrationName=%s", integrationName) } @@ -303,39 +303,6 @@ func TestAgentIntegration(t *testing.T) { cfg.loadContribIntegrations(deps) assert.True(t, cfg.integrations["gRPC"].Available) assert.Equal(t, cfg.integrations["gRPC"].Version, "v1.520") - assert.False(t, cfg.integrations["gRPC v12"].Available) - }) - - t.Run("grpc v12", func(t *testing.T) { - cfg := newConfig() - defer clearIntegrationsForTests() - - d := debug.Module{ - Path: "google.golang.org/grpc", - Version: "v1.10", - } - - deps := []*debug.Module{&d} - cfg.loadContribIntegrations(deps) - assert.True(t, cfg.integrations["gRPC v12"].Available) - assert.Equal(t, cfg.integrations["gRPC v12"].Version, "v1.10") - assert.False(t, cfg.integrations["gRPC"].Available) - }) - - t.Run("grpc bad", func(t *testing.T) { - cfg := newConfig() - defer clearIntegrationsForTests() - - d := debug.Module{ - Path: "google.golang.org/grpc", - Version: "v10.10", - } - - deps := []*debug.Module{&d} - cfg.loadContribIntegrations(deps) - assert.False(t, cfg.integrations["gRPC v12"].Available) - assert.Equal(t, cfg.integrations["gRPC v12"].Version, "") - assert.False(t, cfg.integrations["gRPC"].Available) }) // ensure we clean up global state diff --git a/test.sh b/test.sh index 2ecd68209b..5b63e08b55 100755 --- a/test.sh +++ b/test.sh @@ -111,6 +111,6 @@ if [[ "$contrib" != "" ]]; then sleep $sleeptime fi - PACKAGE_NAMES=$(go list ./contrib/... | grep -v -e grpc.v12 -e google.golang.org/api) + PACKAGE_NAMES=$(go list ./contrib/... | grep -v -e google.golang.org/api) nice -n20 gotestsum --junitfile ./gotestsum-report.xml -- -race -v -coverprofile=contrib_coverage.txt -covermode=atomic $PACKAGE_NAMES fi From 84620ff10d4342697717e474d453e88edffc261a Mon Sep 17 00:00:00 2001 From: Andrew Glaude Date: Mon, 19 Aug 2024 11:30:19 -0400 Subject: [PATCH 2/2] go mod tidy --- go.mod | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index c3f79c3e4f..9aef54a508 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,6 @@ require ( github.com/go-sql-driver/mysql v1.6.0 github.com/gocql/gocql v1.6.0 github.com/gofiber/fiber/v2 v2.52.5 - github.com/golang/protobuf v1.5.3 github.com/gomodule/redigo v1.8.9 github.com/google/pprof v0.0.0-20230817174616-7a8ec2ada47b github.com/google/uuid v1.5.0 @@ -97,7 +96,6 @@ require ( go.opentelemetry.io/otel/trace v1.20.0 go.uber.org/atomic v1.11.0 golang.org/x/mod v0.14.0 - golang.org/x/net v0.23.0 golang.org/x/oauth2 v0.9.0 golang.org/x/sys v0.20.0 golang.org/x/time v0.3.0 @@ -172,6 +170,7 @@ require ( github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -260,6 +259,7 @@ require ( golang.org/x/arch v0.4.0 // indirect golang.org/x/crypto v0.21.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/net v0.23.0 // indirect golang.org/x/sync v0.5.0 // indirect golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect