zipkinsql

package module
v0.0.0-...-296145a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 29, 2020 License: MIT Imports: 9 Imported by: 2

README

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/jcchavezs/zipkin-instrumentation-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, "postgres://user:pass@127.0.0.1:5432/db")

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


import (
    mysql "github.com/go-sql-driver/mysql"
    zipkinsql "github.com/jcchavezs/zipkin-instrumentation-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", "postgres://user:pass@127.0.0.1:5432/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/jcchavezs/zipkin-instrumentation-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/jcchavezs/zipkin-instrumentation-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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var AllTraceOptions = TraceOptions{
	AllowRootSpan:    true,
	RowsAffectedSpan: true,
	LastInsertIDSpan: true,
	TagQuery:         true,
	TagQueryParams:   true,
	TagAffectedRows:  true,
	RemoteEndpoint:   nil,
}

AllTraceOptions has all tracing options enabled.

Functions

func Register

func Register(driverName string, tracer *zipkin.Tracer, options ...TraceOption) (string, error)

Register initializes and registers our zipkinsql wrapped database driver identified by its driverName and using provided TraceOptions. On success it returns the generated driverName to use when calling sql.Open. It is possible to register multiple wrappers for the same database driver if needing different TraceOptions for different connections.

func Wrap

func Wrap(d driver.Driver, t *zipkin.Tracer, options ...TraceOption) driver.Driver

Wrap takes a SQL driver and wraps it with Zipkin instrumentation.

func WrapConn

func WrapConn(c driver.Conn, t *zipkin.Tracer, options ...TraceOption) driver.Conn

WrapConn allows an existing driver.Conn to be wrapped by zipkinsql.

func WrapConnector

func WrapConnector(dc driver.Connector, t *zipkin.Tracer, options ...TraceOption) driver.Connector

WrapConnector allows wrapping a database driver.Connector which eliminates the need to register zipkinsql as an available driver.Driver.

Types

type TraceOption

type TraceOption func(o *TraceOptions)

TraceOption allows for managing zipkinsql configuration using functional options.

func WithAllTraceOptions

func WithAllTraceOptions() TraceOption

WithAllTraceOptions enables all available trace options.

func WithAllowRootSpan

func WithAllowRootSpan(b bool) TraceOption

WithAllowRootSpan if set to true, will allow zipkinsql to create root spans in absence of exisiting spans or even context. Default is to not trace zipkinsql calls if no existing parent span is found in context or when using methods not taking context.

func WithDefaultTags

func WithDefaultTags(tags map[string]string) TraceOption

WithDefaultTags will be set to each span as default.

func WithLastInsertIDSpan

func WithLastInsertIDSpan(b bool) TraceOption

WithLastInsertIDSpan if set to true, will enable the creation of spans on LastInsertId calls.

func WithOptions

func WithOptions(options TraceOptions) TraceOption

WithOptions sets the zipkinsql tracing middleware options through a single TraceOptions object.

func WithRemoteEndpoint

func WithRemoteEndpoint(e model.Endpoint) TraceOption

WithRemoteEndpoint will be set to each client span

func WithRowsAffectedSpan

func WithRowsAffectedSpan(b bool) TraceOption

WithRowsAffectedSpan if set to true, will enable the creation of spans on RowsAffected calls.

func WithTagAffectedRows

func WithTagAffectedRows(b bool) TraceOption

WithTagAffectedRows if set to true, will enable recording of the affected rows number in spans.

func WithTagQuery

func WithTagQuery(b bool) TraceOption

WithTagQuery if set to true, will enable recording of SQL queries in spans. Only allow this if it is safe to have queries recorded with respect to security.

func WithTagQueryParams

func WithTagQueryParams(b bool) TraceOption

WithTagQueryParams if set to true, will enable recording of parameters used with parametrized queries. Only allow this if it is safe to have parameters recorded with respect to security. This setting is a noop if the TagQuery option is set to false.

type TraceOptions

type TraceOptions struct {
	// AllowRoot, if set to true, will allow zipkinsql to create root spans in
	// absence of existing spans or even context.
	// Default is to not trace zipkinsql calls if no existing parent span is found
	// in context or when using methods not taking context.
	AllowRootSpan bool

	// LastInsertIDSpan, if set to true, will enable the creation of spans on
	// LastInsertId calls.
	LastInsertIDSpan bool

	// RowsAffectedSpan, if set to true, will enable the creation of spans on
	// RowsAffectedSpan calls.
	RowsAffectedSpan bool

	// TagQuery, if set to true, will enable recording of sql queries in spans.
	// Only allow this if it is safe to have queries recorded with respect to
	// security.
	TagQuery bool

	// TagQueryParams, if set to true, will enable recording of parameters used
	// with parametrized queries. Only allow this if it is safe to have
	// parameters recorded with respect to security and privacy.
	// This setting is a noop if the TagQuery option is set to false.
	TagQueryParams bool

	// TagAffectedRows, if set to true, will enable the recording of the number of
	// affected rows for the query. Some engines may include this in the response
	// of the query but some require an extra query to obtain the number of affected
	// rows.
	TagAffectedRows bool

	// DefaultTags will be set to each span as default.
	DefaultTags map[string]string

	// RemoteEndpoint will include the remote endpoint information into the client
	// span.
	RemoteEndpoint *model.Endpoint
}

TraceOptions holds configuration of our zipkinsql tracing middleware. By default all boolean options are set to false intentionally when creating a wrapped driver and provide the most sensible default with both performance and security in mind.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL