diff --git a/dialect/dialect.go b/dialect/dialect.go index 1a07a45c2..5bd6afa56 100644 --- a/dialect/dialect.go +++ b/dialect/dialect.go @@ -64,29 +64,37 @@ func NopTx(d Driver) Tx { // DebugDriver is a driver that logs all driver operations. type DebugDriver struct { - Driver // underlying driver. - log func(...interface{}) // log function. defaults to log.Println. + Driver // underlying driver. + log func(context.Context, ...interface{}) // log function. defaults to log.Println. } // Debug gets a driver and an optional logging function, and returns // a new debugged-driver that prints all outgoing operations. func Debug(d Driver, logger ...func(...interface{})) Driver { - drv := &DebugDriver{d, log.Println} + logf := log.Println if len(logger) == 1 { - drv.log = logger[0] + logf = logger[0] } + drv := &DebugDriver{d, func(_ context.Context, v ...interface{}) { logf(v...) }} + return drv +} + +// DebugWithContext gets a driver and a logging function, and returns +// a new debugged-driver that prints all outgoing operations with context. +func DebugWithContext(d Driver, logger func(context.Context, ...interface{})) Driver { + drv := &DebugDriver{d, logger} return drv } // Exec logs its params and calls the underlying driver Exec method. func (d *DebugDriver) Exec(ctx context.Context, query string, args, v interface{}) error { - d.log(fmt.Sprintf("driver.Exec: query=%v args=%v", query, args)) + d.log(ctx, fmt.Sprintf("driver.Exec: query=%v args=%v", query, args)) return d.Driver.Exec(ctx, query, args, v) } // Query logs its params and calls the underlying driver Query method. func (d *DebugDriver) Query(ctx context.Context, query string, args, v interface{}) error { - d.log(fmt.Sprintf("driver.Query: query=%v args=%v", query, args)) + d.log(ctx, fmt.Sprintf("driver.Query: query=%v args=%v", query, args)) return d.Driver.Query(ctx, query, args, v) } @@ -97,37 +105,38 @@ func (d *DebugDriver) Tx(ctx context.Context) (Tx, error) { return nil, err } id := uuid.New().String() - d.log(fmt.Sprintf("driver.Tx(%s): started", id)) - return &DebugTx{tx, id, d.log}, nil + d.log(ctx, fmt.Sprintf("driver.Tx(%s): started", id)) + return &DebugTx{tx, id, d.log, ctx}, nil } // DebugTx is a transaction implementation that logs all transaction operations. type DebugTx struct { - Tx // underlying transaction. - id string // transaction logging id. - log func(...interface{}) // log function. defaults to fmt.Println. + Tx // underlying transaction. + id string // transaction logging id. + log func(context.Context, ...interface{}) // log function. defaults to fmt.Println. + ctx context.Context // underlying transaction context. } // Exec logs its params and calls the underlying transaction Exec method. func (d *DebugTx) Exec(ctx context.Context, query string, args, v interface{}) error { - d.log(fmt.Sprintf("Tx(%s).Exec: query=%v args=%v", d.id, query, args)) + d.log(ctx, fmt.Sprintf("Tx(%s).Exec: query=%v args=%v", d.id, query, args)) return d.Tx.Exec(ctx, query, args, v) } // Query logs its params and calls the underlying transaction Query method. func (d *DebugTx) Query(ctx context.Context, query string, args, v interface{}) error { - d.log(fmt.Sprintf("Tx(%s).Query: query=%v args=%v", d.id, query, args)) + d.log(ctx, fmt.Sprintf("Tx(%s).Query: query=%v args=%v", d.id, query, args)) return d.Tx.Query(ctx, query, args, v) } // Commit logs this step and calls the underlying transaction Commit method. func (d *DebugTx) Commit() error { - d.log(fmt.Sprintf("Tx(%s): committed", d.id)) + d.log(d.ctx, fmt.Sprintf("Tx(%s): committed", d.id)) return d.Tx.Commit() } // Rollback logs this step and calls the underlying transaction Rollback method. func (d *DebugTx) Rollback() error { - d.log(fmt.Sprintf("Tx(%s): rollbacked", d.id)) + d.log(d.ctx, fmt.Sprintf("Tx(%s): rollbacked", d.id)) return d.Tx.Rollback() }