diff --git a/.circleci/config.yml b/.circleci/config.yml index bae0a7f30f..d991eb8742 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,48 +1,15 @@ version: 2.1 -plain-go114: &plain-go114 +plain-go114: &plain-go116 working_directory: /home/circleci/dd-trace-go.v1 docker: - - image: circleci/golang:1.14 + - image: circleci/golang:1.16 environment: GOPATH: "/home/circleci/go" jobs: - go1_12-build: - # Validate that the core builds with go1.12 - parameters: - build_tags: - description: "go build tags used to compile" - default: "" - type: string - goflags: - description: "extra goflags to pass to go test" - default: "" - type: string - docker: - - image: circleci/golang:1.12 - environment: - GOPATH: "/home/circleci/go" - working_directory: /home/circleci/dd-trace-go.v1 - environment: - # Go 1.12 doesn't have the proxy turned on by default but we need it to - # fetch some dependencies that aren't handled by fetching directly - # (such as github.com/go-chi/chi/v4@v4.0.0-rc1) - GOPROXY: "https://proxy.golang.org" - steps: - - checkout - - - run: - name: build - command: | - # Fixes fatal: unable to access 'https://gopkg.in/yaml.v3/': server certificate verification failed. CAfile: none CRLfile: none - # See https://github.com/DataDog/dd-trace-go/pull/1029 - sudo apt update && sudo apt install ca-certificates libgnutls30 -y - - go build -v -tags "<< parameters.build_tags >>" ./ddtrace/... ./profiler/... ./internal/appsec/... - metadata: - <<: *plain-go114 + <<: *plain-go116 steps: - checkout @@ -79,7 +46,7 @@ jobs: go run checkcopyright.go lint: - <<: *plain-go114 + <<: *plain-go116 steps: - checkout @@ -123,7 +90,7 @@ jobs: environment: # environment variables for the build itself TEST_RESULTS: /tmp/test-results # path to where test results will be saved DD_APPSEC_WAF_TIMEOUT: 1s - <<: *plain-go114 + <<: *plain-go116 steps: - checkout @@ -171,7 +138,7 @@ jobs: DD_APPSEC_WAF_TIMEOUT: 1s working_directory: /home/circleci/dd-trace-go.v1 docker: - - image: circleci/golang:1.14 + - image: circleci/golang:1.16 environment: GOPATH: "/home/circleci/go" - image: cassandra:3.7 @@ -334,6 +301,7 @@ jobs: name: Testing outlier google.golang.org/api command: | go get google.golang.org/grpc@v1.29.0 # https://github.com/grpc/grpc-go/issues/3726 + 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/... - run: @@ -368,10 +336,6 @@ workflows: version: 2 build-and-test: jobs: - - go1_12-build: - matrix: - parameters: - build_tags: [ "", "appsec" ] - metadata - lint - test-core: @@ -391,11 +355,6 @@ workflows: only: - v1 jobs: - - go1_12-build: - matrix: - parameters: - build_tags: [ "", "appsec" ] - goflags: [ "-race" ] - test-core: matrix: parameters: diff --git a/README.md b/README.md index e460edaef5..7ad9abd48a 100644 --- a/README.md +++ b/README.md @@ -19,14 +19,53 @@ go get gopkg.in/DataDog/dd-trace-go.v1/contrib/gorilla/mux If you installed more packages than you intended, you can use `go mod tidy` to remove any unused packages. -Requires: +### Documentation + + - [API](https://pkg.go.dev/gopkg.in/DataDog/dd-trace-go.v1/ddtrace) + - [Tracing Go Applications](https://docs.datadoghq.com/tracing/setup/go/) + - [Continuous Go Profiler](https://docs.datadoghq.com/tracing/profiler/enabling/go). + - If you are migrating from an older version of the tracer (e.g. 0.6.x) you may also find the [migration document](MIGRATING.md) we've put together helpful. + +### Support Policy + +Datadog APM for Go is built upon dependencies defined in specific versions of the host operating system, Go releases, and the Datadog Agent/API. For Go the two latest releases are [GA](#support-ga) supported and the version before that is in [Maintenance](#support-maintenance). We do make efforts to support older releases, but generally these releases are considered [Legacy](#support-legacy). This library only officially supports [first class ports](https://github.com/golang/go/wiki/PortingPolicy#first-class-ports) of Go. + +| **Level** | **Support provided** | +|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| General Availability (GA) | Full implementation of all features. Full support for new features, bug & security fixes. | +| Maintenance | Full implementation of existing features. May receive new features. Support for bug & security fixes only. | +| Legacy | Legacy implementation. May have limited function, but no maintenance provided. [Contact our customer support team for special requests.](https://www.datadoghq.com/support/) | + +### Supported Versions + +| **Go Version** | **Support level** | +|----------------|-------------------------------------| +| 1.18 | [GA](#support-ga) | +| 1.17 | [GA](#support-ga) | +| 1.16 | [Maintenance](#support-maintenance) | -* Go >= 1.12 * Datadog's Trace Agent >= 5.21.1 -### Documentation +#### Package Versioning + +A **Minor** version change will be released whenever a new version of Go is released. At that time the newest version of Go is added to [GA](#support-ga), the second oldest supported version moved to [Maintenance](#support-maintenance) and the oldest previously supported version dropped to [Legacy](#support-legacy). +**For example**: +For a dd-trace-go version 1.37.* + +| Go Version | Support | +|------------|-------------------------------------| +| 1.18 | [GA](#support-ga) | +| 1.17 | [GA](#support-ga) | +| 1.16 | [Maintenance](#support-maintenance) | + +Then after Go 1.19 is released there will be a new dd-trace-go version 1.38.0 with support: -The API is documented on [godoc](https://godoc.org/gopkg.in/DataDog/dd-trace-go.v1/ddtrace) as well as Datadog's official documentation for [Tracing Go Applications](https://docs.datadoghq.com/tracing/setup/go/) and the [Continuous Go Profiler](https://docs.datadoghq.com/tracing/profiler/enabling/go). If you are migrating from an older version of the tracer (e.g. 0.6.x) you may also find the [migration document](MIGRATING.md) we've put together helpful. +| Go Version | Support | +|------------|-------------------------------------| +| 1.19 | [GA](#support-ga) | +| 1.18 | [GA](#support-ga) | +| 1.17 | [Maintenance](#support-maintenance) | +| 1.16 | [Legacy](#support-legacy) | ### Contributing diff --git a/contrib/sirupsen/logrus/example_test.go b/contrib/sirupsen/logrus/example_test.go new file mode 100644 index 0000000000..4cafbcaebf --- /dev/null +++ b/contrib/sirupsen/logrus/example_test.go @@ -0,0 +1,34 @@ +// 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 2022 Datadog, Inc. + +package logrus + +import ( + "context" + "os" + "time" + + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" + + "github.com/sirupsen/logrus" +) + +func ExampleHook() { + // Ensure your tracer is started and stopped + // Setup logrus, do this once at the beginning of your program + logrus.SetFormatter(&logrus.JSONFormatter{}) + logrus.AddHook(&DDContextLogHook{}) + logrus.SetOutput(os.Stdout) + + span, sctx := tracer.StartSpanFromContext(context.Background(), "mySpan") + defer span.Finish() + + // Pass the current span context to the logger (Time is set for consistency in output here) + cLog := logrus.WithContext(sctx).WithTime(time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)) + // Log as desired using the context-aware logger + cLog.Info("Completed some work!") + // Output: + // {"dd.span_id":0,"dd.trace_id":0,"level":"info","msg":"Completed some work!","time":"2000-01-01T01:01:01Z"} +} diff --git a/contrib/sirupsen/logrus/logrus.go b/contrib/sirupsen/logrus/logrus.go new file mode 100644 index 0000000000..e3745b0014 --- /dev/null +++ b/contrib/sirupsen/logrus/logrus.go @@ -0,0 +1,32 @@ +// 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 2022 Datadog, Inc. + +// Package logrus provides a log/span correlation hook for the sirupsen/logrus package (https://github.com/sirupsen/logrus). +package logrus + +import ( + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" + + "github.com/sirupsen/logrus" +) + +// DDContextLogHook ensures that any span in the log context is correlated to log output. +type DDContextLogHook struct{} + +// Levels implements logrus.Hook interface, this hook applies to all defined levels +func (d *DDContextLogHook) Levels() []logrus.Level { + return []logrus.Level{logrus.PanicLevel, logrus.FatalLevel, logrus.ErrorLevel, logrus.WarnLevel, logrus.InfoLevel, logrus.DebugLevel, logrus.TraceLevel} +} + +// Fire implements logrus.Hook interface, attaches trace and span details found in entry context +func (d *DDContextLogHook) Fire(e *logrus.Entry) error { + span, found := tracer.SpanFromContext(e.Context) + if !found { + return nil + } + e.Data["dd.trace_id"] = span.Context().TraceID() + e.Data["dd.span_id"] = span.Context().SpanID() + return nil +} diff --git a/contrib/sirupsen/logrus/logrus_test.go b/contrib/sirupsen/logrus/logrus_test.go new file mode 100644 index 0000000000..be23324b4d --- /dev/null +++ b/contrib/sirupsen/logrus/logrus_test.go @@ -0,0 +1,31 @@ +// 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 2022 Datadog, Inc. + +package logrus + +import ( + "context" + "testing" + + "gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer" + + "github.com/sirupsen/logrus" + "github.com/stretchr/testify/assert" +) + +func TestFire(t *testing.T) { + tracer.Start() + defer tracer.Stop() + _, sctx := tracer.StartSpanFromContext(context.Background(), "testSpan", tracer.WithSpanID(1234)) + + hook := &DDContextLogHook{} + e := logrus.NewEntry(logrus.New()) + e.Context = sctx + err := hook.Fire(e) + + assert.NoError(t, err) + assert.Equal(t, uint64(1234), e.Data["dd.trace_id"]) + assert.Equal(t, uint64(1234), e.Data["dd.span_id"]) +} diff --git a/ddtrace/tracer/tracer.go b/ddtrace/tracer/tracer.go index 37cfb8d5d7..041322ad61 100644 --- a/ddtrace/tracer/tracer.go +++ b/ddtrace/tracer/tracer.go @@ -9,6 +9,7 @@ import ( gocontext "context" "os" "runtime/pprof" + rt "runtime/trace" "strconv" "sync" "time" @@ -544,3 +545,11 @@ func (t *tracer) sample(span *span) { } t.prioritySampling.apply(span) } + +func startExecutionTracerTask(name string) func() { + if !rt.IsEnabled() { + return func() {} + } + _, task := rt.NewTask(gocontext.TODO(), name) + return task.End +} diff --git a/ddtrace/tracer/tracer_go11.go b/ddtrace/tracer/tracer_go11.go deleted file mode 100644 index ac8cd8cc87..0000000000 --- a/ddtrace/tracer/tracer_go11.go +++ /dev/null @@ -1,21 +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. - -// +build go1.11 - -package tracer - -import ( - "context" - t "runtime/trace" -) - -func startExecutionTracerTask(name string) func() { - if !t.IsEnabled() { - return func() {} - } - _, task := t.NewTask(context.TODO(), name) - return task.End -} diff --git a/ddtrace/tracer/tracer_nongo11.go b/ddtrace/tracer/tracer_nongo11.go deleted file mode 100644 index ccf8b9f98e..0000000000 --- a/ddtrace/tracer/tracer_nongo11.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. - -// +build !go1.11 - -package tracer - -func startExecutionTracerTask(name string) func() { - return func() {} -} diff --git a/go.mod b/go.mod index 6e29ed8854..4abae052dc 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module gopkg.in/DataDog/dd-trace-go.v1 -go 1.12 +go 1.16 require ( cloud.google.com/go/pubsub v1.4.0 @@ -74,7 +74,7 @@ require ( github.com/philhofer/fwd v1.1.1 // indirect github.com/pierrec/lz4 v2.5.2+incompatible // indirect github.com/segmentio/kafka-go v0.4.29 - github.com/stretchr/objx v0.2.0 // indirect + github.com/sirupsen/logrus v1.7.0 github.com/stretchr/testify v1.7.0 github.com/syndtr/goleveldb v1.0.0 github.com/tidwall/btree v1.1.0 // indirect diff --git a/go.sum b/go.sum index d04f1bf9a0..755b547091 100644 --- a/go.sum +++ b/go.sum @@ -3,7 +3,6 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1 h1:lRi0CHyU+ytlvylOlFKKq0af6JncuyoRh1J+QJBqQx0= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= @@ -26,7 +25,6 @@ cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1 cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1 h1:ukjixP1wl0LpnZ6LWtZJ0mX5tBmjp1f8Sqer8Z2OMUU= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.4.0 h1:76oR7VBOkL7ivoIrFKyW0k7YDCRelrlxktIzQiIUGgg= cloud.google.com/go/pubsub v1.4.0/go.mod h1:LFrqilwgdw4X2cJS9ALgzYmMu+ULyrUN6IHV3CPK4TM= @@ -74,7 +72,6 @@ github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMx github.com/andybalholm/brotli v1.0.2 h1:JKnhI/XQ75uFBTiuzXpzFrUriDPiZjlOSzh6wXogP0E= github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da h1:8GUt8eRujhVEGZFFEjBj46YV4rDjvGrNxb0KMWYkL2I= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.0 h1:B7AQgHi8QSEi4uHu7Sbsga+IJDU+CENgjxoo81vDUqU= github.com/armon/go-metrics v0.3.0/go.mod h1:zXjbSimjXTd7vOpY8B0/2LpvNvDoXBuplAD+gJD3GYs= @@ -107,9 +104,7 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4Yn github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= -github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -161,7 +156,6 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= @@ -169,7 +163,6 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -293,15 +286,12 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -316,7 +306,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -360,22 +349,18 @@ github.com/hashicorp/consul/api v1.0.0 h1:9GEZpB5zZ2Vm+rQ0t0JL/Ey2iaXbmIN1evA/LU github.com/hashicorp/consul/api v1.0.0/go.mod h1:mbFwfRxOTDHZpT3iUsMAFcLNoVm6Xbe1xZ6KiSm8FY0= github.com/hashicorp/consul/internal v0.1.0 h1:jNHZgWe9hbMO05/LRoJYHp/wWNiBwz+Ce6YlppiAEo8= github.com/hashicorp/consul/internal v0.1.0/go.mod h1:zi9bMZYbiPHyAjgBWo7kCUcy5l2NrTdrkVupCc7Oo6c= -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0 h1:d4QkX8FRTYaKaCZBoXYY8zJX2BXjWxurN/GA2tkrmZM= github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= github.com/hashicorp/go-hclog v0.16.2 h1:K4ev2ib4LdQETX5cSZBG0DVLk1jwGqSPXBjdah3veNs= github.com/hashicorp/go-hclog v0.16.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -383,7 +368,6 @@ github.com/hashicorp/go-kms-wrapping/entropy v0.1.0/go.mod h1:d1g9WGtAunDNpek8jU github.com/hashicorp/go-msgpack v0.5.3 h1:zKjpN5BK/P5lMYrLmBHdBULWbJ0XpYR+7NGzqkZzoD4= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0 h1:B9UzwGQJehnUY1yNrnwREHc3fGbC2xefo8g4TbElacI= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= @@ -405,7 +389,6 @@ github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= @@ -423,7 +406,6 @@ github.com/hashicorp/vault/api v1.1.0 h1:QcxC7FuqEl0sZaIjcXB/kNEeBa0DH5z57qbWBvZ github.com/hashicorp/vault/api v1.1.0/go.mod h1:R3Umvhlxi2TN7Ex2hzOowyeNb+SfbVWI973N+ctaFMk= github.com/hashicorp/vault/sdk v0.1.14-0.20200519221838-e0cfd64bc267 h1:e1ok06zGrWJW91rzRroyl5nRNqraaBe4d5hiKcVZuHM= github.com/hashicorp/vault/sdk v0.1.14-0.20200519221838-e0cfd64bc267/go.mod h1:WX57W2PwkrOPQ6rVQk+dy5/htHIaB4aBM70EwKThu10= -github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -529,7 +511,6 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.12.2/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.4 h1:0zhec2I8zGnjWcKyLl6i3gPqKANCCn5e9xmviEEeX6s= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw= github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -547,7 +528,6 @@ github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8 github.com/labstack/echo v3.3.10+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= github.com/labstack/echo/v4 v4.2.0 h1:jkCSsjXmBmapVXF6U4BrSz/cgofWM0CU3Q74wQvXkIc= github.com/labstack/echo/v4 v4.2.0/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= -github.com/labstack/gommon v0.3.0 h1:JEeO0bvc78PKdyHxloTKiF8BD5iGrH8T6MSeGvSgob0= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o= github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= @@ -569,7 +549,6 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.6 h1:6Su7aK7lXmJ/U79bYtBjLNaha4Fs1Rg9plHpcH+vvnE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs= @@ -581,7 +560,6 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -593,7 +571,6 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.25 h1:dFwPR6SfLtrSwgDcIq2bcU/gVutB4sNApq2HBdqcakg= github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -605,13 +582,10 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.3.2 h1:mRS76wmkOn3KkKAyXDu42V+6ebnXWIztFSYGN7GeoRg= github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.2 h1:6h7AQ0yhTcIsmFmnAwQls75jp2Gzs4iB8W7pjMO+rqo= github.com/mitchellh/mapstructure v1.4.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -628,7 +602,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -701,6 +674,7 @@ github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFR github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9/go.mod h1:SnhjPscd9TpLiy1LpzGSKh3bXCfxxXuqd9xmQJy3slM= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= @@ -856,7 +830,6 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20200901203048-c4f52b2c50aa h1:i1+omYRtqpxiCaQJB4MQhUToKvMPFqUUJKvRiRp0gtE= golang.org/x/exp v0.0.0-20200901203048-c4f52b2c50aa/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200908183739-ae8ad444f925 h1:5XVKs2rlCg8EFyRcvO8/XFwYxh1oKJO1Q3X5vttIf9c= golang.org/x/exp v0.0.0-20200908183739-ae8ad444f925/go.mod h1:1phAWC201xIgDyaFpmDeZkgf70Q4Pd/CNqfRtVPtxNw= @@ -880,7 +853,6 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449 h1:xUIPaMhvROX9dhPvRCenIJtU78+lbEenGbgqB5hfHCQ= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -993,22 +965,16 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbqrP/tgas88tPUbBxQrk= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015 h1:hZR0X1kPW+nwyJ9xRxqZk1vx5RUObAPBdKVvXPDUH/E= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b h1:1VkfZQv42XQlA/jchYumAnv1UPo6RgF9rJFkTgZIxO4= golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1020,7 +986,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -1086,7 +1051,6 @@ golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1101,10 +1065,8 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/ google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0 h1:J1Pl9P2lnmYFSJvgs70DKELqHNh8CNWXPbud4njEE2s= google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.25.0 h1:LodzhlzZEUfhXzNUMIfVlf9Gr6Ua5MMtoFWh7+f47qA= google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0 h1:BaiDisFir8O4IJxvAabCGGkQ6yCJegNQqSVoYUNAnbk= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= @@ -1166,16 +1128,13 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1197,12 +1156,10 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -1213,7 +1170,6 @@ gorm.io/driver/postgres v1.0.0/go.mod h1:wtMFcOzmuA5QigNsgEIb7O5lhvH1tHAF1RbWmLW gorm.io/driver/sqlserver v1.0.4 h1:V15fszi0XAo7fbx3/cF50ngshDSN4QT0MXpWTylyPTY= gorm.io/driver/sqlserver v1.0.4/go.mod h1:ciEo5btfITTBCj9BkoUVDvgQbUdLWQNqdFY5OGuGnRg= gorm.io/gorm v1.9.19/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.20.0 h1:qfIlyaZvrF7kMWY3jBdEBXkXJ2M5MFYMTppjILxS3fQ= gorm.io/gorm v1.20.0/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= gorm.io/gorm v1.20.6 h1:qa7tC1WcU+DBI/ZKMxvXy1FcrlGsvxlaKufHrT2qQ08= gorm.io/gorm v1.20.6/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= diff --git a/profiler/internal/extensions/extensions.go b/profiler/internal/extensions/extensions.go new file mode 100644 index 0000000000..b449c52700 --- /dev/null +++ b/profiler/internal/extensions/extensions.go @@ -0,0 +1,60 @@ +// 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 2022 Datadog, Inc. + +// Package extensions provides an interface for using optional features. +// +// Features such as C allocation profiling might require cgo, unsafe code, and +// external non-Go dependencies which might not be desirable for typical users. +// The main profiler package should not import any package implementing such +// features directly as doing so may have undesired side effects. This package +// provides a bridge between the implementation of such optional features and +// the main profiler package. +package extensions + +import ( + "sync" + + "github.com/google/pprof/profile" +) + +// CAllocationProfiler is the interface for profiling allocations done through +// the standard malloc/calloc/realloc APIs. +// +// A CAllocationProfiler implementation is not necessarily safe to use from +// multiple goroutines concurrently. +type CAllocationProfiler interface { + // Start begins sampling C allocations at the given rate, in bytes. + // There will be an average of one sample for every rate bytes + // allocated. + Start(rate int) + // Stop cancels ongoing C allocation profiling and returns the resulting + // profile. The profile will have the correct sample types such that it + // can be merged with the Go heap profile. Returns a non-nil error if + // any part of the profiling failed. + Stop() (*profile.Profile, error) +} + +var ( + mu sync.Mutex + cAllocationProfiler CAllocationProfiler +) + +// GetCAllocationProfiler returns the currently registered C allocation +// profiler, if one is registered. +func GetCAllocationProfiler() (impl CAllocationProfiler, registered bool) { + mu.Lock() + defer mu.Unlock() + if cAllocationProfiler == nil { + return nil, false + } + return cAllocationProfiler, true +} + +// SetCAllocationProfiler registers a C allocation profiler implementation. +func SetCAllocationProfiler(c CAllocationProfiler) { + mu.Lock() + defer mu.Unlock() + cAllocationProfiler = c +} diff --git a/profiler/internal/pprofutils/delta.go b/profiler/internal/pprofutils/delta.go index 1326db36b7..263668bd9c 100644 --- a/profiler/internal/pprofutils/delta.go +++ b/profiler/internal/pprofutils/delta.go @@ -30,7 +30,10 @@ type Delta struct { // profile. Samples that end up with a delta of 0 are dropped. WARNING: Profile // a will be mutated by this function. You should pass a copy if that's // undesirable. -func (d Delta) Convert(a, b *profile.Profile) (*profile.Profile, error) { +// +// Other profiles that should be merged into the resulting profile can be passed +// through the extra parameter. +func (d Delta) Convert(a, b *profile.Profile, extra ...*profile.Profile) (*profile.Profile, error) { ratios := make([]float64, len(a.SampleType)) found := 0 @@ -58,7 +61,10 @@ func (d Delta) Convert(a, b *profile.Profile) (*profile.Profile, error) { a.ScaleN(ratios) - delta, err := profile.Merge([]*profile.Profile{a, b}) + profiles := make([]*profile.Profile, 0, 2+len(extra)) + profiles = append(profiles, a, b) + profiles = append(profiles, extra...) + delta, err := profile.Merge(profiles) if err != nil { return nil, err } diff --git a/profiler/options.go b/profiler/options.go index 1e6c0551fe..8106b61531 100644 --- a/profiler/options.go +++ b/profiler/options.go @@ -116,7 +116,7 @@ func logStartup(c *config) { OSVersion string `json:"os_version"` // Version of the OS Version string `json:"version"` // Profiler version Lang string `json:"lang"` // "Go" - LangVersion string `json:"lang_version"` // Go version, e.g. go1.13 + LangVersion string `json:"lang_version"` // Go version, e.g. go1.18 Hostname string `json:"hostname"` DeltaProfiles bool `json:"delta_profiles"` Service string `json:"service"` diff --git a/profiler/profile.go b/profiler/profile.go index 038d077dc8..5c6eaa1cf1 100644 --- a/profiler/profile.go +++ b/profiler/profile.go @@ -13,6 +13,7 @@ import ( "runtime" "time" + "gopkg.in/DataDog/dd-trace-go.v1/profiler/internal/extensions" "gopkg.in/DataDog/dd-trace-go.v1/profiler/internal/pprofutils" "github.com/DataDog/gostackparse" @@ -63,14 +64,12 @@ type profileType struct { // this isn't done due to idiosyncratic filename used by the // GoroutineProfile. Filename string - // Delta controls if this profile should be generated as a delta profile. - // This is useful for profiles that represent samples collected over the - // lifetime of the process (i.e. heap, block, mutex). If nil, no delta - // profile is generated. - Delta *pprofutils.Delta + // SupportsDelta indicates whether delta profiles can be computed for + // this profile type, which is used to determine the final filename + SupportsDelta bool // Collect collects the given profile and returns the data for it. Most // profiles will be in pprof format, i.e. gzip compressed proto buf data. - Collect func(profileType, *profiler) ([]byte, error) + Collect func(p *profiler) ([]byte, error) } // profileTypes maps every ProfileType to its implementation. @@ -78,7 +77,7 @@ var profileTypes = map[ProfileType]profileType{ CPUProfile: { Name: "cpu", Filename: "cpu.pprof", - Collect: func(_ profileType, p *profiler) ([]byte, error) { + Collect: func(p *profiler) ([]byte, error) { var buf bytes.Buffer if p.cfg.cpuProfileRate != 0 { // The profile has to be set each time before @@ -103,33 +102,33 @@ var profileTypes = map[ProfileType]profileType{ HeapProfile: { Name: "heap", Filename: "heap.pprof", - Delta: &pprofutils.Delta{SampleTypes: []pprofutils.ValueType{ + Collect: collectGenericProfile("heap", &pprofutils.Delta{SampleTypes: []pprofutils.ValueType{ {Type: "alloc_objects", Unit: "count"}, {Type: "alloc_space", Unit: "bytes"}, - }}, - Collect: collectGenericProfile, + }}), + SupportsDelta: true, }, MutexProfile: { - Name: "mutex", - Filename: "mutex.pprof", - Delta: &pprofutils.Delta{}, - Collect: collectGenericProfile, + Name: "mutex", + Filename: "mutex.pprof", + Collect: collectGenericProfile("mutex", &pprofutils.Delta{}), + SupportsDelta: true, }, BlockProfile: { - Name: "block", - Filename: "block.pprof", - Delta: &pprofutils.Delta{}, - Collect: collectGenericProfile, + Name: "block", + Filename: "block.pprof", + Collect: collectGenericProfile("block", &pprofutils.Delta{}), + SupportsDelta: true, }, GoroutineProfile: { Name: "goroutine", Filename: "goroutines.pprof", - Collect: collectGenericProfile, + Collect: collectGenericProfile("goroutine", nil), }, expGoroutineWaitProfile: { Name: "goroutinewait", Filename: "goroutineswait.pprof", - Collect: func(t profileType, p *profiler) ([]byte, error) { + Collect: func(p *profiler) ([]byte, error) { if n := runtime.NumGoroutine(); n > p.cfg.maxGoroutinesWait { return nil, fmt.Errorf("skipping goroutines wait profile: %d goroutines exceeds DD_PROFILING_WAIT_PROFILE_MAX_GOROUTINES limit of %d", n, p.cfg.maxGoroutinesWait) } @@ -149,7 +148,7 @@ var profileTypes = map[ProfileType]profileType{ MetricsProfile: { Name: "metrics", Filename: "metrics.json", - Collect: func(_ profileType, p *profiler) ([]byte, error) { + Collect: func(p *profiler) ([]byte, error) { var buf bytes.Buffer err := p.met.report(now(), &buf) return buf.Bytes(), err @@ -157,10 +156,42 @@ var profileTypes = map[ProfileType]profileType{ }, } -func collectGenericProfile(t profileType, p *profiler) ([]byte, error) { - var buf bytes.Buffer - err := p.lookupProfile(t.Name, &buf, 0) - return buf.Bytes(), err +func collectGenericProfile(name string, delta *pprofutils.Delta) func(p *profiler) ([]byte, error) { + return func(p *profiler) ([]byte, error) { + var extra []*pprofile.Profile + // TODO: add type safety for name == "heap" check and remove redunancy with profileType.Name. + if cAlloc, ok := extensions.GetCAllocationProfiler(); ok && p.cfg.deltaProfiles && name == "heap" { + // For the heap profile, we'd also like to include C + // allocations if that extension is enabled and have the + // allocations show up in the same profile. Collect them + // first before getting the regular heap snapshot so + // that all allocations cover the same time period + // + // TODO: Support non-delta profiles for C allocations? + cAlloc.Start(2 * 1024 * 1024) + p.interruptibleSleep(p.cfg.period) + profile, err := cAlloc.Stop() + if err == nil { + extra = append(extra, profile) + } + } + + var buf bytes.Buffer + err := p.lookupProfile(name, &buf, 0) + data := buf.Bytes() + if delta == nil || !p.cfg.deltaProfiles { + return data, err + } + + start := time.Now() + delta, err := p.deltaProfile(name, delta, data, extra...) + tags := append(p.cfg.tags, fmt.Sprintf("profile_type:%s", name)) + p.cfg.statsd.Timing("datadog.profiler.go.delta_time", time.Since(start), tags, 1) + if err != nil { + return nil, fmt.Errorf("delta profile error: %s", err) + } + return delta.data, err + } } // lookup returns t's profileType implementation. @@ -174,7 +205,7 @@ func (t ProfileType) lookup() profileType { Type: t, Name: "unknown", Filename: "unknown", - Collect: func(_ profileType, _ *profiler) ([]byte, error) { + Collect: func(_ *profiler) ([]byte, error) { return nil, errors.New("profile type not implemented") }, } @@ -217,49 +248,31 @@ func (b *batch) addProfile(p *profile) { func (p *profiler) runProfile(pt ProfileType) ([]*profile, error) { start := now() t := pt.lookup() - // Collect the original profile as-is. - data, err := t.Collect(t, p) + data, err := t.Collect(p) if err != nil { return nil, err } - // Compute the deltaProf (will be nil if not enabled for this profile type). - deltaStart := time.Now() - deltaProf, err := p.deltaProfile(t, data) - if err != nil { - return nil, fmt.Errorf("delta profile error: %s", err) - } end := now() tags := append(p.cfg.tags, pt.Tag()) - var profs []*profile - if deltaProf != nil { - profs = append(profs, deltaProf) - p.cfg.statsd.Timing("datadog.profiler.go.delta_time", end.Sub(deltaStart), tags, 1) - } else { - // If the user has disabled delta profiles, or the profile type - // doesn't support delta profiles (like the CPU profile) then - // send the original profile unchanged. - profs = append(profs, &profile{ - name: t.Filename, - data: data, - }) + filename := t.Filename + // TODO(fg): Consider making Collect() return the filename. + if p.cfg.deltaProfiles && t.SupportsDelta { + filename = "delta-" + filename } p.cfg.statsd.Timing("datadog.profiler.go.collect_time", end.Sub(start), tags, 1) - return profs, nil + return []*profile{{name: filename, data: data}}, nil } // deltaProfile derives the delta profile between curData and the previous -// profile. For profile types that don't have delta profiling enabled, or -// WithDeltaProfiles(false), it simply returns nil, nil. -func (p *profiler) deltaProfile(t profileType, curData []byte) (*profile, error) { - if !p.cfg.deltaProfiles || t.Delta == nil { - return nil, nil - } +// profile. If extra profiles are provided, they will be merged into the final +// profile after computing the delta profile. +func (p *profiler) deltaProfile(name string, delta *pprofutils.Delta, curData []byte, extra ...*pprofile.Profile) (*profile, error) { curProf, err := pprofile.ParseData(curData) if err != nil { return nil, fmt.Errorf("delta prof parse: %v", err) } var deltaData []byte - if prevProf := p.prev[t.Type]; prevProf == nil { + if prevProf := p.prev[name]; prevProf == nil { // First time deltaProfile gets called for a type, there is no prevProf. In // this case we emit the current profile as a delta profile. deltaData = curData @@ -268,7 +281,7 @@ func (p *profiler) deltaProfile(t profileType, curData []byte) (*profile, error) // Unfortunately the core implementation isn't resuable via a API, so we do // our own delta calculation below. // https://github.com/golang/go/commit/2ff1e3ebf5de77325c0e96a6c2a229656fc7be50#diff-94594f8f13448da956b02997e50ca5a156b65085993e23bbfdda222da6508258R303-R304 - deltaProf, err := t.Delta.Convert(prevProf, curProf) + deltaProf, err := delta.Convert(prevProf, curProf, extra...) if err != nil { return nil, fmt.Errorf("delta prof merge: %v", err) } @@ -285,11 +298,8 @@ func (p *profiler) deltaProfile(t profileType, curData []byte) (*profile, error) } // Keep the most recent profiles in memory for future diffing. This needs to // be taken into account when enforcing memory limits going forward. - p.prev[t.Type] = curProf - return &profile{ - name: "delta-" + t.Filename, - data: deltaData, - }, nil + p.prev[name] = curProf + return &profile{data: deltaData}, nil } func goroutineDebug2ToPprof(r io.Reader, w io.Writer, t time.Time) (err error) { diff --git a/profiler/profiler.go b/profiler/profiler.go index 4e33a6d998..d5d6f4bbee 100644 --- a/profiler/profiler.go +++ b/profiler/profiler.go @@ -63,14 +63,14 @@ func Stop() { // profiler collects and sends preset profiles to the Datadog API at a given frequency // using a given configuration. type profiler struct { - cfg *config // profile configuration - out chan batch // upload queue - uploadFunc func(batch) error // defaults to (*profiler).upload; replaced in tests - exit chan struct{} // exit signals the profiler to stop; it is closed after stopping - stopOnce sync.Once // stopOnce ensures the profiler is stopped exactly once. - wg sync.WaitGroup // wg waits for all goroutines to exit when stopping. - met *metrics // metric collector state - prev map[ProfileType]*pprofile.Profile // previous collection results for delta profiling + cfg *config // profile configuration + out chan batch // upload queue + uploadFunc func(batch) error // defaults to (*profiler).upload; replaced in tests + exit chan struct{} // exit signals the profiler to stop; it is closed after stopping + stopOnce sync.Once // stopOnce ensures the profiler is stopped exactly once. + wg sync.WaitGroup // wg waits for all goroutines to exit when stopping. + met *metrics // metric collector state + prev map[string]*pprofile.Profile // previous collection results for delta profiling testHooks testHooks } @@ -178,7 +178,7 @@ func newProfiler(opts ...Option) (*profiler, error) { out: make(chan batch, outChannelSize), exit: make(chan struct{}), met: newMetrics(), - prev: make(map[ProfileType]*pprofile.Profile), + prev: make(map[string]*pprofile.Profile), } p.uploadFunc = p.upload return &p, nil diff --git a/profiler/profiler_test.go b/profiler/profiler_test.go index 48d919ab2c..7573eac4f9 100644 --- a/profiler/profiler_test.go +++ b/profiler/profiler_test.go @@ -277,23 +277,23 @@ func TestProfilerInternal(t *testing.T) { func TestSetProfileFraction(t *testing.T) { t.Run("on", func(t *testing.T) { - start := runtime.SetMutexProfileFraction(-1) + start := runtime.SetMutexProfileFraction(0) defer runtime.SetMutexProfileFraction(start) p, err := unstartedProfiler(WithProfileTypes(MutexProfile)) require.NoError(t, err) p.run() p.stop() - assert.NotEqual(t, start, runtime.SetMutexProfileFraction(-1)) + assert.Equal(t, DefaultMutexFraction, runtime.SetMutexProfileFraction(-1)) }) t.Run("off", func(t *testing.T) { - start := runtime.SetMutexProfileFraction(-1) + start := runtime.SetMutexProfileFraction(0) defer runtime.SetMutexProfileFraction(start) p, err := unstartedProfiler() require.NoError(t, err) p.run() p.stop() - assert.Equal(t, start, runtime.SetMutexProfileFraction(-1)) + assert.Zero(t, runtime.SetMutexProfileFraction(-1)) }) } diff --git a/profiler/upload.go b/profiler/upload.go index d023ad396f..dfc92863b3 100644 --- a/profiler/upload.go +++ b/profiler/upload.go @@ -87,12 +87,7 @@ func (p *profiler) doRequest(bat batch) error { } cancel() }() - // TODO(fg) use NewRequestWithContext once go 1.12 support is dropped. - req, err := http.NewRequest("POST", p.cfg.targetURL, body) - if err != nil { - return err - } - req = req.WithContext(ctx) + req, err := http.NewRequestWithContext(ctx, "POST", p.cfg.targetURL, body) if p.cfg.apiKey != "" { req.Header.Set("DD-API-KEY", p.cfg.apiKey) }