Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(gorm): gorm v2 migration (#170)
* feat(gorm): upgrade gorm to v2
+ add new db method for closing
TODO: add log support through logrus to gorm db

* feat(gorm.v2): add logrus support + fix linter issues
  • Loading branch information
hbollon committed Jun 16, 2021
1 parent 6a9f151 commit 630ce3f
Show file tree
Hide file tree
Showing 6 changed files with 300 additions and 10 deletions.
28 changes: 21 additions & 7 deletions db/db.go
Expand Up @@ -15,11 +15,10 @@ import (
"github.com/hashicorp/terraform/states/statefile"
log "github.com/sirupsen/logrus"

"github.com/jinzhu/gorm"
ctyJson "github.com/zclconf/go-cty/cty/json"

// Use postgres as a DB backend
_ "github.com/jinzhu/gorm/dialects/postgres"
"gorm.io/driver/postgres"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)

// Database is a wrapping structure to *gorm.DB
Expand All @@ -41,13 +40,15 @@ func Init(config config.DBConfig, debug bool) *Database {
config.SSLMode,
config.Password,
)
db, err := gorm.Open("postgres", connString)
db, err := gorm.Open(postgres.Open(connString), &gorm.Config{
Logger: &LogrusGormLogger,
})
if err != nil {
log.Fatal(err)
}

log.Infof("Automigrate")
db.AutoMigrate(
err = db.AutoMigrate(
&types.Version{},
&types.State{},
&types.Module{},
Expand All @@ -68,9 +69,12 @@ func Init(config config.DBConfig, debug bool) *Database {
&types.PlanStateValue{},
&types.Change{},
)
if err != nil {
log.Fatalf("Migration failed: %v\n", err)
}

if debug {
db.LogMode(true)
db.Config.Logger.LogMode(logger.Info)
}
return &Database{db}
}
Expand Down Expand Up @@ -505,3 +509,13 @@ func (db *Database) DefaultVersion(path string) (version string, err error) {
err = row.Scan(&version)
return
}

// Close get generic database interface *sql.DB from the current *gorm.DB
// and close it
func (db *Database) Close() {
sqlDb, err := db.DB.DB()
if err != nil {
log.Fatalf("Unable to terminate db instance: %v\n", err)
}
sqlDb.Close()
}
97 changes: 97 additions & 0 deletions db/logger.go
@@ -0,0 +1,97 @@
package db

import (
"context"
"fmt"
"time"

"github.com/sirupsen/logrus"
"gorm.io/gorm/logger"
"gorm.io/gorm/utils"
)

/*********************************************
* Custom logger definition for Gorm to use Logrus
* Implement gorm Logger iterface
* Based on : https://github.com/go-gorm/gorm/blob/master/logger/logger.go
*********************************************/

// GormLogger is a wrapper class that implement Gorm logger interface
type GormLogger struct {
GormLoggerConfig
}

// GormLoggerConfig handle GormLogger config (log level, slow threshold)
type GormLoggerConfig struct {
LogLevel logger.LogLevel
SlowThreshold time.Duration
}

var (
// LogrusGormLogger default GormLogger instance for Gorm logging through Logrus
LogrusGormLogger = GormLogger{
GormLoggerConfig{
LogLevel: logger.Warn,
SlowThreshold: 200 * time.Millisecond,
},
}
)

// LogMode log mode
func (l *GormLogger) LogMode(level logger.LogLevel) logger.Interface {
newlogger := *l
l.LogLevel = level
return &newlogger
}

// Info print info
func (l *GormLogger) Info(_ context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Info {
logrus.Info(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
}
}

// Warn print warn messages
func (l *GormLogger) Warn(_ context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Warn {
logrus.Warn(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
}
}

// Error print error messages
func (l *GormLogger) Error(_ context.Context, msg string, data ...interface{}) {
if l.LogLevel >= logger.Error {
logrus.Warn(msg, append([]interface{}{utils.FileWithLineNum()}, data...))
}
}

// Trace print sql message
func (l *GormLogger) Trace(_ context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.LogLevel > 0 {
elapsed := time.Since(begin)
switch {
case err != nil && l.LogLevel >= logger.Error:
sql, rows := fc()
if rows == -1 {
logrus.Trace(utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
logrus.Trace(utils.FileWithLineNum(), err, float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= logger.Warn:
sql, rows := fc()
slowLog := fmt.Sprintf("SLOW SQL >= %v", l.SlowThreshold)
if rows == -1 {
logrus.Trace(utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
logrus.Trace(utils.FileWithLineNum(), slowLog, float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
case l.LogLevel >= logger.Info:
sql, rows := fc()
if rows == -1 {
logrus.Trace(utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, "-", sql)
} else {
logrus.Trace(utils.FileWithLineNum(), float64(elapsed.Nanoseconds())/1e6, rows, sql)
}
}
}
}
6 changes: 5 additions & 1 deletion go.mod
Expand Up @@ -13,8 +13,8 @@ require (
github.com/hashicorp/go-tfe v0.12.0
github.com/hashicorp/go-version v1.2.1 // indirect
github.com/hashicorp/terraform v0.15.0
github.com/jackc/pgproto3/v2 v2.0.7 // indirect
github.com/jessevdk/go-flags v1.4.0
github.com/jinzhu/gorm v1.9.16
github.com/lib/pq v1.9.0 // indirect
github.com/machinebox/graphql v0.2.2
github.com/matryer/is v1.4.0 // indirect
Expand All @@ -25,9 +25,13 @@ require (
github.com/spf13/afero v1.5.1 // indirect
github.com/zclconf/go-cty v1.8.1
go.opencensus.io v0.22.6 // indirect
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect
golang.org/x/oauth2 v0.0.0-20210201163806-010130855d6c // indirect
golang.org/x/text v0.3.6 // indirect
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
google.golang.org/api v0.38.0
gopkg.in/yaml.v2 v2.4.0
gorm.io/datatypes v1.0.1
gorm.io/driver/postgres v1.1.0 // indirect
gorm.io/gorm v1.21.10 // indirect
)

0 comments on commit 630ce3f

Please sign in to comment.