Skip to content

Commit

Permalink
feat: add support for tracing (#32)
Browse files Browse the repository at this point in the history
* feat: add tracing for Dial, Connect, and Refresh
* Add instance name as attribute on trace
* Add instructions for using tracing
  • Loading branch information
enocom committed Jul 29, 2021
1 parent a251fd7 commit 4d2acbc
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 58 deletions.
64 changes: 49 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# cloud-sql-go-connector
*Warning*: This project is experimental, and is not an officially supported
*Warning*: This project is experimental, and is not an officially supported
Google product.

The _Cloud SQL Go Connector_ provides strong encryption and IAM authorization
Expand All @@ -11,9 +11,9 @@ see [About the Cloud SQL Auth proxy][about-proxy].

[about-proxy]: https://cloud.google.com/sql/docs/mysql/sql-proxy

The _Cloud SQL Go Connector_ is an experimental new version of the
[Cloud SQL proxy dialer](dialer). Its API is considered unstable and may change
in the future. Please use at your own risk.
The _Cloud SQL Go Connector_ is an experimental new version of the
[Cloud SQL proxy dialer](dialer). Its API is considered unstable and may change
in the future. Please use at your own risk.

[proxy-dialer]: https://github.com/GoogleCloudPlatform/cloudsql-proxy/tree/main/proxy#cloud-sql-proxy-dialer-for-go

Expand All @@ -30,21 +30,21 @@ folder:
replace cloud.google.com/cloudsqlconn => ../cloud-sql-go-connector
```

## Usage
## Usage

This package provides several functions for authorizing and encrypting
connections. These functions can be used with your database driver to connect to
your Cloud SQL instance.

The instance connection name for your Cloud SQL instance is always in the
The instance connection name for your Cloud SQL instance is always in the
format "project:region:instance".

### Credentials
### Credentials

This repo uses the [Application Default Credentials (ADC)][adc] strategy for
typing providing credentials. Please see the
[golang.org/x/oauth2/google][google-auth] documentation for more information in
how these credentials are sourced.
how these credentials are sourced.

To explicitly set a specific source for the Credentials to use, see [Using
DialerOptions](#using-dialeroptions) below.
Expand All @@ -55,18 +55,18 @@ DialerOptions](#using-dialeroptions) below.
### Using the default Dialer

If you don't need to customize your Dialer's behavior, it is convenient to use
the package's "Dial" option, which initializes a default dialer for you.
the package's "Dial" option, which initializes a default dialer for you.

#### pgx for Postgres

Use the [pgConn.DialFunc field][pgconn-cfg] to create connections:

```go
// Configure the driver to connect to the database
dsn := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", pgUser, pgPass, pgDb)
dsn := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable", pgUser, pgPass, pgDB)
config, err := pgx.ParseConfig(dsn)
if err != nil {
t.Fatalf("failed to parse pgx config: %v", err)
log.Fatalf("failed to parse pgx config: %v", err)
}

// Tell the driver to use the Cloud SQL Go Connector to create connections
Expand All @@ -77,7 +77,7 @@ the package's "Dial" option, which initializes a default dialer for you.
// Interact with the driver directly as you normally would
conn, connErr := pgx.ConnectConfig(ctx, config)
if connErr != nil {
t.Fatalf("failed to connect: %s", connErr)
log.Fatalf("failed to connect: %s", connErr)
}
defer conn.Close(ctx)
```
Expand Down Expand Up @@ -106,11 +106,11 @@ For a full list of customizable behavior, see DialerOptions.

### Using DialOptions

If you want to customize things about how the connection is created, use
If you want to customize things about how the connection is created, use
`DialerOptions`:
```go
conn, err := myDialer.Dial(
ctx,
ctx,
"project:region:instance",
cloudsqlconn.WithPrivateIP(),
)
Expand All @@ -125,4 +125,38 @@ myDialer, err := cloudsqlconn.NewDialer(
cloudsqlconn.WithPrivateIP(),
),
)
```
```

