Skip to content

simukti/sqldb-logger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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:

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

PostgreSQL (lib/pq)

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

Following struct drivers maybe compatible:

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

About

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

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published