diff --git a/cmd/apollo-api/main.go b/cmd/apollo-api/main.go index 085315e..72b1909 100644 --- a/cmd/apollo-api/main.go +++ b/cmd/apollo-api/main.go @@ -7,6 +7,7 @@ import ( "net/http" "os" + "github.com/DataDog/datadog-go/statsd" "github.com/joho/godotenv" _ "github.com/lib/pq" @@ -46,7 +47,16 @@ func main() { } defer db.Close() - rc := reddit.NewClient(os.Getenv("REDDIT_CLIENT_ID"), os.Getenv("REDDIT_CLIENT_SECRET")) + statsd, err := statsd.New("127.0.0.1:8125") + if err != nil { + log.Fatal(err) + } + + rc := reddit.NewClient( + os.Getenv("REDDIT_CLIENT_ID"), + os.Getenv("REDDIT_CLIENT_SECRET"), + statsd, + ) app := &application{ cfg, diff --git a/cmd/apollo-worker/main.go b/cmd/apollo-worker/main.go index d91cf59..2389f47 100644 --- a/cmd/apollo-worker/main.go +++ b/cmd/apollo-worker/main.go @@ -182,8 +182,6 @@ func main() { logger.Printf("Couldn't find .env so I will read from existing ENV.") } - rc := reddit.NewClient(os.Getenv("REDDIT_CLIENT_ID"), os.Getenv("REDDIT_CLIENT_SECRET")) - dburl, ok := os.LookupEnv("DATABASE_CONNECTION_POOL_URL") if !ok { dburl = os.Getenv("DATABASE_URL") @@ -204,6 +202,12 @@ func main() { log.Fatal(err) } + rc := reddit.NewClient( + os.Getenv("REDDIT_CLIENT_ID"), + os.Getenv("REDDIT_CLIENT_SECRET"), + statsd, + ) + // This is a very conservative value -- seen as most of the work that is done in these jobs is // runtime.GOMAXPROCS(workers) diff --git a/internal/reddit/client.go b/internal/reddit/client.go index e6c055d..2f394c8 100644 --- a/internal/reddit/client.go +++ b/internal/reddit/client.go @@ -4,9 +4,11 @@ import ( "encoding/json" "io/ioutil" "net/http" + "net/http/httptrace" "strings" "time" + "github.com/DataDog/datadog-go/statsd" "github.com/valyala/fastjson" ) @@ -18,14 +20,26 @@ type Client struct { id string secret string client *http.Client + tracer *httptrace.ClientTrace parser *fastjson.Parser + statsd *statsd.Client } -func NewClient(id, secret string) *Client { +func NewClient(id, secret string, statsd *statsd.Client) *Client { tr := &http.Transport{ MaxIdleConnsPerHost: 128, } + tracer := &httptrace.ClientTrace{ + GotConn: func(info httptrace.GotConnInfo) { + if info.Reused { + statsd.Incr("reddit.api.connections.reused", []string{}, 0.1) + } else { + statsd.Incr("reddit.api.connections.created", []string{}, 0.1) + } + }, + } + client := &http.Client{Transport: tr} parser := &fastjson.Parser{} @@ -34,7 +48,9 @@ func NewClient(id, secret string) *Client { id, secret, client, + tracer, parser, + statsd, } } @@ -56,6 +72,8 @@ func (rac *AuthenticatedClient) request(r *Request) ([]byte, error) { return nil, err } + req = req.WithContext(httptrace.WithClientTrace(req.Context(), rac.tracer)) + resp, err := rac.client.Do(req) if err != nil { return nil, err