Skip to content

simukti/sqldb-logger

master
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?
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

SQLDB-Logger

Coverage Status Go Report Card Sonar Violations (long format) Sonar Tech Debt Sonar Quality Gate Documentation License

A logger for Go SQL database driver without modify existing *sql.DB stdlib usage.

shameless console output sample Colored console writer output above only for sample/development

FEATURES

  • Leveled, detailed and configurable logging.
  • Keep using (or re-use existing) *sql.DB as is.
  • Bring your own logger backend via simple log interface.
  • Trackable log output:
    • Every call has its own unique ID.
    • Prepared statement and execution will have same ID.
    • On execution/result error, it will include the query, arguments, params, and related IDs.

INSTALL

go get -u -v github.com/simukti/sqldb-logger

Version pinning using dependency manager such as Mod or Dep is highly recommended.

USAGE

As a start, Logger is just a simple interface:

type Logger interface {
	Log(ctx context.Context, level Level, msg string, data map[string]interface{})
}

There are 4 included basic implementation that uses well-known JSON structured logger for quickstart:

Note: those adapters does not use given context, you need to modify it and adjust with your needs. (example: add http request id/whatever value from context to query log when you call QueryerContext andExecerContext methods)

Then for that logger to works, you need to integrate with a compatible driver which will be used by *sql.DB.

INTEGRATE WITH EXISTING SQL DB DRIVER

Re-use from existing *sql.DB driver, this is the simplest way:

For example, from:

dsn := "username:passwd@tcp(mysqlserver:3306)/dbname?parseTime=true"
db, err := sql.Open("mysql", dsn) // db is *sql.DB
db.Ping() // to check connectivity and DSN correctness

To:

// import sqldblogger "github.com/simukti/sqldb-logger"
// import "github.com/simukti/sqldb-logger/logadapter/zerologadapter"
dsn := "username:passwd@tcp(mysqlserver:3306)/dbname?parseTime=true"
db, err := sql.Open("mysql", dsn) // db is *sql.DB
// handle err
loggerAdapter := zerologadapter.New(zerolog.New(os.Stdout))
db = sqldblogger.OpenDriver(dsn, db.Driver(), loggerAdapter/*, using_default_options*/) // db is STILL *sql.DB
db.Ping() // to check connectivity and DSN correctness

That's it, all *sql.DB interaction now logged.

INTEGRATE WITH SQL DRIVER STRUCT

It is also possible to integrate with following public empty struct driver directly:

MySQL (go-sql-driver/mysql)

db := sqldblogger.OpenDriver(dsn, &mysql.MySQLDriver{}, loggerAdapter /*, ...options */)

PostgreSQL (lib/pq)

db := sqldblogger.OpenDriver(dsn, &pq.Driver{}, loggerAdapter /*, ...options */) 

SQLite3 (mattn/go-sqlite3)

db := sqldblogger.OpenDriver(dsn, &sqlite3.SQLiteDriver{}, loggerAdapter /*, ...options */)

Following struct drivers maybe compatible:

SQL Server (denisenkom/go-mssqldb)

db := sqldblogger.OpenDriver(dsn, &mssql.Driver{}, loggerAdapter /*, ...options */)

Oracle (mattn/go-oci8)

db := sqldblogger.OpenDriver(dsn, oci8.OCI8Driver, loggerAdapter /*, ...options */)

LOGGER OPTIONS

When using sqldblogger.OpenDriver(dsn, driver, logger, opt...) without 4th variadic argument, it will use default options.

Here is sample of OpenDriver() using all available options and use non-default value:

db = sqldblogger.OpenDriver(
    dsn, 
    db.Driver(), 
    loggerAdapter,
    // AVAILABLE OPTIONS
    sqldblogger.WithErrorFieldname("sql_error"),                    // default: error
    sqldblogger.WithDurationFieldname("query_duration"),            // default: duration
    sqldblogger.WithTimeFieldname("log_time"),                      // default: time
    sqldblogger.WithSQLQueryFieldname("sql_query"),                 // default: query
    sqldblogger.WithSQLArgsFieldname("sql_args"),                   // default: args
    sqldblogger.WithMinimumLevel(sqldblogger.LevelTrace),           // default: LevelDebug
    sqldblogger.WithLogArguments(false),                            // default: true
    sqldblogger.WithDurationUnit(sqldblogger.DurationNanosecond),   // default: DurationMillisecond
    sqldblogger.WithTimeFormat(sqldblogger.TimeFormatRFC3339),      // default: TimeFormatUnix
    sqldblogger.WithLogDriverErrorSkip(true),                       // default: false
    sqldblogger.WithSQLQueryAsMessage(true),                        // default: false
    sqldblogger.WithUIDGenerator(sqldblogger.UIDGenerator),         // default: *defaultUID
    sqldblogger.WithConnectionIDFieldname("con_id"),                // default: conn_id
    sqldblogger.WithStatementIDFieldname("stm_id"),                 // default: stmt_id
    sqldblogger.WithTransactionIDFieldname("trx_id"),               // default: tx_id
    sqldblogger.WithWrapResult(false),                              // default: true
    sqldblogger.WithIncludeStartTime(true),                         // default: false
    sqldblogger.WithStartTimeFieldname("start_time"),               // default: start
    sqldblogger.WithPreparerLevel(sqldblogger.LevelDebug),          // default: LevelInfo
    sqldblogger.WithQueryerLevel(sqldblogger.LevelDebug),           // default: LevelInfo
    sqldblogger.WithExecerLevel(sqldblogger.LevelDebug),            // default: LevelInfo
)

Click here for options documentation.

MOTIVATION

I want to:

  • Keep using *sql.DB.
  • Have configurable output field.
  • Leverage structured logging.
  • Fetch and log context.Context value if needed.
  • Re-use pgx log interface.

I haven't found Go *sql.DB logger with that features, so why not created myself?

REFERENCES

CONTRIBUTE

If you found a bug, typo, wrong test, idea, help with existing issue, or anything constructive.

Don't hesitate to create an issue or pull request.

CREDITS

  • pgx for awesome PostgreSQL driver.

LICENSE

MIT