Skip to content

Commit bd20d9e

Browse files
authored
feat: Add datadog tracing to http middleware (coder#530)
* add datadog tracing to http handlers
1 parent e0172dd commit bd20d9e

File tree

5 files changed

+438
-11
lines changed

5 files changed

+438
-11
lines changed

cli/start.go

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,9 @@ import (
1616
"path/filepath"
1717
"time"
1818

19-
"github.com/briandowns/spinner"
20-
"github.com/coreos/go-systemd/daemon"
21-
"github.com/spf13/cobra"
22-
"golang.org/x/xerrors"
23-
"google.golang.org/api/idtoken"
24-
"google.golang.org/api/option"
25-
2619
"cdr.dev/slog"
2720
"cdr.dev/slog/sloggers/sloghuman"
21+
"github.com/briandowns/spinner"
2822
"github.com/coder/coder/cli/cliflag"
2923
"github.com/coder/coder/cli/cliui"
3024
"github.com/coder/coder/cli/config"
@@ -37,6 +31,12 @@ import (
3731
"github.com/coder/coder/provisionerd"
3832
"github.com/coder/coder/provisionersdk"
3933
"github.com/coder/coder/provisionersdk/proto"
34+
"github.com/coreos/go-systemd/daemon"
35+
"github.com/spf13/cobra"
36+
"golang.org/x/xerrors"
37+
"google.golang.org/api/idtoken"
38+
"google.golang.org/api/option"
39+
"gopkg.in/DataDog/dd-trace-go.v1/ddtrace/tracer"
4040
)
4141

4242
func start() *cobra.Command {
@@ -55,12 +55,17 @@ func start() *cobra.Command {
5555
tlsKeyFile string
5656
tlsMinVersion string
5757
useTunnel bool
58+
traceDatadog bool
5859
)
5960
root := &cobra.Command{
6061
Use: "start",
6162
RunE: func(cmd *cobra.Command, args []string) error {
62-
printLogo(cmd)
63+
if traceDatadog {
64+
tracer.Start()
65+
defer tracer.Stop()
66+
}
6367

68+
printLogo(cmd)
6469
listener, err := net.Listen("tcp", address)
6570
if err != nil {
6671
return xerrors.Errorf("listen %q: %w", address, err)
@@ -328,6 +333,7 @@ func start() *cobra.Command {
328333
`Specifies the minimum supported version of TLS. Accepted values are "tls10", "tls11", "tls12" or "tls13"`)
329334
cliflag.BoolVarP(root.Flags(), &useTunnel, "tunnel", "", "CODER_DEV_TUNNEL", false, "Serve dev mode through a Cloudflare Tunnel for easy setup")
330335
_ = root.Flags().MarkHidden("tunnel")
336+
cliflag.BoolVarP(root.Flags(), &traceDatadog, "trace-datadog", "", "CODER_TRACE_DATADOG", false, "Send tracing data to a datadog agent")
331337

332338
return root
333339
}

cli/start_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import (
1919
"time"
2020

2121
"github.com/stretchr/testify/require"
22+
"go.uber.org/goleak"
2223

2324
"github.com/coder/coder/cli/clitest"
2425
"github.com/coder/coder/coderd/coderdtest"
@@ -199,6 +200,21 @@ func TestStart(t *testing.T) {
199200
require.NoError(t, err)
200201
<-done
201202
})
203+
t.Run("DatadogTracerNoLeak", func(t *testing.T) {
204+
t.Parallel()
205+
ctx, cancelFunc := context.WithCancel(context.Background())
206+
defer cancelFunc()
207+
root, _ := clitest.New(t, "start", "--dev", "--tunnel=false", "--address", ":0", "--trace-datadog=true")
208+
done := make(chan struct{})
209+
go func() {
210+
defer close(done)
211+
err := root.ExecuteContext(ctx)
212+
require.ErrorIs(t, err, context.Canceled)
213+
}()
214+
cancelFunc()
215+
<-done
216+
require.Error(t, goleak.Find())
217+
})
202218
}
203219

204220
func generateTLSCertificate(t testing.TB) (certPath, keyPath string) {

coderd/coderd.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/coder/coder/coderd/httpapi"
1616
"github.com/coder/coder/coderd/httpmw"
1717
"github.com/coder/coder/site"
18+
chitrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/go-chi/chi.v5"
1819
)
1920

2021
// Options are requires parameters for Coder to start.
@@ -43,6 +44,7 @@ func New(options *Options) (http.Handler, func()) {
4344

4445
r := chi.NewRouter()
4546
r.Route("/api/v2", func(r chi.Router) {
47+
r.Use(chitrace.Middleware())
4648
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
4749
httpapi.Write(w, http.StatusOK, httpapi.Response{
4850
Message: "👋",

go.mod

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ replace github.com/urfave/cli/v2 => github.com/ipostelnik/cli/v2 v2.3.1-0.202103
2525

2626
replace github.com/rivo/tview => github.com/kylecarbs/tview v0.0.0-20220309202238-8464256e10a1
2727

28+
// glog has a single goroutine leak on start that we removed in a fork: https://github.com/coder/glog/pull/1.
29+
replace github.com/golang/glog => github.com/coder/glog v1.0.1-0.20220322161911-7365fe7f2cd1
30+
2831
require (
2932
cdr.dev/slog v1.4.1
3033
cloud.google.com/go/compute v1.5.0
@@ -89,6 +92,10 @@ require (
8992
require (
9093
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
9194
github.com/BurntSushi/toml v1.0.0 // indirect
95+
github.com/DataDog/datadog-agent/pkg/obfuscate v0.0.0-20211129110424-6491aa3bf583 // indirect
96+
github.com/DataDog/datadog-go v4.8.2+incompatible // indirect
97+
github.com/DataDog/datadog-go/v5 v5.0.2 // indirect
98+
github.com/DataDog/sketches-go v1.0.0 // indirect
9299
github.com/Microsoft/go-winio v0.5.2 // indirect
93100
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
94101
github.com/agext/levenshtein v1.2.3 // indirect
@@ -113,13 +120,15 @@ require (
113120
github.com/coredns/coredns v1.9.0 // indirect
114121
github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect
115122
github.com/davecgh/go-spew v1.1.1 // indirect
123+
github.com/dgraph-io/ristretto v0.1.0 // indirect
116124
github.com/dhui/dktest v0.3.9 // indirect
117125
github.com/dlclark/regexp2 v1.4.0 // indirect
118126
github.com/docker/cli v20.10.13+incompatible // indirect
119127
github.com/docker/distribution v2.8.0+incompatible // indirect
120128
github.com/docker/docker v20.10.13+incompatible // indirect
121129
github.com/docker/go-connections v0.4.0 // indirect
122130
github.com/docker/go-units v0.4.0 // indirect
131+
github.com/dustin/go-humanize v1.0.0 // indirect
123132
github.com/facebookgo/grace v0.0.0-20180706040059-75cf19382434 // indirect
124133
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 // indirect
125134
github.com/francoispqt/gojay v1.2.13 // indirect
@@ -136,6 +145,7 @@ require (
136145
github.com/gobwas/ws v1.1.0 // indirect
137146
github.com/gogo/protobuf v1.3.2 // indirect
138147
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 // indirect
148+
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
139149
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
140150
github.com/golang/protobuf v1.5.2 // indirect
141151
github.com/google/go-cmp v0.5.7 // indirect
@@ -149,13 +159,15 @@ require (
149159
github.com/hashicorp/hcl v1.0.0 // indirect
150160
github.com/imdario/mergo v0.3.12 // indirect
151161
github.com/inconshreveable/mousetrap v1.0.0 // indirect
162+
github.com/josharian/intern v1.0.0 // indirect
152163
github.com/json-iterator/go v1.1.12 // indirect
153164
github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc // indirect
154165
github.com/klauspost/compress v1.15.0 // indirect
155166
github.com/leodido/go-urn v1.2.1 // indirect
156167
github.com/lucas-clemente/quic-go v0.25.1-0.20220307142123-ad1cb27c1b64 // indirect
157168
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
158169
github.com/lunixbochs/vtclean v1.0.0 // indirect
170+
github.com/mailru/easyjson v0.7.7 // indirect
159171
github.com/marten-seemann/qtls-go1-16 v0.1.4 // indirect
160172
github.com/marten-seemann/qtls-go1-17 v0.1.0 // indirect
161173
github.com/marten-seemann/qtls-go1-18 v0.1.0-beta.1 // indirect
@@ -179,6 +191,7 @@ require (
179191
github.com/opencontainers/runc v1.1.0 // indirect
180192
github.com/opentracing/opentracing-go v1.2.0 // indirect
181193
github.com/pelletier/go-toml/v2 v2.0.0-beta.6 // indirect
194+
github.com/philhofer/fwd v1.1.1 // indirect
182195
github.com/pion/dtls/v2 v2.1.3 // indirect
183196
github.com/pion/ice/v2 v2.2.2 // indirect
184197
github.com/pion/interceptor v0.1.10 // indirect
@@ -206,7 +219,8 @@ require (
206219
github.com/spf13/afero v1.8.1 // indirect
207220
github.com/spf13/cast v1.4.1 // indirect
208221
github.com/spf13/jwalterweatherman v1.1.0 // indirect
209-
github.com/spf13/pflag v1.0.5 // indirect
222+
github.com/spf13/pflag v1.0.5
223+
github.com/tinylib/msgp v1.1.2 // indirect
210224
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
211225
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
212226
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
@@ -216,10 +230,12 @@ require (
216230
golang.org/x/mod v0.5.1 // indirect
217231
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
218232
golang.org/x/text v0.3.7 // indirect
233+
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
219234
golang.org/x/tools v0.1.9 // indirect
220235
google.golang.org/appengine v1.6.7 // indirect
221236
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6 // indirect
222237
google.golang.org/grpc v1.45.0 // indirect
238+
gopkg.in/DataDog/dd-trace-go.v1 v1.37.0
223239
gopkg.in/coreos/go-oidc.v2 v2.2.1 // indirect
224240
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
225241
gopkg.in/square/go-jose.v2 v2.6.0 // indirect

0 commit comments

Comments
 (0)