Instrumenting database/sql with OpenTelemetry

Introduction

otelsqlopen in new window is an instrumentation for database/sql that records database queries and reports sql.DBStats metrics.

Installation

To install otelsql:

go get github.com/uptrace/opentelemetry-go-extra/otelsql

Usage

To instrument database/sql, you need to connect to a database using the API provided by this package:

sqlotelsql
sql.Open(driverName, dsn)otelsql.Open(driverName, dsn)
sql.OpenDB(connector)otelsql.OpenDB(connector)
import (
	"github.com/uptrace/opentelemetry-go-extra/otelsql"
	semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)

db, err := otelsql.Open("sqlite", "file::memory:?cache=shared",
	otelsql.WithAttributes(semconv.DBSystemSqlite),
	otelsql.WithDBName("mydb"))
if err != nil {
	panic(err)
}

And then use context-aware API to propagateopen in new window the active span:

var num int
if err := db.QueryRowContext(ctx, "SELECT 42").Scan(&num); err != nil {
	panic(err)
}

See exampleopen in new window for details.

Options

Both otelsql.Openopen in new window and otelsql.OpenDBopen in new window accept the same optionsopen in new window:

sqlboiler

You can use otelsql to instrument sqlboileropen in new window ORM:

import (
    "github.com/uptrace/opentelemetry-go-extra/otelsql"
    semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)

db, err := otelsql.Open("postgres", "dbname=fun user=abc",
    otelsql.WithAttributes(semconv.DBSystemPostgreSQL))
if err != nil {
  return err
}

boil.SetDB(db)

GORM 1

You can use otelsql to instrument GORM 1open in new window:

import (
    "github.com/jinzhu/gorm"
    "github.com/uptrace/opentelemetry-go-extra/otelsql"
    semconv "go.opentelemetry.io/otel/semconv/v1.4.0"
)

// gormOpen is like gorm.Open, but it uses otelsql to instrument the database.
func gormOpen(driverName, dataSourceName string, opts ...otelsql.Option) (*gorm.DB, error) {
	db, err := otelsql.Open(driverName, dataSourceName, opts...)
	if err != nil {
		return nil, err
	}
	return gorm.Open(driverName, db)
}

db, err := gormOpen("mysql", "user:password@/dbname",
    otelsql.WithAttributes(semconv.DBSystemMySQL))
if err != nil {
    panic(err)
}

To instrument GORM 2, use otelgorm.

What is next?

Next, instrumentopen in new window more operations (for example, database queries or error logs) or learn about OpenTelemetry API to create your own instrumentations.