cargo-platform/internal/logger/database.go
2026-08-16 01:40:21 +07:00

93 lines
2.6 KiB
Go

package logger
import (
"context"
"errors"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
gormlogger "gorm.io/gorm/logger"
"gorm.io/gorm/utils"
)
// GormZapLogger adalah custom logger GORM yang menggunakan Zap
type GormZapLogger struct {
ZapLogger *zap.Logger
LogLevel gormlogger.LogLevel
SlowThreshold time.Duration
}
// NewGormZapLogger menginisialisasi logger baru
func NewGormZapLogger(zapLog *zap.Logger, slowThreshold time.Duration) *GormZapLogger {
return &GormZapLogger{
ZapLogger: zapLog,
LogLevel: gormlogger.Info, // Atur default ke Info, bisa disesuaikan
SlowThreshold: slowThreshold, // Waktu batas query dianggap lambat (misal 200ms)
}
}
// LogMode mengubah level log GORM
func (l *GormZapLogger) LogMode(level gormlogger.LogLevel) gormlogger.Interface {
newLogger := *l
newLogger.LogLevel = level
return &newLogger
}
// Info mencetak log informasi biasa
func (l *GormZapLogger) Info(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= gormlogger.Info {
l.ZapLogger.Sugar().Infof(msg, data...)
}
}
// Warn mencetak log peringatan
func (l *GormZapLogger) Warn(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= gormlogger.Warn {
l.ZapLogger.Sugar().Warnf(msg, data...)
}
}
// Error mencetak log kesalahan
func (l *GormZapLogger) Error(ctx context.Context, msg string, data ...interface{}) {
if l.LogLevel >= gormlogger.Error {
l.ZapLogger.Sugar().Errorf(msg, data...)
}
}
// Trace mencetak log internal query SQL dari GORM
func (l *GormZapLogger) Trace(ctx context.Context, begin time.Time, fc func() (string, int64), err error) {
if l.LogLevel <= gormlogger.Silent {
return
}
elapsed := time.Since(begin)
sql, rows := fc()
// Ambil lokasi file baris kode Go yang mengeksekusi query ini
line := utils.FileWithLineNum()
// Siapkan fields bawaan Zap agar log terstruktur dengan baik
fields := []zap.Field{
zap.String("line", line),
zap.Duration("elapsed", elapsed),
zap.Int64("rows", rows),
zap.String("sql", sql),
}
switch {
// Kasus 1: Terjadi Error dan Error tersebut BUKAN Record NotFound
case err != nil && l.LogLevel >= gormlogger.Error && !errors.Is(err, gorm.ErrRecordNotFound):
fields = append(fields, zap.Error(err))
l.ZapLogger.Error("[GORM] query error", fields...)
// Kasus 2: Query berjalan lambat melewati batas SlowThreshold
case elapsed > l.SlowThreshold && l.SlowThreshold != 0 && l.LogLevel >= gormlogger.Warn:
l.ZapLogger.Warn("[GORM] slow query warning", fields...)
// Kasus 3: Log info query normal
case l.LogLevel >= gormlogger.Info:
l.ZapLogger.Info("[GORM] query execution", fields...)
}
}