Skip to content

Commit

Permalink
fix/feature: fix and extend debug logging (#59)
Browse files Browse the repository at this point in the history
This commit allows devs to specify a logger via
WithLogger(...) which implements the LogWriter
interface. By providing a logger that implements
LogWriter, devs can override the default logging
behavior for a logger (the default only emits
postgres errors)
  • Loading branch information
jimlambrt authored Sep 9, 2024
1 parent b637c1e commit 6cee92b
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 10 deletions.
34 changes: 26 additions & 8 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,21 @@ func openDialector(dialect gorm.Dialector, opt ...Option) (*DB, error) {
}
opts := GetOpts(opt...)
if opts.WithLogger != nil {
newLogger := logger.New(
getGormLogger(opts.WithLogger),
logger.Config{
LogLevel: logger.LogLevel(opts.withLogLevel), // Log level
Colorful: false, // Disable color
},
)
var newLogger logger.Interface
loggerConfig := logger.Config{
LogLevel: logger.LogLevel(opts.withLogLevel), // Log level
Colorful: false, // Disable color
}
switch v := opts.WithLogger.(type) {
case LogWriter:
// it's already a gorm logger, so we just need to configure it
newLogger = logger.New(v, loggerConfig)
default:
newLogger = logger.New(
getGormLogger(opts.WithLogger), // wrap the hclog with a gorm logger that only logs errors
loggerConfig,
)
}
db = db.Session(&gorm.Session{Logger: newLogger})
}
if opts.WithMaxOpenConnections > 0 {
Expand All @@ -228,7 +236,17 @@ func openDialector(dialect gorm.Dialector, opt ...Option) (*DB, error) {
}
underlyingDB.SetMaxOpenConns(opts.WithMaxOpenConnections)
}
return &DB{wrapped: db}, nil

ret := &DB{wrapped: db}
ret.Debug(opts.WithDebug)
return ret, nil
}

// LogWriter defines an interface which can be used when passing a logger via
// WithLogger(...). This interface allows callers to override the default
// behavior for a logger (the default only emits postgres errors)
type LogWriter interface {
Printf(string, ...any)
}

type gormLogger struct {
Expand Down
39 changes: 39 additions & 0 deletions db_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import (
"fmt"
"io/ioutil"
"os"
"strings"
"sync"
"testing"

"github.com/hashicorp/go-dbw"
Expand Down Expand Up @@ -137,6 +139,43 @@ func TestDB_OpenWith(t *testing.T) {
_, err := dbw.OpenWith(sqlite.Open("file::memory:"), nil)
assert.NoError(err)
})
t.Run("sqlite-with-logger", func(t *testing.T) {
assert, require := assert.New(t), require.New(t)
buf := new(strings.Builder)
testLock := &sync.Mutex{}
testLogger := hclog.New(&hclog.LoggerOptions{
Mutex: testLock,
Name: "test",
JSONFormat: true,
Output: buf,
Level: hclog.Debug,
})
d, err := dbw.OpenWith(sqlite.Open("file::memory:"), dbw.WithLogger(gormDebugLogger{Logger: testLogger}), dbw.WithDebug(true))
require.NoError(err)
require.NotEmpty(d)
rw := dbw.New(d)
const sql = "select 'hello world'"
testCtx := context.Background()
rows, err := rw.Query(testCtx, sql, nil)
require.NoError(err)
defer rows.Close()
assert.Contains(buf.String(), sql)
t.Log(buf.String())
})
}

type gormDebugLogger struct {
hclog.Logger
}

func (g gormDebugLogger) Printf(msg string, values ...interface{}) {
b := new(strings.Builder)
fmt.Fprintf(b, msg, values...)
g.Debug(b.String())
}

func getGormLogger(log hclog.Logger) gormDebugLogger {
return gormDebugLogger{Logger: log}
}

func TestDB_StringToDbType(t *testing.T) {
Expand Down
8 changes: 6 additions & 2 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ type Options struct {
WithPrngValues []string

// WithLogger specifies an optional hclog to use for db operations. It's only
// valid for Open(..) and OpenWith(...)
// valid for Open(..) and OpenWith(...) The logger provided can optionally
// implement the LogWriter interface as well which would override the default
// behavior for a logger (the default only emits postgres errors)
WithLogger hclog.Logger

// WithMinOpenConnections specifies and optional min open connections for the
Expand Down Expand Up @@ -214,7 +216,9 @@ func WithPrngValues(withPrngValues []string) Option {
}

// WithLogger specifies an optional hclog to use for db operations. It's only
// valid for Open(..) and OpenWith(...)
// valid for Open(..) and OpenWith(...). The logger provided can optionally
// implement the LogWriter interface as well which would override the default
// behavior for a logger (the default only emits postgres errors)
func WithLogger(l hclog.Logger) Option {
return func(o *Options) {
o.WithLogger = l
Expand Down

0 comments on commit 6cee92b

Please sign in to comment.