From 7fe002d1dfe45a478c58b3fc58c1175d0a955b08 Mon Sep 17 00:00:00 2001
From: Kelsey <kelsey@netlify.com>
Date: Thu, 3 Dec 2020 12:14:18 -0700
Subject: [PATCH] wip db instrumentation

---
 api/api.go      |  1 +
 api/helpers.go  |  8 ++++++++
 go.mod          |  3 +++
 go.sum          |  2 ++
 hack/test.env   |  2 +-
 storage/dial.go | 13 +++++++++++--
 6 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/api/api.go b/api/api.go
index 50bef8265..a97bd7384 100644
--- a/api/api.go
+++ b/api/api.go
@@ -88,6 +88,7 @@ func NewAPIWithVersion(ctx context.Context, globalConfig *conf.GlobalConfigurati
 	r.Use(addRequestID(globalConfig))
 	r.Use(recoverer)
 	r.UseBypass(tracer)
+	r.Use(addDBConnectionContext(api.db))
 
 	r.Get("/health", api.HealthCheck)
 
diff --git a/api/helpers.go b/api/helpers.go
index b6380956d..bfec150d1 100644
--- a/api/helpers.go
+++ b/api/helpers.go
@@ -37,6 +37,14 @@ func addRequestID(globalConfig *conf.GlobalConfiguration) middlewareHandler {
 	}
 }
 
+func addDBConnectionContext(c *storage.Connection) middlewareHandler {
+	return func(w http.ResponseWriter, r *http.Request) (context.Context, error) {
+		ctx := r.Context()
+		c.WithContext(ctx)
+		return ctx, nil
+	}
+}
+
 func sendJSON(w http.ResponseWriter, status int, obj interface{}) error {
 	w.Header().Set("Content-Type", "application/json")
 	b, err := json.Marshal(obj)
diff --git a/go.mod b/go.mod
index ff8a32535..40a41566e 100644
--- a/go.mod
+++ b/go.mod
@@ -13,6 +13,9 @@ require (
 	github.com/imdario/mergo v0.0.0-20160216103600-3e95a51e0639
 	github.com/joho/godotenv v1.3.0
 	github.com/kelseyhightower/envconfig v1.4.0
+	github.com/luna-duclos/instrumentedsql v1.1.3
+	github.com/luna-duclos/instrumentedsql/opentracing v0.0.0-20201103091713-40d03108b6f4
+	github.com/mattn/go-colorable v0.1.4 // indirect
 	github.com/netlify/mailme v1.1.1
 	github.com/opentracing/opentracing-go v1.1.0
 	github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
diff --git a/go.sum b/go.sum
index fc4eaff98..fe53286c3 100644
--- a/go.sum
+++ b/go.sum
@@ -221,6 +221,8 @@ github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU=
 github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
 github.com/luna-duclos/instrumentedsql v1.1.3 h1:t7mvC0z1jUt5A0UQ6I/0H31ryymuQRnJcWCiqV3lSAA=
 github.com/luna-duclos/instrumentedsql v1.1.3/go.mod h1:9J1njvFds+zN7y85EDhN9XNQLANWwZt2ULeIC8yMNYs=
+github.com/luna-duclos/instrumentedsql/opentracing v0.0.0-20201103091713-40d03108b6f4 h1:b8Uu5JfweuhcXIqANFs9dOw5zanFj89GYOGlyys37ds=
+github.com/luna-duclos/instrumentedsql/opentracing v0.0.0-20201103091713-40d03108b6f4/go.mod h1:YnZVBK+MxEr2sn1rbf4UMqsBd0uKaCOq52UtmbfDKNM=
 github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI=
diff --git a/hack/test.env b/hack/test.env
index f6e5a45a1..34b136c04 100644
--- a/hack/test.env
+++ b/hack/test.env
@@ -30,7 +30,7 @@ GOTRUE_EXTERNAL_SAML_ENABLED=true
 GOTRUE_EXTERNAL_SAML_METADATA_URL=
 GOTRUE_EXTERNAL_SAML_API_BASE=http://localhost
 GOTRUE_EXTERNAL_SAML_NAME=TestSamlName
-GOTRUE_TRACING_ENABLED=false
+GOTRUE_TRACING_ENABLED=true
 GOTRUE_TRACING_HOST=127.0.0.1
 GOTRUE_TRACING_PORT=8126
 GOTRUE_TRACING_TAGS="env:test"
diff --git a/storage/dial.go b/storage/dial.go
index 499df9e87..ea031083e 100644
--- a/storage/dial.go
+++ b/storage/dial.go
@@ -1,6 +1,7 @@
 package storage
 
 import (
+	"context"
 	"net/url"
 	"reflect"
 
@@ -8,6 +9,8 @@ import (
 	_ "github.com/go-sql-driver/mysql"
 	"github.com/gobuffalo/pop/v5"
 	"github.com/gobuffalo/pop/v5/columns"
+	"github.com/luna-duclos/instrumentedsql"
+	"github.com/luna-duclos/instrumentedsql/opentracing"
 	"github.com/netlify/gotrue/conf"
 	"github.com/netlify/gotrue/storage/namespace"
 	"github.com/pkg/errors"
@@ -30,8 +33,10 @@ func Dial(config *conf.GlobalConfiguration) (*Connection, error) {
 	}
 
 	db, err := pop.NewConnection(&pop.ConnectionDetails{
-		Dialect: config.DB.Driver,
-		URL:     config.DB.URL,
+		Dialect:                   config.DB.Driver,
+		URL:                       config.DB.URL,
+		UseInstrumentedDriver:     true,
+		InstrumentedDriverOptions: []instrumentedsql.Opt{instrumentedsql.WithTracer(opentracing.NewTracer(true))},
 	})
 	if err != nil {
 		return nil, errors.Wrap(err, "opening database connection")
@@ -82,3 +87,7 @@ func getExcludedColumns(model interface{}, includeColumns ...string) ([]string,
 	}
 	return xcols, nil
 }
+
+func (c *Connection) WithContext(ctx context.Context) {
+	c.Connection = c.Connection.WithContext(ctx)
+}