Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Zipkin instrumentation SQL

Build Status Go Report Card GoDoc

A SQL wrapper including Zipkin instrumentation


import (
    _ ""
    zipkinsql ""
    zipkin ""

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:pass@")

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

import (
    mysql ""
    zipkinsql ""
    zipkinmodel ""

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

// Explicitly wrap the MySQL driver with zipkinsql
driver = zipkinsql.Wrap(
        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:pass@")

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

import zipkinsql ""

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.


    zipkinsql ""
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