Files
base/internal/pkg/database/logger.go
2026-04-10 18:25:21 +03:30

95 lines
2.1 KiB
Go

package database
import (
"context"
"errors"
"time"
"github.com/rs/zerolog"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
type GormLogger struct {
logger zerolog.Logger
slowThreshold time.Duration
logLevel logger.LogLevel
}
func (l *GormLogger) LogMode(level logger.LogLevel) logger.Interface {
newLogger := *l
newLogger.logLevel = level
return &newLogger
}
func (l *GormLogger) Info(ctx context.Context, msg string, data ...interface{}) {
if l.logLevel >= logger.Info {
l.logger.Info().Msgf(msg, data...)
}
}
func (l *GormLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
if l.logLevel >= logger.Warn {
l.logger.Warn().Msgf(msg, data...)
}
}
func (l *GormLogger) Error(ctx context.Context, msg string, data ...interface{}) {
if l.logLevel >= logger.Error {
l.logger.Error().Msgf(msg, data...)
}
}
func (l *GormLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.logLevel <= logger.Silent {
return
}
elapsed := time.Since(begin)
sql, rows := fc()
switch {
// cache miss / record not found - expected, don't log as error
case err != nil && errors.Is(err, gorm.ErrRecordNotFound):
if l.logLevel >= logger.Info {
l.logger.Debug().
Str("sql", sql).
Int64("rows", rows).
Dur("elapsed", elapsed).
Msg("QueryCacheMiss")
}
// error query
case err != nil && l.logLevel >= logger.Error:
l.logger.Error().
Err(err).
Str("sql", sql).
Int64("rows", rows).
Dur("elapsed", elapsed).
Msg("QueryError")
// slow query
case elapsed > l.slowThreshold && l.logLevel >= logger.Warn:
l.logger.Warn().
Str("sql", sql).
Int64("rows", rows).
Dur("elapsed", elapsed).
Msg("SlowQuery")
// normal query
case l.logLevel >= logger.Info:
l.logger.Debug().
Str("sql", sql).
Int64("rows", rows).
Dur("elapsed", elapsed).
Msg("Query")
}
}
func NewGormLogger(serviceLogger zerolog.Logger, threshold time.Duration) *GormLogger {
return &GormLogger{
logger: serviceLogger.With().Str("module", "gorm").Logger(),
slowThreshold: threshold,
logLevel: logger.Warn, // default
}
}