Golang Sqlite3 Db Sql Tracer

published: [nandalism home] (dark light)

How This Works - database/sql Driver Wrapper

It seems the best way to instrument your golang database/sql code is to write a wrapper which pretends to be a db driver but actually forwards the commands to the real db driver, after tracing/logging them.

If you just want to trace, there is a much more complete system at github.com/ExpansiveWorlds/instrumentedsql. The intention of this post is to show how to write your own.

Here is the full dbtracer module.

Use

In your code import the dbtracer driver instead of the normal sqlite3 driver. Nothing else should change. Tracing will appear in your log.

  # yourdbcode.go
  import (
    _ "src.deckc.hair/nandalism/dbtracer"
  )

  // dbpool, err := sql.Open("sqlite3", database_path)
  dbpool, err := sql.Open("dbtracer", database_path)

The Code

The code is very short (around 100 lines). Many more things could be added, but this provides a minimal example of writing a golang db/sql driver wrapper. You will need to implement 3 interfaces.

The driver.Driver:

type TracerDriver struct {...}
func (d *TracerDriver) Open(name string) (conn driver.Conn, err error)

The driver.Conn, connection interface:

type TracerConn struct {...}
func (c *TracerConn) Prepare(query string) (s driver.Stmt, err error) <--- this is where you capture the sql template
func (c *TracerConn) Close() (err error)
func (c *TracerConn) Begin() (tx driver.Tx, err error)

The driver.Stmt, statement interface:

type TracerStmt struct {...}
func (s *TracerStmt) Close() error
func (s *TracerStmt) NumInput() int

// here you fill in the values in the sql template captured and log the actual sql statement
func (s *TracerStmt) Exec(args []driver.Value) (driver.Result, error)
func (s *TracerStmt) Query(args []driver.Value) (driver.Rows, error)

site built using mf technology