### Enabling Tracing

This library includes support for tracing using [OpenCensus][]. To enable
tracing, you need to configure an [exporter][]. OpenCensus supports many
backends for exporters. For example, to use [Cloud Trace][], you would
configure an exporter like so:

``` golang
package main

import (
"contrib.go.opencensus.io/exporter/stackdriver"
"go.opencensus.io/trace"
)

func main() {
sd, err := stackdriver.NewExporter(stackdriver.Options{
ProjectID: "mycoolproject",
})
if err != nil {
// handle error
}
defer sd.Flush()
trace.RegisterExporter(sd)

// Use cloudsqlconn as usual.
// ...
}
```

[OpenCensus]: https://opencensus.io/introduction/
[exporter]: https://opencensus.io/exporters/
[Cloud Trace]: https://cloud.google.com/trace
19 changes: 16 additions & 3 deletions dialer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"time"

"cloud.google.com/go/cloudsqlconn/internal/cloudsql"
"cloud.google.com/go/cloudsqlconn/internal/trace"
"golang.org/x/net/proxy"
"google.golang.org/api/option"
sqladmin "google.golang.org/api/sqladmin/v1beta4"
Expand Down Expand Up @@ -120,23 +121,35 @@ func NewDialer(ctx context.Context, opts ...DialerOption) (*Dialer, error) {

// Dial returns a net.Conn connected to the specified Cloud SQL instance. The instance argument must be the
// instance's connection name, which is in the format "project-name:region:instance-name".
func (d *Dialer) Dial(ctx context.Context, instance string, opts ...DialOption) (net.Conn, error) {
func (d *Dialer) Dial(ctx context.Context, instance string, opts ...DialOption) (conn net.Conn, err error) {
var endDial trace.EndSpanFunc
ctx, endDial = trace.StartSpan(ctx, "cloud.google.com/go/cloudsqlconn.Dial",
trace.AddInstanceName(instance))
defer func() { endDial(err) }()
cfg := d.defaultDialCfg
for _, opt := range opts {
opt(&cfg)
}

var endInfo trace.EndSpanFunc
ctx, endInfo = trace.StartSpan(ctx, "cloud.google.com/go/cloudsqlconn/internal.InstanceInfo")
i, err := d.instance(instance)
if err != nil {
endInfo(err)
return nil, err
}
addr, tlsCfg, err := i.ConnectInfo(ctx, cfg.ipType)
if err != nil {
endInfo(err)
return nil, err
}
addr = net.JoinHostPort(addr, serverProxyPort)
endInfo(err)

conn, err := proxy.Dial(ctx, "tcp", addr)
var connectEnd trace.EndSpanFunc
ctx, connectEnd = trace.StartSpan(ctx, "cloud.google.com/go/cloudsqlconn/internal.Connect")
defer func() { connectEnd(err) }()
addr = net.JoinHostPort(addr, serverProxyPort)
conn, err = proxy.Dial(ctx, "tcp", addr)
if err != nil {
// refresh the instance info in case it caused the connection failure
i.ForceRefresh()
Expand Down
14 changes: 8 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ module cloud.google.com/go/cloudsqlconn
go 1.15

require (
cloud.google.com/go v0.75.0 // indirect
github.com/jackc/pgx/v4 v4.10.1
golang.org/x/net v0.0.0-20200904194848-62affa334b73
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 // indirect
github.com/pkg/errors v0.9.1 // indirect
go.opencensus.io v0.22.6
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4
golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba
google.golang.org/api v0.31.0
google.golang.org/genproto v0.0.0-20200911024640-645f7a48b24f // indirect
google.golang.org/grpc v1.32.0 // indirect
google.golang.org/api v0.37.0
google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f
google.golang.org/grpc v1.39.0
)
Loading

0 comments on commit 4d2acbc

Please sign in to comment.