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)
}