feat: add custom logger wrapper to use zap logger for database

This commit is contained in:
Derrick Hammer 2024-02-24 08:41:40 -05:00
parent b5b0ed64b6
commit f6f9a7f97a
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
4 changed files with 87 additions and 8 deletions

View File

@ -23,7 +23,7 @@ import (
func main() { func main() {
logger := _logger.NewLogger() logger, logLevel := _logger.NewLogger()
cfg, err := config.NewManager(logger) cfg, err := config.NewManager(logger)
if err != nil { if err != nil {
@ -50,7 +50,7 @@ func main() {
fx.New( fx.New(
fx.Supply(cfg), fx.Supply(cfg),
fx.Supply(logger), fx.Supply(logger, logLevel),
fxLogger, fxLogger,
fx.Invoke(initCheckRequiredConfig), fx.Invoke(initCheckRequiredConfig),
fx.Provide(NewIdentity), fx.Provide(NewIdentity),

View File

@ -21,6 +21,7 @@ type DatabaseParams struct {
fx.In fx.In
Config *config.Manager Config *config.Manager
Logger *zap.Logger Logger *zap.Logger
LoggerLevel *zap.AtomicLevel
} }
var Module = fx.Module("db", var Module = fx.Module("db",
@ -39,7 +40,9 @@ func NewDatabase(lc fx.Lifecycle, params DatabaseParams) *gorm.DB {
dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local", username, password, host, port, dbname, charset) dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=%s&parseTime=True&loc=Local", username, password, host, port, dbname, charset)
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
Logger: newLogger(params.Logger, params.LoggerLevel),
})
if err != nil { if err != nil {
panic(err) panic(err)
} }

75
db/logger.go Normal file
View File

@ -0,0 +1,75 @@
package db
import (
"context"
"strconv"
"time"
"go.uber.org/zap"
dbLogger "gorm.io/gorm/logger"
)
var _ dbLogger.Interface = (*logger)(nil)
var (
levels = map[dbLogger.LogLevel]zap.AtomicLevel{
dbLogger.Silent: zap.NewAtomicLevelAt(zap.InfoLevel),
dbLogger.Error: zap.NewAtomicLevelAt(zap.ErrorLevel),
dbLogger.Warn: zap.NewAtomicLevelAt(zap.WarnLevel),
dbLogger.Info: zap.NewAtomicLevelAt(zap.InfoLevel),
}
)
type logger struct {
logger *zap.Logger
level *zap.AtomicLevel
}
func (l logger) LogMode(level dbLogger.LogLevel) dbLogger.Interface {
if atomicLevel, ok := levels[level]; ok {
l.level.SetLevel(atomicLevel.Level())
return l
}
l.logger.Fatal("invalid log level", zap.Int("level", int(level)))
return nil
}
func (l logger) Info(ctx context.Context, s string, i ...interface{}) {
l.logger.Info(s, interfacesToFields(i...)...)
}
func (l logger) Warn(ctx context.Context, s string, i ...interface{}) {
l.logger.Warn(s, interfacesToFields(i...)...)
}
func (l logger) Error(ctx context.Context, s string, i ...interface{}) {
l.logger.Error(s, interfacesToFields(i...)...)
}
func (l logger) Trace(ctx context.Context, begin time.Time, fc func() (sql string, rowsAffected int64), err error) {
if l.level.Level() <= zap.DebugLevel {
sql, rowsAffected := fc()
fields := []zap.Field{
zap.String("sql", sql),
zap.Int64("rows_affected", rowsAffected),
zap.Duration("elapsed", time.Since(begin)),
}
if err != nil {
fields = append(fields, zap.Error(err))
}
l.logger.Debug("trace", fields...)
}
}
func newLogger(zlog *zap.Logger, zlogLevel *zap.AtomicLevel) *logger {
return &logger{logger: zlog, level: zlogLevel}
}
func interfacesToFields(i ...interface{}) []zap.Field {
fields := make([]zap.Field, 0)
for idx, v := range i {
fields = append(fields, zap.Any(strconv.Itoa(idx), v))
}
return fields
}

View File

@ -1,10 +1,11 @@
package logger package logger
import ( import (
"os"
"github.com/spf13/viper" "github.com/spf13/viper"
"go.uber.org/zap" "go.uber.org/zap"
"go.uber.org/zap/zapcore" "go.uber.org/zap/zapcore"
"os"
) )
func NewFallbackLogger() *zap.Logger { func NewFallbackLogger() *zap.Logger {
@ -13,7 +14,7 @@ func NewFallbackLogger() *zap.Logger {
return logger return logger
} }
func NewLogger() *zap.Logger { func NewLogger() (*zap.Logger, *zap.AtomicLevel) {
// Create a new atomic level // Create a new atomic level
atomicLevel := zap.NewAtomicLevel() atomicLevel := zap.NewAtomicLevel()
@ -28,7 +29,7 @@ func NewLogger() *zap.Logger {
atomicLevel, atomicLevel,
)) ))
return logger return logger, &atomicLevel
} }
func mapLogLevel(level string) zapcore.Level { func mapLogLevel(level string) zapcore.Level {