Skip to content

Commit ce76473

Browse files
committed
Add InstanceName trace option to differentiate multiple database instances
1 parent 41ee6eb commit ce76473

5 files changed

Lines changed: 53 additions & 23 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var (
3232
)
3333

3434
// Register our ocsql wrapper for the provided SQLite3 driver.
35-
driverName, err = ocsql.Register("sqlite3", ocsql.WithAllTraceOptions())
35+
driverName, err = ocsql.Register("sqlite3", ocsql.WithAllTraceOptions(), ocsql.WithInstanceName("resources"))
3636
if err != nil {
3737
log.Fatalf("unable to register our ocsql driver: %v\n", err)
3838
}

driver.go

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ func Register(driverName string, options ...TraceOption) (string, error) {
8888

8989
// Wrap takes a SQL driver and wraps it with OpenCensus instrumentation.
9090
func Wrap(d driver.Driver, options ...TraceOption) driver.Driver {
91-
o := TraceOptions{}
91+
o := TraceOptions{
92+
InstanceName: defaultInstanceName,
93+
}
9294
for _, option := range options {
9395
option(&o)
9496
}
@@ -109,7 +111,9 @@ func (d ocDriver) Open(name string) (driver.Conn, error) {
109111

110112
// WrapConn allows an existing driver.Conn to be wrapped by ocsql.
111113
func WrapConn(c driver.Conn, options ...TraceOption) driver.Conn {
112-
o := TraceOptions{}
114+
o := TraceOptions{
115+
InstanceName: defaultInstanceName,
116+
}
113117
for _, option := range options {
114118
option(&o)
115119
}
@@ -123,7 +127,7 @@ type ocConn struct {
123127
}
124128

125129
func (c ocConn) Ping(ctx context.Context) (err error) {
126-
defer recordCallStats(ctx, "go.sql.ping")(err)
130+
defer recordCallStats(ctx, "go.sql.ping", c.options.InstanceName)(err)
127131

128132
if c.options.Ping && (c.options.AllowRoot || trace.FromContext(ctx) != nil) {
129133
var span *trace.Span
@@ -151,7 +155,7 @@ func (c ocConn) Ping(ctx context.Context) (err error) {
151155
}
152156

153157
func (c ocConn) Exec(query string, args []driver.Value) (res driver.Result, err error) {
154-
defer recordCallStats(context.Background(), "go.sql.exec")(err)
158+
defer recordCallStats(context.Background(), "go.sql.exec", c.options.InstanceName)(err)
155159

156160
if exec, ok := c.parent.(driver.Execer); ok {
157161
if !c.options.AllowRoot {
@@ -192,7 +196,7 @@ func (c ocConn) Exec(query string, args []driver.Value) (res driver.Result, err
192196
}
193197

194198
func (c ocConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (res driver.Result, err error) {
195-
defer recordCallStats(ctx, "go.sql.exec")(err)
199+
defer recordCallStats(ctx, "go.sql.exec", c.options.InstanceName)(err)
196200

197201
if execCtx, ok := c.parent.(driver.ExecerContext); ok {
198202
parentSpan := trace.FromContext(ctx)
@@ -231,7 +235,7 @@ func (c ocConn) ExecContext(ctx context.Context, query string, args []driver.Nam
231235
}
232236

233237
func (c ocConn) Query(query string, args []driver.Value) (rows driver.Rows, err error) {
234-
defer recordCallStats(context.Background(), "go.sql.query")(err)
238+
defer recordCallStats(context.Background(), "go.sql.query", c.options.InstanceName)(err)
235239

236240
if queryer, ok := c.parent.(driver.Queryer); ok {
237241
if !c.options.AllowRoot {
@@ -273,7 +277,7 @@ func (c ocConn) Query(query string, args []driver.Value) (rows driver.Rows, err
273277
}
274278

275279
func (c ocConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (rows driver.Rows, err error) {
276-
defer recordCallStats(ctx, "go.sql.query")(err)
280+
defer recordCallStats(ctx, "go.sql.query", c.options.InstanceName)(err)
277281

278282
if queryerCtx, ok := c.parent.(driver.QueryerContext); ok {
279283
parentSpan := trace.FromContext(ctx)
@@ -313,7 +317,7 @@ func (c ocConn) QueryContext(ctx context.Context, query string, args []driver.Na
313317
}
314318

315319
func (c ocConn) Prepare(query string) (stmt driver.Stmt, err error) {
316-
defer recordCallStats(context.Background(), "go.sql.prepare")(err)
320+
defer recordCallStats(context.Background(), "go.sql.prepare", c.options.InstanceName)(err)
317321

318322
if c.options.AllowRoot {
319323
_, span := trace.StartSpan(context.Background(), "sql:prepare", trace.WithSpanKind(trace.SpanKindClient))
@@ -349,7 +353,7 @@ func (c *ocConn) Begin() (driver.Tx, error) {
349353
}
350354

351355
func (c *ocConn) PrepareContext(ctx context.Context, query string) (stmt driver.Stmt, err error) {
352-
defer recordCallStats(ctx, "go.sql.prepare")(err)
356+
defer recordCallStats(ctx, "go.sql.prepare", c.options.InstanceName)(err)
353357

354358
var span *trace.Span
355359
attrs := append([]trace.Attribute(nil), c.options.DefaultAttributes...)
@@ -382,7 +386,7 @@ func (c *ocConn) PrepareContext(ctx context.Context, query string) (stmt driver.
382386
}
383387

384388
func (c *ocConn) BeginTx(ctx context.Context, opts driver.TxOptions) (tx driver.Tx, err error) {
385-
defer recordCallStats(ctx, "go.sql.begin")(err)
389+
defer recordCallStats(ctx, "go.sql.begin", c.options.InstanceName)(err)
386390

387391
if !c.options.AllowRoot && trace.FromContext(ctx) == nil {
388392
if connBeginTx, ok := c.parent.(driver.ConnBeginTx); ok {
@@ -479,7 +483,7 @@ type ocStmt struct {
479483
}
480484

481485
func (s ocStmt) Exec(args []driver.Value) (res driver.Result, err error) {
482-
defer recordCallStats(context.Background(), "go.sql.stmt.exec")(err)
486+
defer recordCallStats(context.Background(), "go.sql.stmt.exec", s.options.InstanceName)(err)
483487

484488
if !s.options.AllowRoot {
485489
return s.parent.Exec(args)
@@ -526,7 +530,7 @@ func (s ocStmt) NumInput() int {
526530
}
527531

528532
func (s ocStmt) Query(args []driver.Value) (rows driver.Rows, err error) {
529-
defer recordCallStats(context.Background(), "go.sql.stmt.query")(err)
533+
defer recordCallStats(context.Background(), "go.sql.stmt.query", s.options.InstanceName)(err)
530534

531535
if !s.options.AllowRoot {
532536
return s.parent.Query(args)
@@ -564,7 +568,7 @@ func (s ocStmt) Query(args []driver.Value) (rows driver.Rows, err error) {
564568
}
565569

566570
func (s ocStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (res driver.Result, err error) {
567-
defer recordCallStats(ctx, "go.sql.stmt.exec")(err)
571+
defer recordCallStats(ctx, "go.sql.stmt.exec", s.options.InstanceName)(err)
568572

569573
parentSpan := trace.FromContext(ctx)
570574
if !s.options.AllowRoot && parentSpan == nil {
@@ -603,7 +607,7 @@ func (s ocStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (res
603607
}
604608

605609
func (s ocStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (rows driver.Rows, err error) {
606-
defer recordCallStats(ctx, "go.sql.stmt.query")(err)
610+
defer recordCallStats(ctx, "go.sql.stmt.query", s.options.InstanceName)(err)
607611

608612
parentSpan := trace.FromContext(ctx)
609613
if !s.options.AllowRoot && parentSpan == nil {
@@ -800,7 +804,7 @@ type ocTx struct {
800804
}
801805

802806
func (t ocTx) Commit() (err error) {
803-
defer recordCallStats(context.Background(), "go.sql.commit")(err)
807+
defer recordCallStats(context.Background(), "go.sql.commit", t.options.InstanceName)(err)
804808

805809
_, span := trace.StartSpan(t.ctx, "sql:commit", trace.WithSpanKind(trace.SpanKindClient))
806810
if len(t.options.DefaultAttributes) > 0 {
@@ -816,7 +820,7 @@ func (t ocTx) Commit() (err error) {
816820
}
817821

818822
func (t ocTx) Rollback() (err error) {
819-
defer recordCallStats(context.Background(), "go.sql.rollback")(err)
823+
defer recordCallStats(context.Background(), "go.sql.rollback", t.options.InstanceName)(err)
820824

821825
_, span := trace.StartSpan(t.ctx, "sql:rollback", trace.WithSpanKind(trace.SpanKindClient))
822826
if len(t.options.DefaultAttributes) > 0 {

driver_go1.10.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ var (
1919
// WrapConnector allows wrapping a database driver.Connector which eliminates
2020
// the need to register ocsql as an available driver.Driver.
2121
func WrapConnector(dc driver.Connector, options ...TraceOption) driver.Connector {
22-
opts := TraceOptions{}
22+
opts := TraceOptions{
23+
InstanceName: defaultInstanceName,
24+
}
2325
for _, o := range options {
2426
o(&opts)
2527
}

observability.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import (
1111

1212
// The following tags are applied to stats recorded by this package.
1313
var (
14+
// GoSQLInstance is the SQL instance name.
15+
GoSQLInstance, _ = tag.NewKey("go_sql_instance")
1416
// GoSQLMethod is the SQL method called.
1517
GoSQLMethod, _ = tag.NewKey("go_sql_method")
1618
// GoSQLError is the error received while calling a SQL method.
@@ -79,64 +81,71 @@ var (
7981
Description: "The distribution of latencies of various calls in milliseconds",
8082
Measure: MeasureLatencyMs,
8183
Aggregation: DefaultMillisecondsDistribution,
82-
TagKeys: []tag.Key{GoSQLMethod, GoSQLError, GoSQLStatus},
84+
TagKeys: []tag.Key{GoSQLInstance, GoSQLMethod, GoSQLError, GoSQLStatus},
8385
}
8486

8587
SQLClientCallsView = &view.View{
8688
Name: "go.sql/client/calls",
8789
Description: "The number of various calls of methods",
8890
Measure: MeasureLatencyMs,
8991
Aggregation: view.Count(),
90-
TagKeys: []tag.Key{GoSQLMethod, GoSQLError, GoSQLStatus},
92+
TagKeys: []tag.Key{GoSQLInstance, GoSQLMethod, GoSQLError, GoSQLStatus},
9193
}
9294

9395
SQLClientOpenConnectionsView = &view.View{
9496
Name: "go.sql/db/connections/open",
9597
Description: "The number of open connections",
9698
Measure: MeasureOpenConnections,
9799
Aggregation: view.LastValue(),
100+
TagKeys: []tag.Key{GoSQLInstance},
98101
}
99102

100103
SQLClientIdleConnectionsView = &view.View{
101104
Name: "go.sql/db/connections/idle",
102105
Description: "The number of idle connections",
103106
Measure: MeasureIdleConnections,
104107
Aggregation: view.LastValue(),
108+
TagKeys: []tag.Key{GoSQLInstance},
105109
}
106110

107111
SQLClientActiveConnectionsView = &view.View{
108112
Name: "go.sql/db/connections/active",
109113
Description: "The number of active connections",
110114
Measure: MeasureActiveConnections,
111115
Aggregation: view.LastValue(),
116+
TagKeys: []tag.Key{GoSQLInstance},
112117
}
113118

114119
SQLClientWaitCountView = &view.View{
115120
Name: "go.sql/db/connections/wait_count",
116121
Description: "The total number of connections waited for",
117122
Measure: MeasureWaitCount,
118123
Aggregation: view.LastValue(),
124+
TagKeys: []tag.Key{GoSQLInstance},
119125
}
120126

121127
SQLClientWaitDurationView = &view.View{
122128
Name: "go.sql/db/connections/wait_duration",
123129
Description: "The total time blocked waiting for a new connection",
124130
Measure: MeasureWaitDuration,
125131
Aggregation: view.LastValue(),
132+
TagKeys: []tag.Key{GoSQLInstance},
126133
}
127134

128135
SQLClientIdleClosedView = &view.View{
129136
Name: "go.sql/db/connections/idle_closed_count",
130137
Description: "The total number of connections closed due to SetMaxIdleConns",
131138
Measure: MeasureIdleClosed,
132139
Aggregation: view.LastValue(),
140+
TagKeys: []tag.Key{GoSQLInstance},
133141
}
134142

135143
SQLClientLifetimeClosedView = &view.View{
136144
Name: "go.sql/db/connections/lifetime_closed_count",
137145
Description: "The total number of connections closed due to SetConnMaxLifetime",
138146
Measure: MeasureLifetimeClosed,
139147
Aggregation: view.LastValue(),
148+
TagKeys: []tag.Key{GoSQLInstance},
140149
}
141150

142151
DefaultViews = []*view.View{
@@ -154,7 +163,7 @@ func RegisterAllViews() {
154163
}
155164
}
156165

157-
func recordCallStats(ctx context.Context, method string) func(err error) {
166+
func recordCallStats(ctx context.Context, method, instanceName string) func(err error) {
158167
var tags []tag.Mutator
159168
startTime := time.Now()
160169

@@ -163,11 +172,14 @@ func recordCallStats(ctx context.Context, method string) func(err error) {
163172

164173
if err != nil {
165174
tags = []tag.Mutator{
166-
tag.Insert(GoSQLMethod, method), valueErr, tag.Insert(GoSQLError, err.Error()),
175+
tag.Insert(GoSQLMethod, method),
176+
valueErr,
177+
tag.Insert(GoSQLError, err.Error()),
178+
tag.Insert(GoSQLInstance, instanceName),
167179
}
168180
} else {
169181
tags = []tag.Mutator{
170-
tag.Insert(GoSQLMethod, method), valueOK,
182+
tag.Insert(GoSQLMethod, method), valueOK, tag.Insert(GoSQLInstance, instanceName),
171183
}
172184
}
173185

options.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
// TraceOption allows for managing ocsql configuration using functional options.
88
type TraceOption func(o *TraceOptions)
99

10+
const defaultInstanceName = "default"
11+
1012
// TraceOptions holds configuration of our ocsql tracing middleware.
1113
// By default all options are set to false intentionally when creating a wrapped
1214
// driver and provide the most sensible default with both performance and
@@ -51,6 +53,9 @@ type TraceOptions struct {
5153
// DefaultAttributes will be set to each span as default.
5254
DefaultAttributes []trace.Attribute
5355

56+
// InstanceName identifies database.
57+
InstanceName string
58+
5459
// DisableErrSkip, if set to true, will suppress driver.ErrSkip errors in spans.
5560
DisableErrSkip bool
5661
}
@@ -166,3 +171,10 @@ func WithDisableErrSkip(b bool) TraceOption {
166171
o.DisableErrSkip = b
167172
}
168173
}
174+
175+
// WithInstanceName sets database instance name.
176+
func WithInstanceName(instanceName string) TraceOption {
177+
return func(o *TraceOptions) {
178+
o.InstanceName = instanceName
179+
}
180+
}

0 commit comments

Comments
 (0)