Skip to content

openzipkin-contrib/zipkin-go-sql

Folders and files

NameName
Last commit message
Last commit date
Sep 6, 2020
Sep 7, 2020
Sep 6, 2020
Mar 29, 2020
Aug 24, 2023
Apr 2, 2019
Dec 3, 2018
Mar 1, 2019
Apr 2, 2019
Sep 6, 2020
Sep 6, 2020
Apr 2, 2019

Repository files navigation

Zipkin instrumentation SQL

Build Status Go Report Card GoDoc

A SQL wrapper including Zipkin instrumentation

Usage

import (
    _ "github.com/go-sql-driver/mysql"
    zipkinsql "github.com/openzipkin-contrib/zipkin-go-sql"
    zipkin "github.com/openzipkin/zipkin-go"
)

var (
    driverName string
    err        error
    db         *sql.DB
    tracer     *zipkin.Tracer
)

// Register our zipkinsql wrapper for the provided MySQL driver.
driverName, err = zipkinsql.Register("mysql", tracer, zipkinsql.WithAllTraceOptions())
if err != nil {
    log.Fatalf("unable to register zipkin driver: %v\n", err)
}

// Connect to a MySQL database using the zipkinsql driver wrapper.
db, err = sql.Open(driverName, "mysql://user:[email protected]:3306/db")

You can also wrap your own driver with zipkin instrumentation as follows:

import (
    mysql "github.com/go-sql-driver/mysql"
    zipkinsql "github.com/openzipkin-contrib/zipkin-go-sql"
    zipkinmodel "github.com/openzipkin/zipkin-go/model"
)

var (
    driver driver.Driver
    err    error
    db     *sql.DB
    tracer *zipkin.Tracer
)

// Explicitly wrap the MySQL driver with zipkinsql
driver = zipkinsql.Wrap(
    &mysql.MySQLDriver{},
    tracer,
    zipkinsql.WithRemoteEndpoint(zipkinmodel.Endpoint{
        ServiceName: "resultsdb",
        Port: 5432
    }),
)

// Register our zipkinsql wrapper as a database driver
sql.Register("zipkinsql-mysql", driver)

// Connect to a MySQL database using the zipkinsql driver wrapper
db, err = sql.Open("zipkinsql-mysql", "mysql://user:[email protected]:3306/db")

Projects providing their own abstractions on top of database/sql/driver can also wrap an existing driver.Conn interface directly with zipkinsql.

import zipkinsql "github.com/openzipkin-contrib/zipkin-go-sql"

func initializeConn(...) driver.Conn {
    // create custom driver.Conn
    conn := Connect(...)

    // wrap with zipkinsql
    return zipkinsql.WrapConn(conn, tracer, zipkinsql.WithAllTraceOptions())
}

Go 1.10+ provides a new driver.Connector interface that can be wrapped directly by zipkinsql without the need for zipkinsql to register a driver.Driver.

Example:

import(
    zipkinsql "github.com/openzipkin-contrib/zipkin-go-sql"
    "github.com/lib/pq"
)
var (
    connector driver.Connector
    err       error
    db        *sql.DB
    tracer *zipkin.Tracer
)

connector, err = pq.NewConnector("postgres://user:pass@host:5432/db")
if err != nil {
    log.Fatalf("unable to create postgres connector: %v\n", err)
}
// Wrap the driver.Connector with zipkinsql.
connector = zipkinsql.WrapConnector(connector, tracer, zipkinsql.WithAllTraceOptions())
// Use the wrapped driver.Connector.
db = sql.OpenDB(connector)

Using jmoiron/sqlx

If using the sqlx library with named queries you will need to use the sqlx.NewDb function to wrap an existing *sql.DB connection. sqlx.Open and sqlx.Connect methods won't work.

First create a *sql.DB connection and then create a *sqlx.DB connection by wrapping the former and keeping the same driver name e.g.:

driverName, err := zipkinsql.Register("postgres", zipkinsql.WithAllTraceOptions())
if err != nil { ... }

db, err := sql.Open(driverName, "postgres://localhost:5432/my_database")
if err != nil { ... }

// Keep the driver name!
dbx := sqlx.NewDb(db, "postgres")

Usage of *Context methods

Instrumentation is possible if the context is being passed downstream in methods. This is not only for instrumentation purposes but also a good practice in go programming. database/sql package exposes already a set of methods that receive the context as first paramenter:

  • *DB.Begin -> *DB.BeginTx
  • *DB.Exec -> *DB.ExecContext
  • *DB.Ping -> *DB.PingContext
  • *DB.Prepare -> *DB.PrepareContext
  • *DB.Query -> *DB.QueryContext
  • *DB.QueryRow -> *DB.QueryRowContext
  • *Stmt.Exec -> *Stmt.ExecContext
  • *Stmt.Query -> *Stmt.QueryContext
  • *Stmt.QueryRow -> *Stmt.QueryRowContext
  • *Tx.Exec -> *Tx.ExecContext
  • *Tx.Prepare -> *Tx.PrepareContext
  • *Tx.Query -> *Tx.QueryContext
  • *Tx.QueryRow -> *Tx.QueryRowContext