Files
satusehat-service/internal/infrastructure/monitoring/repository_wrapper.go
T
2026-04-14 01:23:34 +00:00

185 lines
4.5 KiB
Go

// File: /home/meninjar/goprint/service/internal/infrastructure/monitoring/repository_wrapper.go
package monitoring
import (
"context"
"time"
"service/pkg/logger"
"gorm.io/gorm"
)
// GormDBWrapper wraps GORM DB with metrics collection
type GormDBWrapper struct {
*gorm.DB
metrics *Metrics
database string
logger logger.Logger
}
// NewGormDBWrapper creates a new GORM wrapper with metrics
func NewGormDBWrapper(db *gorm.DB, metrics *Metrics, database string) *GormDBWrapper {
log := logger.Default().WithFields(
logger.String("component", "gorm_wrapper"),
logger.String("database", database),
)
return &GormDBWrapper{
DB: db,
metrics: metrics,
database: database,
logger: log,
}
}
// Create overrides GORM Create with metrics
func (w *GormDBWrapper) Create(value interface{}) *gorm.DB {
start := time.Now()
result := w.DB.Create(value)
duration := time.Since(start)
table := w.DB.Statement.Table
status := "success"
if result.Error != nil {
status = "error"
}
w.metrics.RecordDBQuery("create", table, w.database, duration, result.Error)
w.logger.Debug("Database create operation",
logger.String("table", table),
logger.String("status", status),
logger.Float64("duration_seconds", duration.Seconds()),
logger.ErrorField(result.Error),
)
return result
}
// Find overrides GORM Find with metrics
func (w *GormDBWrapper) Find(dest interface{}, conds ...interface{}) *gorm.DB {
start := time.Now()
result := w.DB.Find(dest, conds...)
duration := time.Since(start)
table := w.DB.Statement.Table
status := "success"
if result.Error != nil {
status = "error"
}
w.metrics.RecordDBQuery("find", table, w.database, duration, result.Error)
w.logger.Debug("Database find operation",
logger.String("table", table),
logger.String("status", status),
logger.Float64("duration_seconds", duration.Seconds()),
logger.ErrorField(result.Error),
)
return result
}
// First overrides GORM First with metrics
func (w *GormDBWrapper) First(dest interface{}, conds ...interface{}) *gorm.DB {
start := time.Now()
result := w.DB.First(dest, conds...)
duration := time.Since(start)
table := w.DB.Statement.Table
status := "success"
if result.Error != nil {
status = "error"
}
w.metrics.RecordDBQuery("first", table, w.database, duration, result.Error)
w.logger.Debug("Database first operation",
logger.String("table", table),
logger.String("status", status),
logger.Float64("duration_seconds", duration.Seconds()),
logger.ErrorField(result.Error),
)
return result
}
// Update overrides GORM Update with metrics
func (w *GormDBWrapper) Update(column string, value interface{}) *gorm.DB {
start := time.Now()
result := w.DB.Update(column, value)
duration := time.Since(start)
table := w.DB.Statement.Table
status := "success"
if result.Error != nil {
status = "error"
}
w.metrics.RecordDBQuery("update", table, w.database, duration, result.Error)
w.logger.Debug("Database update operation",
logger.String("table", table),
logger.String("status", status),
logger.Float64("duration_seconds", duration.Seconds()),
logger.ErrorField(result.Error),
)
return result
}
// Delete overrides GORM Delete with metrics
func (w *GormDBWrapper) Delete(value interface{}, conds ...interface{}) *gorm.DB {
start := time.Now()
result := w.DB.Delete(value, conds...)
duration := time.Since(start)
table := w.DB.Statement.Table
status := "success"
if result.Error != nil {
status = "error"
}
w.metrics.RecordDBQuery("delete", table, w.database, duration, result.Error)
w.logger.Debug("Database delete operation",
logger.String("table", table),
logger.String("status", status),
logger.Float64("duration_seconds", duration.Seconds()),
logger.ErrorField(result.Error),
)
return result
}
// WithContext overrides GORM WithContext to maintain wrapper
func (w *GormDBWrapper) WithContext(ctx context.Context) *GormDBWrapper {
return &GormDBWrapper{
DB: w.DB.WithContext(ctx),
metrics: w.metrics,
database: w.database,
logger: w.logger,
}
}
// Model overrides GORM Model to maintain wrapper
func (w *GormDBWrapper) Model(value interface{}) *GormDBWrapper {
return &GormDBWrapper{
DB: w.DB.Model(value),
metrics: w.metrics,
database: w.database,
logger: w.logger,
}
}
// Table overrides GORM Table to maintain wrapper
func (w *GormDBWrapper) Table(name string, args ...interface{}) *GormDBWrapper {
return &GormDBWrapper{
DB: w.DB.Table(name, args...),
metrics: w.metrics,
database: w.database,
logger: w.logger,
}
}